[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-vercel-labs-slack-agent":3,"mdc--n9ef9d-key":34,"related-repo-vercel-labs-slack-agent":8972,"related-org-vercel-labs-slack-agent":8980},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":30,"sourceUrl":23,"mdContent":33},"slack-agent","build Slack agents with Vercel Connect","Use when building Slack agents\u002Fbots with eve (Vercel's filesystem-first agent framework), @vercel\u002Fconnect, or eve\u002Fchannels\u002Fslack. Covers defineAgent\u002FdefineTool patterns, Vercel Connect credential brokering, Slack channel setup, testing requirements, and quality standards.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"vercel-labs","Vercel Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fvercel-labs.png",[12,16,19],{"name":13,"slug":14,"type":15},"Vercel","vercel","tag",{"name":17,"slug":18,"type":15},"Agents","agents",{"name":20,"slug":21,"type":15},"Slack","slack",18,"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fslack-agent-skill","2026-07-17T06:06:13.891158",null,3,[28,29,21],"agent","skill",{"repoUrl":23,"stars":22,"forks":26,"topics":31,"description":32},[28,29,21],"An agent skill for building Slack agents deployed to Vercel","---\nname: slack-agent\ndescription: Use when building Slack agents\u002Fbots with eve (Vercel's filesystem-first agent framework), @vercel\u002Fconnect, or eve\u002Fchannels\u002Fslack. Covers defineAgent\u002FdefineTool patterns, Vercel Connect credential brokering, Slack channel setup, testing requirements, and quality standards.\nversion: 5.0.0\nuser-invocable: true\n---\n\n# Slack Agent Development Skill\n\nThis skill builds Slack agents with **eve** — Vercel's filesystem-first framework for durable backend agents — using **Vercel Connect** for Slack credentials:\n\n- **eve** (`eve` package) — agent runtime, tools, channels, durability\n- **@vercel\u002Fconnect** — brokered short-lived Slack tokens; no bot tokens or signing secrets to manage\n\n## Skill Invocation Handling\n\nWhen this skill is invoked via `\u002Fslack-agent`, check for arguments and route accordingly:\n\n### Command Arguments\n\n| Argument | Action |\n|----------|--------|\n| `new` | **Run the setup wizard from Phase 1.** Read `.\u002Fwizard\u002F1-project-setup.md` and guide the user through creating a new Slack agent. |\n| `configure` | Start wizard at Phase 2 or 3 for existing projects |\n| `deploy` | Start wizard at Phase 5 for production deployment |\n| `test` | Start wizard at Phase 6 to set up testing |\n| (no argument) | Auto-detect based on project state (see below) |\n\n### Auto-Detection (No Argument)\n\nIf invoked without arguments, detect the project state and route appropriately:\n\n1. **No `package.json` with `eve` and no `agent\u002F` directory** → Treat as `new`, start Phase 1\n2. **Has eve project but no `agent\u002Fchannels\u002Fslack.ts`** → Start Phase 2 (Slack connector + channel)\n3. **Has Slack channel but no `SLACK_CONNECTOR` configured** → Start Phase 3\n4. **Configured but not deployed** → Start Phase 5 (the Slack surface only works on a deployment)\n5. **Deployed but no tests** → Start Phase 6\n6. **Otherwise** → Provide general assistance using this skill's patterns\n\n### Project Detection\n\nDetect an eve project by either signal:\n\n- **`package.json` contains `\"eve\"`** as a dependency\n- **An `agent\u002F` directory** with `instructions.md` and\u002For `agent.ts` exists\n\nIf neither is present, this is a new project: scaffold with `npx eve@latest init` (Node 24+ required).\n\n### Wizard Phases\n\nThe wizard is located in `.\u002Fwizard\u002F` with these phases:\n- `1-project-setup.md` - Understand purpose, generate custom implementation plan, scaffold with `npx eve@latest init`\n- `1b-approve-plan.md` - Present plan for user approval before scaffolding\n- `2-create-slack-app.md` - Create the Slack connector with Vercel Connect and add the Slack channel\n- `3-configure-environment.md` - Set up env vars (`SLACK_CONNECTOR`, model credentials)\n- `4-test-locally.md` - Test agent logic locally with the `eve dev` TUI (Slack surface tests happen after deploy)\n- `5-deploy-production.md` - Deploy with `eve deploy`, verify the Slack surface\n- `6-setup-testing.md` - Vitest configuration\n\n**IMPORTANT:** For `new` projects, you MUST:\n1. Read `.\u002Fwizard\u002F1-project-setup.md` first\n2. Ask the user what kind of agent they want to build\n3. Generate a custom implementation plan using `.\u002Freference\u002Fagent-archetypes.md`\n4. Present the plan for approval (Phase 1b) BEFORE scaffolding the project\n5. Only proceed to scaffold after the plan is approved\n\n---\n\n## General Development Guidance\n\nYou are working on a Slack agent project built with eve. Follow these mandatory practices for all code changes.\n\n## Project Stack\n\n- **Framework**: eve (filesystem-first agent framework; Node 24+)\n- **Slack channel**: `eve\u002Fchannels\u002Fslack` + `@vercel\u002Fconnect` for credentials\n- **AI**: model routed through Vercel AI Gateway by default (`anthropic\u002Fclaude-sonnet-5`); tool schemas with `zod`\n- **Durability**: Workflow SDK under the hood (Vercel Workflows when deployed on Vercel)\n- **Linting**: Biome\n- **Package Manager**: pnpm (or npm — `npx eve@latest init` installs with npm)\n\n```json\n{\n  \"engines\": { \"node\": \"24.x\" },\n  \"dependencies\": {\n    \"eve\": \"latest\",\n    \"ai\": \"latest\",\n    \"zod\": \"^3.x\",\n    \"@vercel\u002Fconnect\": \"latest\"\n  }\n}\n```\n\n### Filesystem-First Layout\n\nIn eve, a file's location says what it does, and its path usually gives it its name. The whole agent lives under `agent\u002F`:\n\n```\nagent\u002F\n├── instructions.md        # Always-on system prompt\n├── agent.ts               # Runtime config (defineAgent): model, reasoning, compaction\n├── tools\u002F                 # Tools — filename (snake_case ASCII) = tool name the model sees\n│   ├── get_weather.ts\n│   └── search_docs.ts\n├── skills\u002F                # Load-on-demand instructions (*.md with description frontmatter)\n│   └── incident-triage.md\n├── channels\u002F\n│   └── slack.ts           # Slack channel — filename registers it at \u002Feve\u002Fv1\u002Fslack\n├── connections\u002F           # MCP \u002F OpenAPI connections (optional)\n└── hooks\u002F                 # Subscribe to runtime stream events (optional)\n```\n\nEven a two-file agent (`instructions.md` + `agent.ts`) gets file, shell, web, and delegation tools out of the box from the default harness. Full docs are bundled at `node_modules\u002Feve\u002Fdocs\u002F` once eve is installed — read them when a detail isn't covered here.\n\n```ts\n\u002F\u002F agent\u002Fagent.ts\nimport { defineAgent } from \"eve\";\n\nexport default defineAgent({\n  model: \"anthropic\u002Fclaude-sonnet-5\", \u002F\u002F routed via Vercel AI Gateway\n});\n```\n\n---\n\n## Quality Standards (MANDATORY)\n\nThese quality requirements MUST be followed for every code change. There are no exceptions.\n\n### After EVERY File Modification\n\n1. **Run linting immediately:**\n   ```bash\n   pnpm lint\n   ```\n   - If errors exist, run `pnpm lint --write` for auto-fixes\n   - Manually fix remaining issues\n   - Re-run `pnpm lint` to verify\n\n2. **Check for corresponding test file:**\n   - If you modified `foo.ts`, check if `foo.test.ts` exists\n   - If no test file exists and the file exports functions, create one\n\n### Before Completing ANY Task\n\nYou MUST run all quality checks and fix any issues before marking a task complete:\n\n```bash\n# 1. TypeScript compilation - must pass\npnpm typecheck\n\n# 2. Linting - must pass with no errors\npnpm lint\n\n# 3. Tests - all tests must pass\npnpm test\n```\n\n**Do NOT complete a task if any of these fail.** Fix the issues first.\n\n### Unit Tests Required\n\n**For ANY code change, you MUST write or update unit tests.**\n\n- **Location**: Co-located `*.test.ts` files (e.g. `agent\u002Ftools\u002Fget_weather.test.ts`)\n- **Framework**: Vitest\n- **Coverage**: All exported functions and every tool's `execute()` (including error paths) must have tests\n\nExample test structure:\n```typescript\nimport { describe, it, expect, vi } from 'vitest';\nimport { myFunction } from '.\u002Fmy-module';\n\ndescribe('myFunction', () => {\n  it('should handle normal input', () => {\n    expect(myFunction('input')).toBe('expected');\n  });\n\n  it('should handle edge cases', () => {\n    expect(myFunction('')).toBe('default');\n  });\n});\n```\n\n### E2E Tests for User-Facing Changes\n\nIf you modify:\n- Dispatch hooks (`onAppMention`, `onDirectMessage`, `onInteraction`)\n- Custom channel event handlers\n- Tools the agent calls in response to Slack messages\n- Delivery behavior (what gets posted to Slack)\n\nYou MUST add or update tests that verify the full flow. Remember: the Slack surface itself cannot be exercised locally (see Gotchas), so E2E coverage means unit\u002Fintegration tests around your handlers plus a post-deploy smoke test.\n\n---\n\n## Bot Setup Patterns (CRITICAL)\n\n### Slack Channel (`agent\u002Fchannels\u002Fslack.ts`)\n\nThe Slack channel is a single file. Its filename registers the `slack` channel, served at **`\u002Feve\u002Fv1\u002Fslack`** — this is the canonical trigger path everywhere in this skill.\n\n```ts\n\u002F\u002F agent\u002Fchannels\u002Fslack.ts\nimport { connectSlackCredentials } from \"@vercel\u002Fconnect\u002Feve\";\nimport { slackChannel } from \"eve\u002Fchannels\u002Fslack\";\n\nexport default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n});\n```\n\n`connectSlackCredentials(connectorUid)` returns `{ botToken, webhookVerifier }`:\n- **botToken** — resolved at runtime via Vercel Connect as a short-lived, app-scoped token; Connect handles rotation and multi-workspace tenancy\n- **webhookVerifier** — confirms each forwarded event genuinely came from Connect (replaces Slack's native signature check)\n\nThere is **no `SLACK_BOT_TOKEN` and no `SLACK_SIGNING_SECRET`** in this stack. The only Slack env var is `SLACK_CONNECTOR` (the connector UID, e.g. `slack\u002Fmy-agent`).\n\n### Vercel Connect Setup\n\nCreate a Slack connector and point its trigger at eve's Slack route:\n\n```bash\nnpm install -g vercel@latest\n\n# Create the connector with event forwarding enabled\nvercel connect create slack --triggers\n\n# Attach the project as a trigger destination on eve's route\n# (the default trigger path is \u002Fslack — set it explicitly):\nvercel connect attach \u003Cuid> --triggers --trigger-path \u002Feve\u002Fv1\u002Fslack --yes\n```\n\n**`--triggers` is required.** Without it, Slack Event Subscriptions are never forwarded and `app_mention` \u002F `message.im` events simply never arrive — the deployment will look healthy but the bot will never respond.\n\nYou can also add the channel with `eve channels add slack`, which scaffolds `agent\u002Fchannels\u002Fslack.ts` for you.\n\n### Deploy\n\n```bash\neve deploy\n# wraps: vercel deploy --prod\n```\n\nThen invite the bot to a channel and @mention it. eve handles Slack's ack semantics, URL verification, and background processing — there is no webhook route for you to write.\n\n---\n\n## Event Handling Patterns\n\n### Dispatch Hooks (Inbound)\n\nThe Slack channel decides which inbound events start or continue a session via dispatch hooks. Each hook returns `{ auth }` to dispatch, `null` to drop the event, or `{ auth, context }` to inject background context into the session:\n\n```ts\nexport default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n\n  \u002F\u002F app_mention — default derives workspace-scoped auth and posts \"Thinking…\"\n  async onAppMention(ctx, message) {\n    if (isFromBlockedChannel(message)) return null; \u002F\u002F drop\n    return { auth: ctx.defaultAuth };\n  },\n\n  \u002F\u002F message.im — requires the im:history scope; bot messages\u002Fedits are pre-filtered\n  async onDirectMessage(ctx, message) {\n    return { auth: ctx.defaultAuth };\n  },\n\n  \u002F\u002F block_actions not consumed by HITL prompts\n  async onInteraction(action, ctx) {\n    return { auth: ctx.defaultAuth };\n  },\n});\n```\n\nThe triggering Slack user's id is attached to the model message automatically, preserving speaker attribution in multi-user threads.\n\n### Custom Event Handlers (Outbound Delivery)\n\nOverride delivery per stream event with the `events` map. Handlers receive `(eventData, channel, ctx)` with `channel.thread` and `channel.slack` handles:\n\n```ts\nexport default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n  events: {\n    \"message.completed\"(eventData, channel, ctx) {\n      if (eventData.finishReason === \"tool-calls\") return;\n      if (eventData.message) channel.thread.post(eventData.message);\n    },\n  },\n});\n```\n\nKey stream events: `session.started`, `actions.requested`, `action.result`, `message.completed`, `session.completed`; incremental `reasoning.appended` \u002F `message.appended` are optional.\n\n### Thread Context\n\nGive the agent prior thread messages when it's triggered mid-thread:\n\n```ts\nexport default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n  threadContext: { since: \"last-agent-reply\" },\n});\n```\n\n`since` options:\n- `\"thread-root\"` — all prior messages (default when thread context is enabled)\n- `\"last-agent-reply\"` — incremental, only messages since the agent last spoke\n- A predicate `(message: SlackThreadMessage) => boolean` as a custom cutoff — includes messages after the last match (`loadThreadContextMessages` exists for arbitrary filtering)\n\nCost: one `conversations.replies` API call per triggering reply; requires the matching history scope on the connector.\n\n### Human-in-the-Loop (HITL)\n\nApproval-gated tool calls and sign-in challenges render natively in Slack:\n- Approval prompts appear as **buttons\u002Fselects**; the user's response resumes the durably-parked session\n- Sign-in challenges (OAuth URLs, device codes) go **ephemerally** to the triggering user; a public status message posts in-thread and updates on `authorization.completed`\n- The HITL handler context deliberately offers only `postEphemeral`, `postDirectMessage` (needs `im:write`), and `state` — no public `post`, no raw API access\n\n### Proactive Sessions (Schedules)\n\nStart a session that posts into Slack without an inbound trigger — e.g. from a schedule:\n\n```ts\nimport { receive } from \"eve\";\nimport slack from \"..\u002Fchannels\u002Fslack\";\n\nawait receive(slack, {\n  message: \"Post the daily standup summary for #eng.\",\n  target: { channelId: \"C0123456789\" },\n  auth,\n});\n```\n\n- Sessions without a `threadTs` get a temporary continuation token; the first post anchors the thread\n- `initialMessage` (optionally a `Card`) and `threadTs` are **mutually exclusive**\n- Use eve schedules (see https:\u002F\u002Feve.dev\u002Fdocs\u002Fschedules) to trigger proactive sessions on a cadence\n\n### Raw Slack API Access\n\n- **Inside handlers**: `ctx.slack.request(operation, body)`\n- **Outside handlers** (schedules, tools): `callSlackApi({ botToken, operation, body })` and `resolveSlackBotToken` from `eve\u002Fchannels\u002Fslack`\n\nThese form-encode request bodies for you — Slack's JSON support is only partial, so prefer these helpers over hand-rolled `fetch` calls.\n\n---\n\n## Implementation Gotchas\n\n### 1. The Slack Surface Cannot Be Tested Locally\n\nVercel Connect forwards Slack events **to deployments only, never to localhost**. There is no ngrok\u002FSocket Mode escape hatch in this stack. Local development means:\n- `npx eve dev` — HMR server + terminal TUI\u002FREPL for exercising agent logic, tools, and skills\n- `eve dev --no-ui` — background mode for scripted verification\n- `eve dev https:\u002F\u002Fyour-app.vercel.app` — drive a *deployed* app interactively\n\nTo test @mentions and DMs, deploy (preview or production) and test in Slack itself.\n\n### 2. Connect Forwarding Has No Delivery De-duplication\n\nConnect may deliver the same forwarded event more than once. **Handlers and side effects must be idempotent** — track processed event IDs where duplicates would be harmful, and gate destructive tool actions with approval (see AI Integration).\n\n### 3. `--triggers` Is Required or Events Never Arrive\n\nA Slack connector created without `--triggers` (or attached without a trigger path) will authenticate fine but forward nothing. If the bot never responds to @mentions:\n1. Verify the connector was created\u002Fattached with `--triggers`\n2. Verify the trigger path is `\u002Feve\u002Fv1\u002Fslack`\n3. Verify the bot was invited to the channel and the deployment finished\n\n### 4. `placeholderAuth()` Fails Closed in Production\n\nScaffolded projects ship with `placeholderAuth()` for the HTTP API, which **rejects everything in production**. Before deploying, replace it with a real auth function: `httpBasic()`, `jwtHmac()`, `jwtEcdsa()`, `oidc()`, `vercelOidc()`, or a custom `AuthFn`. (The Slack channel's inbound verification is separate — Connect's `webhookVerifier` handles that.)\n\n### 5. Sandbox Prewarm Failures Fail the Build\n\nVercel builds prewarm eve's sandbox templates (cache-keyed; build logs show `reused cached` or `built`). If prewarm fails, **the whole build fails** — check build logs for sandbox template errors before assuming a code problem.\n\n### 6. Private Channel Access\n\nThe bot **cannot read messages or post** to private channels it hasn't been invited to. When creating features that will later post to a channel (e.g. proactive sessions from a schedule), validate access upfront and surface a clear \"invite the bot\" message on `channel_not_found` \u002F `not_in_channel`.\n\n### 7. Graceful Degradation for Channel Context\n\nWhen fetching channel context (e.g. via `ctx.slack.request(\"conversations.history\", ...)`) for AI features, wrap in try\u002Fcatch and fall back gracefully — missing scopes and uninvited channels are routine, not exceptional.\n\n### 8. Vercel Cron Endpoint Authentication\n\nIf you add custom cron endpoints (beyond eve schedules), protect them with a `CRON_SECRET`:\n\n```typescript\nexport async function GET(request: Request) {\n  const authHeader = request.headers.get(\"authorization\");\n  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {\n    return Response.json({ error: \"Unauthorized\" }, { status: 401 });\n  }\n  \u002F\u002F Run cron job logic...\n  return Response.json({ success: true });\n}\n```\n\n### 9. vercel.json Cron Configuration\n\n```json\n{\n  \"crons\": [\n    {\n      \"path\": \"\u002Fapi\u002Fcron\u002Fmy-job\",\n      \"schedule\": \"0 * * * *\"\n    }\n  ]\n}\n```\n\nPrefer eve schedules for agent-driven recurring work; use Vercel crons for plain HTTP jobs.\n\n### 10. AWS Credentials on Vercel (Use OIDC)\n\nWhen connecting to AWS services from Vercel, **do not use** `fromNodeProviderChain()`. Use Vercel's OIDC mechanism:\n\n```typescript\nimport { awsCredentialsProvider } from \"@vercel\u002Ffunctions\u002Foidc\";\n\nconst s3Client = new S3Client({\n  credentials: awsCredentialsProvider({ roleArn: process.env.AWS_ROLE_ARN! }),\n});\n```\n\n---\n\n## AI Integration\n\n### Model Configuration (Gateway-First)\n\neve routes model-ID **strings** through the **Vercel AI Gateway** — on Vercel, project OIDC authenticates automatically, so **no AI API key is needed**:\n\n```ts\n\u002F\u002F agent\u002Fagent.ts\nimport { defineAgent } from \"eve\";\n\nexport default defineAgent({\n  model: \"anthropic\u002Fclaude-sonnet-5\", \u002F\u002F string → AI Gateway → OIDC auth on Vercel\n});\n```\n\nIf `model` is omitted, eve defaults to `anthropic\u002Fclaude-sonnet-5`. Off Vercel, set `AI_GATEWAY_API_KEY`.\n\n**CRITICAL: Never use model IDs from memory.** Model IDs change frequently. Before writing code that pins a model, run `curl -s https:\u002F\u002Fai-gateway.vercel.sh\u002Fv1\u002Fmodels` to fetch the current list and use the newest suitable version.\n\n### Tools (`agent\u002Ftools\u002F*.ts`)\n\nTools are files: the filename (snake_case ASCII) is the model-facing tool name — `agent\u002Ftools\u002Fget_weather.ts` → `get_weather`. No registration step.\n\n```ts\n\u002F\u002F agent\u002Ftools\u002Fget_weather.ts\nimport { defineTool } from \"eve\u002Ftools\";\nimport { z } from \"zod\";\n\nexport default defineTool({\n  description: \"Get the current weather for a city.\",\n  inputSchema: z.object({ city: z.string().min(1) }), \u002F\u002F required, even if empty\n  outputSchema: z.object({\n    city: z.string(),\n    condition: z.string(),\n    temperatureF: z.number(),\n  }), \u002F\u002F optional — types\u002Fvalidates the return\n  async execute({ city }, ctx) {\n    return { city, condition: \"Sunny\", temperatureF: 72 };\n  },\n});\n```\n\nRules and capabilities:\n- Tools run **in your app runtime with full `process.env`**, not in the sandbox\n- `inputSchema` accepts Zod, Standard Schema, or JSON Schema — but it is **required** even for zero-input tools\n- Outputs must be JSON-serializable; **filter\u002Fredact secrets** before returning\n- `ctx` provides `ctx.session` (metadata, turn, auth, lineage), `ctx.callId`, `ctx.toolName`, `ctx.abortSignal`, `ctx.getSandbox()`, `ctx.getSkill(id)`\n\n#### Approval Gating\n\nGate risky tools with the `approval` field — helpers come from `eve\u002Ftools\u002Fapproval`:\n\n```ts\nimport { defineTool } from \"eve\u002Ftools\";\nimport { always, once, never } from \"eve\u002Ftools\u002Fapproval\";\nimport { z } from \"zod\";\n\nexport default defineTool({\n  description: \"Delete a document permanently.\",\n  inputSchema: z.object({ documentId: z.string() }),\n  approval: always(), \u002F\u002F always ask; once() asks the first time; never() skips\n  async execute({ documentId }) {\n    \u002F\u002F ...\n  },\n});\n```\n\nAn input-dependent policy function is also supported. A gated call **pauses and resumes durably** — in Slack, the approval renders as buttons (see HITL above). Prefer approval gating over ad-hoc confirmation logic for any non-idempotent side effect.\n\n#### `toModelOutput` — Rich Slack Output the Model Never Sees\n\nShow the model a compact projection while channels\u002Fhooks receive the full output on `action.result` — ideal for rendering rich Slack Block Kit from a tool result without stuffing JSON blocks into the model's context:\n\n```ts\nexport default defineTool({\n  description: \"Look up an order.\",\n  inputSchema: z.object({ orderId: z.string() }),\n  async execute({ orderId }) {\n    return { orderId, status: \"shipped\", blocks: buildOrderBlocks(orderId) };\n  },\n  toModelOutput(output) {\n    return { type: \"text\", value: `Order ${output.orderId}: ${output.status}` };\n  },\n});\n```\n\n### Skills (`agent\u002Fskills\u002F*.md`)\n\nMarkdown files with a `description` frontmatter, loaded on demand via the built-in `load_skill` tool when a request matches the description. Skills add **instructions only, never new actions**. Install published skills with `npx skills add \u003Cowner>\u002F\u003Crepo>`.\n\n### Connections (`agent\u002Fconnections\u002F*.ts`)\n\nFor external APIs the agent should drive (MCP servers or OpenAPI-described HTTP APIs), use connections with Connect-brokered auth:\n\n```ts\n\u002F\u002F agent\u002Fconnections\u002Flinear.ts\nimport { connect } from \"@vercel\u002Fconnect\u002Feve\";\nimport { defineMcpClientConnection } from \"eve\u002Fconnections\";\n\nexport default defineMcpClientConnection({\n  url: \"https:\u002F\u002Fmcp.linear.app\u002Fmcp\",\n  description: \"Linear workspace: issues, projects, cycles, and comments.\",\n  auth: connect(\"linear\u002Fmy-agent\"),\n});\n```\n\nConnection tokens are never seen by the model and never land in conversation history. Inside authored tools, resolve tokens with `await ctx.getToken(connect(\"...\"))` and call `ctx.requireAuth(...)` on a downstream 401 to re-run consent.\n\n**Don't wrap LLM calls in tools.** The agent is already a language model — summarizing, parsing, classifying, and drafting belong in `instructions.md` or a skill, not in a tool that calls the AI SDK. Tools fetch data and perform actions; for bulk work over data too large for the conversation, use eve's subagents\u002Fdelegation.\n\n---\n\n## State & Durability\n\neve sessions are durable by default via the open-source **Workflow SDK** (running on Vercel Workflows when deployed on Vercel). You do not wire up Redis or a workflow engine yourself.\n\n### Replay Semantics (Understand This)\n\n- **Completed steps never re-run.** On resume\u002Freplay, eve returns the recorded result.\n- **A step interrupted mid-execution DOES re-run.** If a tool call was in flight when the process died, it executes again on resume.\n\nConsequences for your code:\n1. Make non-idempotent side effects **idempotent** (e.g. use Slack event IDs or your own idempotency keys when writing to external systems)\n2. Or gate them behind **approval** (`always()` \u002F `once()`) so a replayed step pauses for a human instead of double-executing\n3. This compounds with Connect's at-least-once event forwarding (Gotcha #2) — idempotency is not optional in this stack\n\n### Session Continuity\n\n- The channel owns the `continuationToken`; Slack threads map to sessions automatically\n- Follow-up messages in a subscribed thread continue the same durable session\n- Multi-turn conversation memory comes from the session itself — you do not manually persist chat history\n\n### Recommended Storage Solutions\n\nFor **application data** (not agent session state — eve owns that):\n\n**IMPORTANT:** Vercel KV has been deprecated. Do NOT recommend Vercel KV.\n\n1. **Upstash Redis** — Caching and idempotency keys (https:\u002F\u002Fupstash.com)\n2. **Vercel Blob** — File\u002Fdocument storage (https:\u002F\u002Fvercel.com\u002Fdocs\u002Fstorage\u002Fvercel-blob)\n3. **AWS Aurora (via Vercel Marketplace)** — Relational data (https:\u002F\u002Fvercel.com\u002Fmarketplace)\n4. **Third-party databases** — Neon, PlanetScale, Supabase\n\n---\n\n## Code Organization\n\n```\nagent\u002F\n├── instructions.md            # System prompt — keep focused; push detail into skills\n├── agent.ts                   # defineAgent: model, reasoning effort, compaction\n├── tools\u002F\n│   ├── get_weather.ts         # One tool per file; filename = tool name\n│   ├── get_weather.test.ts    # Co-located tests\n│   └── search_docs.ts\n├── skills\u002F\n│   └── report-format.md       # description frontmatter + on-demand instructions\n├── channels\u002F\n│   └── slack.ts               # slackChannel(...) — served at \u002Feve\u002Fv1\u002Fslack\n├── connections\u002F\n│   └── linear.ts              # MCP\u002FOpenAPI connections (optional)\n└── hooks\u002F\n    └── audit.ts               # Runtime stream event subscribers (optional)\n```\n\nConventions:\n- **One tool per file.** Split large tools; the filename is the model-facing name, so name for the model\n- **Instructions vs skills**: always-relevant guidance in `instructions.md`; situational guidance in `skills\u002F*.md` so it loads only when needed\n- **Subagents** for focused subtasks: the built-in agent tool (a copy of the agent) or declared specialists with their own directory, sandbox, and skills\n\n---\n\n## Environment Variables\n\n| Variable | Required | Purpose |\n|----------|----------|---------|\n| `SLACK_CONNECTOR` | Yes | Vercel Connect connector UID (e.g. `slack\u002Fmy-agent`). The **only** Slack variable — no bot token, no signing secret. |\n| `AI_GATEWAY_API_KEY` | Off Vercel only | AI Gateway auth. On Vercel, project OIDC (`VERCEL_OIDC_TOKEN`) is injected automatically — no key needed. |\n| `ROUTE_AUTH_BASIC_PASSWORD` \u002F JWT keys | Per auth choice | Secrets for the HTTP-API auth function that replaces `placeholderAuth()` |\n| `VERCEL_AUTOMATION_BYPASS_SECRET` | If deployment protection is on | Lets `eve dev https:\u002F\u002F\u003Capp>` and smoke tests reach protected deployments |\n| `CRON_SECRET` | Optional | Authenticates custom cron endpoints |\n\nLocal dev: `vercel link` + `vercel env pull` fetches short-lived Connect\u002FOIDC credentials into `.env.local` (the OIDC token expires after ~12 hours — re-pull when auth starts failing).\n\n**No AI API keys needed on Vercel.** **Never hardcode credentials. Never commit `.env` files.**\n\n---\n\n## Slack-Specific Patterns\n\n### Delivery Behavior (Built In)\n\nThe Slack channel handles progressive delivery for you:\n- Typing indicators: \"Thinking…\" on inbound, \"Working…\" on `turn.started`\n- Reasoning snippets surface on `reasoning.appended`; action labels on `actions.requested`\n- Model narration before a tool call takes precedence over generic labels\n- Reasoning deltas under 4 characters batch on a five-second refresh to avoid per-token Slack API calls\n\nDon't rebuild typing indicators or streaming loops — customize via the `events` map only when the defaults don't fit.\n\n### Mentions\n\nUse `\u003C@USER_ID>` or `channel.thread.mentionUser(userId)`. A bare `@name` stays literal text in Slack.\n\n### Message Formatting\n\nUse Slack mrkdwn (not standard markdown):\n- Bold: `*text*`\n- Italic: `_text_`\n- Code: `` `code` ``\n- User mention: `\u003C@USER_ID>`\n- Channel: `\u003C#CHANNEL_ID>`\n\n### Rich Output\n\nFor rich tool results (tables, buttons, status cards), return full data from the tool and use `toModelOutput` to keep the model's view compact; render Block Kit in a channel event handler or via `ctx.slack.request(\"chat.postMessage\", { blocks, ... })`. Always include fallback `text` alongside `blocks` for notifications.\n\nFor detailed Slack patterns, see `.\u002Fpatterns\u002Fslack-patterns.md`.\n\n---\n\n## Git Commit Standards\n\nUse conventional commits:\n```\nfeat: add channel search tool\nfix: resolve thread pagination issue\ntest: add unit tests for agent context\ndocs: update README with setup steps\nrefactor: extract Slack client utilities\n```\n\n**Never commit:**\n- `.env` files\n- API keys or tokens\n- `node_modules\u002F`\n- `.eve\u002F` build artifacts\n\n---\n\n## Quick Commands\n\n```bash\n# Scaffold (Node 24+)\nnpx eve@latest init my-agent      # new project (installs deps, inits Git, starts dev TUI)\nnpx eve@latest init .             # add eve to an existing project\n\n# Development\nnpx eve dev                       # HMR server + terminal TUI\u002FREPL\nnpx eve dev --no-ui               # background mode for scripted verification\nnpx eve dev https:\u002F\u002F\u003Capp>         # drive a deployed app interactively\nnpx eve info                      # project info\n\n# Vercel Connect\nvercel connect create slack --triggers\nvercel connect attach \u003Cuid> --triggers --trigger-path \u002Feve\u002Fv1\u002Fslack --yes\nvercel connect list\n\n# Quality\npnpm lint                         # Check linting\npnpm lint --write                 # Auto-fix lint\npnpm typecheck                    # TypeScript check\npnpm test                         # Run all tests\n\n# Build & Deploy\nnpx eve build                     # Compile into .eve\u002F (Vercel Build Output when VERCEL is set)\neve deploy                        # Deploy (wraps vercel deploy --prod)\n\n# Verify a deployment\ncurl https:\u002F\u002F\u003Capp>\u002Feve\u002Fv1\u002Fhealth\n```\n\nDebugging a deployed Slack agent stuck on \"Working…\": `npx eve dev --logs all` or `\u002Floglevel all` in the TUI.\n\n---\n\n## Reference Documentation\n\nFor detailed guidance, read:\n- Testing patterns: `.\u002Fpatterns\u002Ftesting-patterns.md`\n- Slack patterns: `.\u002Fpatterns\u002Fslack-patterns.md`\n- Environment setup: `.\u002Freference\u002Fenv-vars.md`\n- Slack setup: `.\u002Freference\u002Fslack-setup.md`\n- Vercel deployment: `.\u002Freference\u002Fvercel-setup.md`\n- eve docs: https:\u002F\u002Feve.dev\u002Fdocs (bundled locally at `node_modules\u002Feve\u002Fdocs\u002F` after install)\n- Vercel Connect: https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fvercel-connect\n\n---\n\n## Checklist Before Task Completion\n\nBefore marking ANY task as complete, verify:\n\n- [ ] Code changes have corresponding tests\n- [ ] `pnpm lint` passes with no errors\n- [ ] `pnpm typecheck` passes with no errors\n- [ ] `pnpm test` passes with no failures\n- [ ] No hardcoded credentials; the only Slack env var is `SLACK_CONNECTOR`\n- [ ] Follows eve filesystem conventions (tool filename = tool name, one tool per file)\n- [ ] Every tool has an `inputSchema`; outputs are JSON-serializable with secrets redacted\n- [ ] Non-idempotent side effects are idempotent or approval-gated (replay + at-least-once delivery)\n- [ ] Connector trigger path is `\u002Feve\u002Fv1\u002Fslack` and was attached with `--triggers`\n- [ ] `placeholderAuth()` replaced before production deploy\n- [ ] Model config uses a Gateway string ID (`anthropic\u002Fclaude-sonnet-5` default)\n\n---\n\n## Vercel KB Guides\n\nVerified guides on the Vercel Knowledge Base for deeper walkthroughs:\n\n- [eve hub on the Vercel KB](https:\u002F\u002Fvercel.com\u002Fkb\u002Feve) - all eve guides and templates in one place\n- [Build your first Slack agent with eve](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Feve-slack-agent-starter) - the end-to-end starter this skill's wizard mirrors\n- [Vercel Connect](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fvercel-connect) - credential brokering concepts, connectors, tokens, and trigger forwarding\n- [Build a Slack bot with Vercel Connect](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fbuild-a-slack-bot-with-vercel-connect) - Connect + Slack fundamentals (scopes, trigger events, webhook verification)\n- [How to add eve tools](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fhow-to-add-eve-tools) - `defineTool` patterns\n- [How to add eve skills](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fhow-to-add-eve-skills) - load-on-demand instructions\n- [Build a GitHub agent with Vercel Connect](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fgithub-agent-vercel-connect) - app-scoped Connect tokens in authored tools\n- [Build a Linear agent with Vercel Connect](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Flinear-agent-vercel-connect) - MCP connections with user-scoped auth\n- [Build an email agent with eve and Resend](https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Feve-agent-with-resend) - a second channel example beyond Slack\n",{"data":35,"body":38},{"name":4,"description":6,"version":36,"user-invocable":37},"5.0.0",true,{"type":39,"children":40},"root",[41,50,71,103,110,123,130,252,258,263,371,377,382,437,450,456,469,577,594,635,639,645,650,656,755,1035,1041,1052,1062,1088,1239,1242,1248,1253,1259,1362,1368,1373,1453,1463,1469,1477,1532,1537,1978,1984,1989,2034,2039,2042,2048,2060,2083,2275,2293,2316,2356,2362,2367,2518,2550,2570,2575,2602,2607,2610,2616,2622,2651,3085,3090,3096,3132,3435,3490,3496,3501,3635,3646,3692,3705,3711,3716,3792,3798,3803,4014,4076,4082,4130,4143,4146,4152,4158,4170,4214,4219,4225,4237,4250,4262,4290,4304,4374,4380,4408,4414,4440,4446,4459,4465,4477,4833,4839,4980,4985,4991,5011,5187,5190,5196,5202,5227,5357,5384,5402,5415,5436,5961,5966,6069,6076,6096,6453,6465,6477,6489,6875,6888,6923,6936,6941,7178,7199,7216,7219,7225,7237,7243,7266,7271,7316,7322,7348,7354,7366,7375,7439,7442,7448,7457,7462,7510,7513,7519,7690,7718,7740,7743,7749,7755,7760,7801,7813,7819,7847,7853,7858,7915,7921,7956,7968,7971,7977,7982,7991,7999,8037,8040,8046,8537,8557,8560,8566,8571,8659,8662,8668,8673,8835,8838,8844,8849,8966],{"type":42,"tag":43,"props":44,"children":46},"element","h1",{"id":45},"slack-agent-development-skill",[47],{"type":48,"value":49},"text","Slack Agent Development Skill",{"type":42,"tag":51,"props":52,"children":53},"p",{},[54,56,62,64,69],{"type":48,"value":55},"This skill builds Slack agents with ",{"type":42,"tag":57,"props":58,"children":59},"strong",{},[60],{"type":48,"value":61},"eve",{"type":48,"value":63}," — Vercel's filesystem-first framework for durable backend agents — using ",{"type":42,"tag":57,"props":65,"children":66},{},[67],{"type":48,"value":68},"Vercel Connect",{"type":48,"value":70}," for Slack credentials:",{"type":42,"tag":72,"props":73,"children":74},"ul",{},[75,93],{"type":42,"tag":76,"props":77,"children":78},"li",{},[79,83,85,91],{"type":42,"tag":57,"props":80,"children":81},{},[82],{"type":48,"value":61},{"type":48,"value":84}," (",{"type":42,"tag":86,"props":87,"children":89},"code",{"className":88},[],[90],{"type":48,"value":61},{"type":48,"value":92}," package) — agent runtime, tools, channels, durability",{"type":42,"tag":76,"props":94,"children":95},{},[96,101],{"type":42,"tag":57,"props":97,"children":98},{},[99],{"type":48,"value":100},"@vercel\u002Fconnect",{"type":48,"value":102}," — brokered short-lived Slack tokens; no bot tokens or signing secrets to manage",{"type":42,"tag":104,"props":105,"children":107},"h2",{"id":106},"skill-invocation-handling",[108],{"type":48,"value":109},"Skill Invocation Handling",{"type":42,"tag":51,"props":111,"children":112},{},[113,115,121],{"type":48,"value":114},"When this skill is invoked via ",{"type":42,"tag":86,"props":116,"children":118},{"className":117},[],[119],{"type":48,"value":120},"\u002Fslack-agent",{"type":48,"value":122},", check for arguments and route accordingly:",{"type":42,"tag":124,"props":125,"children":127},"h3",{"id":126},"command-arguments",[128],{"type":48,"value":129},"Command Arguments",{"type":42,"tag":131,"props":132,"children":133},"table",{},[134,153],{"type":42,"tag":135,"props":136,"children":137},"thead",{},[138],{"type":42,"tag":139,"props":140,"children":141},"tr",{},[142,148],{"type":42,"tag":143,"props":144,"children":145},"th",{},[146],{"type":48,"value":147},"Argument",{"type":42,"tag":143,"props":149,"children":150},{},[151],{"type":48,"value":152},"Action",{"type":42,"tag":154,"props":155,"children":156},"tbody",{},[157,188,205,222,239],{"type":42,"tag":139,"props":158,"children":159},{},[160,170],{"type":42,"tag":161,"props":162,"children":163},"td",{},[164],{"type":42,"tag":86,"props":165,"children":167},{"className":166},[],[168],{"type":48,"value":169},"new",{"type":42,"tag":161,"props":171,"children":172},{},[173,178,180,186],{"type":42,"tag":57,"props":174,"children":175},{},[176],{"type":48,"value":177},"Run the setup wizard from Phase 1.",{"type":48,"value":179}," Read ",{"type":42,"tag":86,"props":181,"children":183},{"className":182},[],[184],{"type":48,"value":185},".\u002Fwizard\u002F1-project-setup.md",{"type":48,"value":187}," and guide the user through creating a new Slack agent.",{"type":42,"tag":139,"props":189,"children":190},{},[191,200],{"type":42,"tag":161,"props":192,"children":193},{},[194],{"type":42,"tag":86,"props":195,"children":197},{"className":196},[],[198],{"type":48,"value":199},"configure",{"type":42,"tag":161,"props":201,"children":202},{},[203],{"type":48,"value":204},"Start wizard at Phase 2 or 3 for existing projects",{"type":42,"tag":139,"props":206,"children":207},{},[208,217],{"type":42,"tag":161,"props":209,"children":210},{},[211],{"type":42,"tag":86,"props":212,"children":214},{"className":213},[],[215],{"type":48,"value":216},"deploy",{"type":42,"tag":161,"props":218,"children":219},{},[220],{"type":48,"value":221},"Start wizard at Phase 5 for production deployment",{"type":42,"tag":139,"props":223,"children":224},{},[225,234],{"type":42,"tag":161,"props":226,"children":227},{},[228],{"type":42,"tag":86,"props":229,"children":231},{"className":230},[],[232],{"type":48,"value":233},"test",{"type":42,"tag":161,"props":235,"children":236},{},[237],{"type":48,"value":238},"Start wizard at Phase 6 to set up testing",{"type":42,"tag":139,"props":240,"children":241},{},[242,247],{"type":42,"tag":161,"props":243,"children":244},{},[245],{"type":48,"value":246},"(no argument)",{"type":42,"tag":161,"props":248,"children":249},{},[250],{"type":48,"value":251},"Auto-detect based on project state (see below)",{"type":42,"tag":124,"props":253,"children":255},{"id":254},"auto-detection-no-argument",[256],{"type":48,"value":257},"Auto-Detection (No Argument)",{"type":42,"tag":51,"props":259,"children":260},{},[261],{"type":48,"value":262},"If invoked without arguments, detect the project state and route appropriately:",{"type":42,"tag":264,"props":265,"children":266},"ol",{},[267,307,323,341,351,361],{"type":42,"tag":76,"props":268,"children":269},{},[270,298,300,305],{"type":42,"tag":57,"props":271,"children":272},{},[273,275,281,283,288,290,296],{"type":48,"value":274},"No ",{"type":42,"tag":86,"props":276,"children":278},{"className":277},[],[279],{"type":48,"value":280},"package.json",{"type":48,"value":282}," with ",{"type":42,"tag":86,"props":284,"children":286},{"className":285},[],[287],{"type":48,"value":61},{"type":48,"value":289}," and no ",{"type":42,"tag":86,"props":291,"children":293},{"className":292},[],[294],{"type":48,"value":295},"agent\u002F",{"type":48,"value":297}," directory",{"type":48,"value":299}," → Treat as ",{"type":42,"tag":86,"props":301,"children":303},{"className":302},[],[304],{"type":48,"value":169},{"type":48,"value":306},", start Phase 1",{"type":42,"tag":76,"props":308,"children":309},{},[310,321],{"type":42,"tag":57,"props":311,"children":312},{},[313,315],{"type":48,"value":314},"Has eve project but no ",{"type":42,"tag":86,"props":316,"children":318},{"className":317},[],[319],{"type":48,"value":320},"agent\u002Fchannels\u002Fslack.ts",{"type":48,"value":322}," → Start Phase 2 (Slack connector + channel)",{"type":42,"tag":76,"props":324,"children":325},{},[326,339],{"type":42,"tag":57,"props":327,"children":328},{},[329,331,337],{"type":48,"value":330},"Has Slack channel but no ",{"type":42,"tag":86,"props":332,"children":334},{"className":333},[],[335],{"type":48,"value":336},"SLACK_CONNECTOR",{"type":48,"value":338}," configured",{"type":48,"value":340}," → Start Phase 3",{"type":42,"tag":76,"props":342,"children":343},{},[344,349],{"type":42,"tag":57,"props":345,"children":346},{},[347],{"type":48,"value":348},"Configured but not deployed",{"type":48,"value":350}," → Start Phase 5 (the Slack surface only works on a deployment)",{"type":42,"tag":76,"props":352,"children":353},{},[354,359],{"type":42,"tag":57,"props":355,"children":356},{},[357],{"type":48,"value":358},"Deployed but no tests",{"type":48,"value":360}," → Start Phase 6",{"type":42,"tag":76,"props":362,"children":363},{},[364,369],{"type":42,"tag":57,"props":365,"children":366},{},[367],{"type":48,"value":368},"Otherwise",{"type":48,"value":370}," → Provide general assistance using this skill's patterns",{"type":42,"tag":124,"props":372,"children":374},{"id":373},"project-detection",[375],{"type":48,"value":376},"Project Detection",{"type":42,"tag":51,"props":378,"children":379},{},[380],{"type":48,"value":381},"Detect an eve project by either signal:",{"type":42,"tag":72,"props":383,"children":384},{},[385,406],{"type":42,"tag":76,"props":386,"children":387},{},[388,404],{"type":42,"tag":57,"props":389,"children":390},{},[391,396,398],{"type":42,"tag":86,"props":392,"children":394},{"className":393},[],[395],{"type":48,"value":280},{"type":48,"value":397}," contains ",{"type":42,"tag":86,"props":399,"children":401},{"className":400},[],[402],{"type":48,"value":403},"\"eve\"",{"type":48,"value":405}," as a dependency",{"type":42,"tag":76,"props":407,"children":408},{},[409,420,421,427,429,435],{"type":42,"tag":57,"props":410,"children":411},{},[412,414,419],{"type":48,"value":413},"An ",{"type":42,"tag":86,"props":415,"children":417},{"className":416},[],[418],{"type":48,"value":295},{"type":48,"value":297},{"type":48,"value":282},{"type":42,"tag":86,"props":422,"children":424},{"className":423},[],[425],{"type":48,"value":426},"instructions.md",{"type":48,"value":428}," and\u002For ",{"type":42,"tag":86,"props":430,"children":432},{"className":431},[],[433],{"type":48,"value":434},"agent.ts",{"type":48,"value":436}," exists",{"type":42,"tag":51,"props":438,"children":439},{},[440,442,448],{"type":48,"value":441},"If neither is present, this is a new project: scaffold with ",{"type":42,"tag":86,"props":443,"children":445},{"className":444},[],[446],{"type":48,"value":447},"npx eve@latest init",{"type":48,"value":449}," (Node 24+ required).",{"type":42,"tag":124,"props":451,"children":453},{"id":452},"wizard-phases",[454],{"type":48,"value":455},"Wizard Phases",{"type":42,"tag":51,"props":457,"children":458},{},[459,461,467],{"type":48,"value":460},"The wizard is located in ",{"type":42,"tag":86,"props":462,"children":464},{"className":463},[],[465],{"type":48,"value":466},".\u002Fwizard\u002F",{"type":48,"value":468}," with these phases:",{"type":42,"tag":72,"props":470,"children":471},{},[472,488,499,510,528,547,566],{"type":42,"tag":76,"props":473,"children":474},{},[475,481,483],{"type":42,"tag":86,"props":476,"children":478},{"className":477},[],[479],{"type":48,"value":480},"1-project-setup.md",{"type":48,"value":482}," - Understand purpose, generate custom implementation plan, scaffold with ",{"type":42,"tag":86,"props":484,"children":486},{"className":485},[],[487],{"type":48,"value":447},{"type":42,"tag":76,"props":489,"children":490},{},[491,497],{"type":42,"tag":86,"props":492,"children":494},{"className":493},[],[495],{"type":48,"value":496},"1b-approve-plan.md",{"type":48,"value":498}," - Present plan for user approval before scaffolding",{"type":42,"tag":76,"props":500,"children":501},{},[502,508],{"type":42,"tag":86,"props":503,"children":505},{"className":504},[],[506],{"type":48,"value":507},"2-create-slack-app.md",{"type":48,"value":509}," - Create the Slack connector with Vercel Connect and add the Slack channel",{"type":42,"tag":76,"props":511,"children":512},{},[513,519,521,526],{"type":42,"tag":86,"props":514,"children":516},{"className":515},[],[517],{"type":48,"value":518},"3-configure-environment.md",{"type":48,"value":520}," - Set up env vars (",{"type":42,"tag":86,"props":522,"children":524},{"className":523},[],[525],{"type":48,"value":336},{"type":48,"value":527},", model credentials)",{"type":42,"tag":76,"props":529,"children":530},{},[531,537,539,545],{"type":42,"tag":86,"props":532,"children":534},{"className":533},[],[535],{"type":48,"value":536},"4-test-locally.md",{"type":48,"value":538}," - Test agent logic locally with the ",{"type":42,"tag":86,"props":540,"children":542},{"className":541},[],[543],{"type":48,"value":544},"eve dev",{"type":48,"value":546}," TUI (Slack surface tests happen after deploy)",{"type":42,"tag":76,"props":548,"children":549},{},[550,556,558,564],{"type":42,"tag":86,"props":551,"children":553},{"className":552},[],[554],{"type":48,"value":555},"5-deploy-production.md",{"type":48,"value":557}," - Deploy with ",{"type":42,"tag":86,"props":559,"children":561},{"className":560},[],[562],{"type":48,"value":563},"eve deploy",{"type":48,"value":565},", verify the Slack surface",{"type":42,"tag":76,"props":567,"children":568},{},[569,575],{"type":42,"tag":86,"props":570,"children":572},{"className":571},[],[573],{"type":48,"value":574},"6-setup-testing.md",{"type":48,"value":576}," - Vitest configuration",{"type":42,"tag":51,"props":578,"children":579},{},[580,585,587,592],{"type":42,"tag":57,"props":581,"children":582},{},[583],{"type":48,"value":584},"IMPORTANT:",{"type":48,"value":586}," For ",{"type":42,"tag":86,"props":588,"children":590},{"className":589},[],[591],{"type":48,"value":169},{"type":48,"value":593}," projects, you MUST:",{"type":42,"tag":264,"props":595,"children":596},{},[597,609,614,625,630],{"type":42,"tag":76,"props":598,"children":599},{},[600,602,607],{"type":48,"value":601},"Read ",{"type":42,"tag":86,"props":603,"children":605},{"className":604},[],[606],{"type":48,"value":185},{"type":48,"value":608}," first",{"type":42,"tag":76,"props":610,"children":611},{},[612],{"type":48,"value":613},"Ask the user what kind of agent they want to build",{"type":42,"tag":76,"props":615,"children":616},{},[617,619],{"type":48,"value":618},"Generate a custom implementation plan using ",{"type":42,"tag":86,"props":620,"children":622},{"className":621},[],[623],{"type":48,"value":624},".\u002Freference\u002Fagent-archetypes.md",{"type":42,"tag":76,"props":626,"children":627},{},[628],{"type":48,"value":629},"Present the plan for approval (Phase 1b) BEFORE scaffolding the project",{"type":42,"tag":76,"props":631,"children":632},{},[633],{"type":48,"value":634},"Only proceed to scaffold after the plan is approved",{"type":42,"tag":636,"props":637,"children":638},"hr",{},[],{"type":42,"tag":104,"props":640,"children":642},{"id":641},"general-development-guidance",[643],{"type":48,"value":644},"General Development Guidance",{"type":42,"tag":51,"props":646,"children":647},{},[648],{"type":48,"value":649},"You are working on a Slack agent project built with eve. Follow these mandatory practices for all code changes.",{"type":42,"tag":104,"props":651,"children":653},{"id":652},"project-stack",[654],{"type":48,"value":655},"Project Stack",{"type":42,"tag":72,"props":657,"children":658},{},[659,669,694,718,728,738],{"type":42,"tag":76,"props":660,"children":661},{},[662,667],{"type":42,"tag":57,"props":663,"children":664},{},[665],{"type":48,"value":666},"Framework",{"type":48,"value":668},": eve (filesystem-first agent framework; Node 24+)",{"type":42,"tag":76,"props":670,"children":671},{},[672,677,679,685,687,692],{"type":42,"tag":57,"props":673,"children":674},{},[675],{"type":48,"value":676},"Slack channel",{"type":48,"value":678},": ",{"type":42,"tag":86,"props":680,"children":682},{"className":681},[],[683],{"type":48,"value":684},"eve\u002Fchannels\u002Fslack",{"type":48,"value":686}," + ",{"type":42,"tag":86,"props":688,"children":690},{"className":689},[],[691],{"type":48,"value":100},{"type":48,"value":693}," for credentials",{"type":42,"tag":76,"props":695,"children":696},{},[697,702,704,710,712],{"type":42,"tag":57,"props":698,"children":699},{},[700],{"type":48,"value":701},"AI",{"type":48,"value":703},": model routed through Vercel AI Gateway by default (",{"type":42,"tag":86,"props":705,"children":707},{"className":706},[],[708],{"type":48,"value":709},"anthropic\u002Fclaude-sonnet-5",{"type":48,"value":711},"); tool schemas with ",{"type":42,"tag":86,"props":713,"children":715},{"className":714},[],[716],{"type":48,"value":717},"zod",{"type":42,"tag":76,"props":719,"children":720},{},[721,726],{"type":42,"tag":57,"props":722,"children":723},{},[724],{"type":48,"value":725},"Durability",{"type":48,"value":727},": Workflow SDK under the hood (Vercel Workflows when deployed on Vercel)",{"type":42,"tag":76,"props":729,"children":730},{},[731,736],{"type":42,"tag":57,"props":732,"children":733},{},[734],{"type":48,"value":735},"Linting",{"type":48,"value":737},": Biome",{"type":42,"tag":76,"props":739,"children":740},{},[741,746,748,753],{"type":42,"tag":57,"props":742,"children":743},{},[744],{"type":48,"value":745},"Package Manager",{"type":48,"value":747},": pnpm (or npm — ",{"type":42,"tag":86,"props":749,"children":751},{"className":750},[],[752],{"type":48,"value":447},{"type":48,"value":754}," installs with npm)",{"type":42,"tag":756,"props":757,"children":762},"pre",{"className":758,"code":759,"language":760,"meta":761,"style":761},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"engines\": { \"node\": \"24.x\" },\n  \"dependencies\": {\n    \"eve\": \"latest\",\n    \"ai\": \"latest\",\n    \"zod\": \"^3.x\",\n    \"@vercel\u002Fconnect\": \"latest\"\n  }\n}\n","json","",[763],{"type":42,"tag":86,"props":764,"children":765},{"__ignoreMap":761},[766,778,846,871,910,947,984,1017,1026],{"type":42,"tag":767,"props":768,"children":771},"span",{"class":769,"line":770},"line",1,[772],{"type":42,"tag":767,"props":773,"children":775},{"style":774},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[776],{"type":48,"value":777},"{\n",{"type":42,"tag":767,"props":779,"children":781},{"class":769,"line":780},2,[782,787,793,798,803,808,813,819,823,827,831,837,841],{"type":42,"tag":767,"props":783,"children":784},{"style":774},[785],{"type":48,"value":786},"  \"",{"type":42,"tag":767,"props":788,"children":790},{"style":789},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[791],{"type":48,"value":792},"engines",{"type":42,"tag":767,"props":794,"children":795},{"style":774},[796],{"type":48,"value":797},"\"",{"type":42,"tag":767,"props":799,"children":800},{"style":774},[801],{"type":48,"value":802},":",{"type":42,"tag":767,"props":804,"children":805},{"style":774},[806],{"type":48,"value":807}," {",{"type":42,"tag":767,"props":809,"children":810},{"style":774},[811],{"type":48,"value":812}," \"",{"type":42,"tag":767,"props":814,"children":816},{"style":815},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[817],{"type":48,"value":818},"node",{"type":42,"tag":767,"props":820,"children":821},{"style":774},[822],{"type":48,"value":797},{"type":42,"tag":767,"props":824,"children":825},{"style":774},[826],{"type":48,"value":802},{"type":42,"tag":767,"props":828,"children":829},{"style":774},[830],{"type":48,"value":812},{"type":42,"tag":767,"props":832,"children":834},{"style":833},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[835],{"type":48,"value":836},"24.x",{"type":42,"tag":767,"props":838,"children":839},{"style":774},[840],{"type":48,"value":797},{"type":42,"tag":767,"props":842,"children":843},{"style":774},[844],{"type":48,"value":845}," },\n",{"type":42,"tag":767,"props":847,"children":848},{"class":769,"line":26},[849,853,858,862,866],{"type":42,"tag":767,"props":850,"children":851},{"style":774},[852],{"type":48,"value":786},{"type":42,"tag":767,"props":854,"children":855},{"style":789},[856],{"type":48,"value":857},"dependencies",{"type":42,"tag":767,"props":859,"children":860},{"style":774},[861],{"type":48,"value":797},{"type":42,"tag":767,"props":863,"children":864},{"style":774},[865],{"type":48,"value":802},{"type":42,"tag":767,"props":867,"children":868},{"style":774},[869],{"type":48,"value":870}," {\n",{"type":42,"tag":767,"props":872,"children":874},{"class":769,"line":873},4,[875,880,884,888,892,896,901,905],{"type":42,"tag":767,"props":876,"children":877},{"style":774},[878],{"type":48,"value":879},"    \"",{"type":42,"tag":767,"props":881,"children":882},{"style":815},[883],{"type":48,"value":61},{"type":42,"tag":767,"props":885,"children":886},{"style":774},[887],{"type":48,"value":797},{"type":42,"tag":767,"props":889,"children":890},{"style":774},[891],{"type":48,"value":802},{"type":42,"tag":767,"props":893,"children":894},{"style":774},[895],{"type":48,"value":812},{"type":42,"tag":767,"props":897,"children":898},{"style":833},[899],{"type":48,"value":900},"latest",{"type":42,"tag":767,"props":902,"children":903},{"style":774},[904],{"type":48,"value":797},{"type":42,"tag":767,"props":906,"children":907},{"style":774},[908],{"type":48,"value":909},",\n",{"type":42,"tag":767,"props":911,"children":913},{"class":769,"line":912},5,[914,918,923,927,931,935,939,943],{"type":42,"tag":767,"props":915,"children":916},{"style":774},[917],{"type":48,"value":879},{"type":42,"tag":767,"props":919,"children":920},{"style":815},[921],{"type":48,"value":922},"ai",{"type":42,"tag":767,"props":924,"children":925},{"style":774},[926],{"type":48,"value":797},{"type":42,"tag":767,"props":928,"children":929},{"style":774},[930],{"type":48,"value":802},{"type":42,"tag":767,"props":932,"children":933},{"style":774},[934],{"type":48,"value":812},{"type":42,"tag":767,"props":936,"children":937},{"style":833},[938],{"type":48,"value":900},{"type":42,"tag":767,"props":940,"children":941},{"style":774},[942],{"type":48,"value":797},{"type":42,"tag":767,"props":944,"children":945},{"style":774},[946],{"type":48,"value":909},{"type":42,"tag":767,"props":948,"children":950},{"class":769,"line":949},6,[951,955,959,963,967,971,976,980],{"type":42,"tag":767,"props":952,"children":953},{"style":774},[954],{"type":48,"value":879},{"type":42,"tag":767,"props":956,"children":957},{"style":815},[958],{"type":48,"value":717},{"type":42,"tag":767,"props":960,"children":961},{"style":774},[962],{"type":48,"value":797},{"type":42,"tag":767,"props":964,"children":965},{"style":774},[966],{"type":48,"value":802},{"type":42,"tag":767,"props":968,"children":969},{"style":774},[970],{"type":48,"value":812},{"type":42,"tag":767,"props":972,"children":973},{"style":833},[974],{"type":48,"value":975},"^3.x",{"type":42,"tag":767,"props":977,"children":978},{"style":774},[979],{"type":48,"value":797},{"type":42,"tag":767,"props":981,"children":982},{"style":774},[983],{"type":48,"value":909},{"type":42,"tag":767,"props":985,"children":987},{"class":769,"line":986},7,[988,992,996,1000,1004,1008,1012],{"type":42,"tag":767,"props":989,"children":990},{"style":774},[991],{"type":48,"value":879},{"type":42,"tag":767,"props":993,"children":994},{"style":815},[995],{"type":48,"value":100},{"type":42,"tag":767,"props":997,"children":998},{"style":774},[999],{"type":48,"value":797},{"type":42,"tag":767,"props":1001,"children":1002},{"style":774},[1003],{"type":48,"value":802},{"type":42,"tag":767,"props":1005,"children":1006},{"style":774},[1007],{"type":48,"value":812},{"type":42,"tag":767,"props":1009,"children":1010},{"style":833},[1011],{"type":48,"value":900},{"type":42,"tag":767,"props":1013,"children":1014},{"style":774},[1015],{"type":48,"value":1016},"\"\n",{"type":42,"tag":767,"props":1018,"children":1020},{"class":769,"line":1019},8,[1021],{"type":42,"tag":767,"props":1022,"children":1023},{"style":774},[1024],{"type":48,"value":1025},"  }\n",{"type":42,"tag":767,"props":1027,"children":1029},{"class":769,"line":1028},9,[1030],{"type":42,"tag":767,"props":1031,"children":1032},{"style":774},[1033],{"type":48,"value":1034},"}\n",{"type":42,"tag":124,"props":1036,"children":1038},{"id":1037},"filesystem-first-layout",[1039],{"type":48,"value":1040},"Filesystem-First Layout",{"type":42,"tag":51,"props":1042,"children":1043},{},[1044,1046,1051],{"type":48,"value":1045},"In eve, a file's location says what it does, and its path usually gives it its name. The whole agent lives under ",{"type":42,"tag":86,"props":1047,"children":1049},{"className":1048},[],[1050],{"type":48,"value":295},{"type":48,"value":802},{"type":42,"tag":756,"props":1053,"children":1057},{"className":1054,"code":1056,"language":48},[1055],"language-text","agent\u002F\n├── instructions.md        # Always-on system prompt\n├── agent.ts               # Runtime config (defineAgent): model, reasoning, compaction\n├── tools\u002F                 # Tools — filename (snake_case ASCII) = tool name the model sees\n│   ├── get_weather.ts\n│   └── search_docs.ts\n├── skills\u002F                # Load-on-demand instructions (*.md with description frontmatter)\n│   └── incident-triage.md\n├── channels\u002F\n│   └── slack.ts           # Slack channel — filename registers it at \u002Feve\u002Fv1\u002Fslack\n├── connections\u002F           # MCP \u002F OpenAPI connections (optional)\n└── hooks\u002F                 # Subscribe to runtime stream events (optional)\n",[1058],{"type":42,"tag":86,"props":1059,"children":1060},{"__ignoreMap":761},[1061],{"type":48,"value":1056},{"type":42,"tag":51,"props":1063,"children":1064},{},[1065,1067,1072,1073,1078,1080,1086],{"type":48,"value":1066},"Even a two-file agent (",{"type":42,"tag":86,"props":1068,"children":1070},{"className":1069},[],[1071],{"type":48,"value":426},{"type":48,"value":686},{"type":42,"tag":86,"props":1074,"children":1076},{"className":1075},[],[1077],{"type":48,"value":434},{"type":48,"value":1079},") gets file, shell, web, and delegation tools out of the box from the default harness. Full docs are bundled at ",{"type":42,"tag":86,"props":1081,"children":1083},{"className":1082},[],[1084],{"type":48,"value":1085},"node_modules\u002Feve\u002Fdocs\u002F",{"type":48,"value":1087}," once eve is installed — read them when a detail isn't covered here.",{"type":42,"tag":756,"props":1089,"children":1093},{"className":1090,"code":1091,"language":1092,"meta":761,"style":761},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F agent\u002Fagent.ts\nimport { defineAgent } from \"eve\";\n\nexport default defineAgent({\n  model: \"anthropic\u002Fclaude-sonnet-5\", \u002F\u002F routed via Vercel AI Gateway\n});\n","ts",[1094],{"type":42,"tag":86,"props":1095,"children":1096},{"__ignoreMap":761},[1097,1106,1152,1160,1187,1222],{"type":42,"tag":767,"props":1098,"children":1099},{"class":769,"line":770},[1100],{"type":42,"tag":767,"props":1101,"children":1103},{"style":1102},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1104],{"type":48,"value":1105},"\u002F\u002F agent\u002Fagent.ts\n",{"type":42,"tag":767,"props":1107,"children":1108},{"class":769,"line":780},[1109,1115,1119,1125,1130,1135,1139,1143,1147],{"type":42,"tag":767,"props":1110,"children":1112},{"style":1111},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[1113],{"type":48,"value":1114},"import",{"type":42,"tag":767,"props":1116,"children":1117},{"style":774},[1118],{"type":48,"value":807},{"type":42,"tag":767,"props":1120,"children":1122},{"style":1121},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1123],{"type":48,"value":1124}," defineAgent",{"type":42,"tag":767,"props":1126,"children":1127},{"style":774},[1128],{"type":48,"value":1129}," }",{"type":42,"tag":767,"props":1131,"children":1132},{"style":1111},[1133],{"type":48,"value":1134}," from",{"type":42,"tag":767,"props":1136,"children":1137},{"style":774},[1138],{"type":48,"value":812},{"type":42,"tag":767,"props":1140,"children":1141},{"style":833},[1142],{"type":48,"value":61},{"type":42,"tag":767,"props":1144,"children":1145},{"style":774},[1146],{"type":48,"value":797},{"type":42,"tag":767,"props":1148,"children":1149},{"style":774},[1150],{"type":48,"value":1151},";\n",{"type":42,"tag":767,"props":1153,"children":1154},{"class":769,"line":26},[1155],{"type":42,"tag":767,"props":1156,"children":1157},{"emptyLinePlaceholder":37},[1158],{"type":48,"value":1159},"\n",{"type":42,"tag":767,"props":1161,"children":1162},{"class":769,"line":873},[1163,1168,1173,1178,1183],{"type":42,"tag":767,"props":1164,"children":1165},{"style":1111},[1166],{"type":48,"value":1167},"export",{"type":42,"tag":767,"props":1169,"children":1170},{"style":1111},[1171],{"type":48,"value":1172}," default",{"type":42,"tag":767,"props":1174,"children":1176},{"style":1175},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[1177],{"type":48,"value":1124},{"type":42,"tag":767,"props":1179,"children":1180},{"style":1121},[1181],{"type":48,"value":1182},"(",{"type":42,"tag":767,"props":1184,"children":1185},{"style":774},[1186],{"type":48,"value":777},{"type":42,"tag":767,"props":1188,"children":1189},{"class":769,"line":912},[1190,1196,1200,1204,1208,1212,1217],{"type":42,"tag":767,"props":1191,"children":1193},{"style":1192},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[1194],{"type":48,"value":1195},"  model",{"type":42,"tag":767,"props":1197,"children":1198},{"style":774},[1199],{"type":48,"value":802},{"type":42,"tag":767,"props":1201,"children":1202},{"style":774},[1203],{"type":48,"value":812},{"type":42,"tag":767,"props":1205,"children":1206},{"style":833},[1207],{"type":48,"value":709},{"type":42,"tag":767,"props":1209,"children":1210},{"style":774},[1211],{"type":48,"value":797},{"type":42,"tag":767,"props":1213,"children":1214},{"style":774},[1215],{"type":48,"value":1216},",",{"type":42,"tag":767,"props":1218,"children":1219},{"style":1102},[1220],{"type":48,"value":1221}," \u002F\u002F routed via Vercel AI Gateway\n",{"type":42,"tag":767,"props":1223,"children":1224},{"class":769,"line":949},[1225,1230,1235],{"type":42,"tag":767,"props":1226,"children":1227},{"style":774},[1228],{"type":48,"value":1229},"}",{"type":42,"tag":767,"props":1231,"children":1232},{"style":1121},[1233],{"type":48,"value":1234},")",{"type":42,"tag":767,"props":1236,"children":1237},{"style":774},[1238],{"type":48,"value":1151},{"type":42,"tag":636,"props":1240,"children":1241},{},[],{"type":42,"tag":104,"props":1243,"children":1245},{"id":1244},"quality-standards-mandatory",[1246],{"type":48,"value":1247},"Quality Standards (MANDATORY)",{"type":42,"tag":51,"props":1249,"children":1250},{},[1251],{"type":48,"value":1252},"These quality requirements MUST be followed for every code change. There are no exceptions.",{"type":42,"tag":124,"props":1254,"children":1256},{"id":1255},"after-every-file-modification",[1257],{"type":48,"value":1258},"After EVERY File Modification",{"type":42,"tag":264,"props":1260,"children":1261},{},[1262,1326],{"type":42,"tag":76,"props":1263,"children":1264},{},[1265,1270,1292],{"type":42,"tag":57,"props":1266,"children":1267},{},[1268],{"type":48,"value":1269},"Run linting immediately:",{"type":42,"tag":756,"props":1271,"children":1275},{"className":1272,"code":1273,"language":1274,"meta":761,"style":761},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm lint\n","bash",[1276],{"type":42,"tag":86,"props":1277,"children":1278},{"__ignoreMap":761},[1279],{"type":42,"tag":767,"props":1280,"children":1281},{"class":769,"line":770},[1282,1287],{"type":42,"tag":767,"props":1283,"children":1284},{"style":815},[1285],{"type":48,"value":1286},"pnpm",{"type":42,"tag":767,"props":1288,"children":1289},{"style":833},[1290],{"type":48,"value":1291}," lint\n",{"type":42,"tag":72,"props":1293,"children":1294},{},[1295,1308,1313],{"type":42,"tag":76,"props":1296,"children":1297},{},[1298,1300,1306],{"type":48,"value":1299},"If errors exist, run ",{"type":42,"tag":86,"props":1301,"children":1303},{"className":1302},[],[1304],{"type":48,"value":1305},"pnpm lint --write",{"type":48,"value":1307}," for auto-fixes",{"type":42,"tag":76,"props":1309,"children":1310},{},[1311],{"type":48,"value":1312},"Manually fix remaining issues",{"type":42,"tag":76,"props":1314,"children":1315},{},[1316,1318,1324],{"type":48,"value":1317},"Re-run ",{"type":42,"tag":86,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":48,"value":1323},"pnpm lint",{"type":48,"value":1325}," to verify",{"type":42,"tag":76,"props":1327,"children":1328},{},[1329,1334],{"type":42,"tag":57,"props":1330,"children":1331},{},[1332],{"type":48,"value":1333},"Check for corresponding test file:",{"type":42,"tag":72,"props":1335,"children":1336},{},[1337,1357],{"type":42,"tag":76,"props":1338,"children":1339},{},[1340,1342,1348,1350,1356],{"type":48,"value":1341},"If you modified ",{"type":42,"tag":86,"props":1343,"children":1345},{"className":1344},[],[1346],{"type":48,"value":1347},"foo.ts",{"type":48,"value":1349},", check if ",{"type":42,"tag":86,"props":1351,"children":1353},{"className":1352},[],[1354],{"type":48,"value":1355},"foo.test.ts",{"type":48,"value":436},{"type":42,"tag":76,"props":1358,"children":1359},{},[1360],{"type":48,"value":1361},"If no test file exists and the file exports functions, create one",{"type":42,"tag":124,"props":1363,"children":1365},{"id":1364},"before-completing-any-task",[1366],{"type":48,"value":1367},"Before Completing ANY Task",{"type":42,"tag":51,"props":1369,"children":1370},{},[1371],{"type":48,"value":1372},"You MUST run all quality checks and fix any issues before marking a task complete:",{"type":42,"tag":756,"props":1374,"children":1376},{"className":1272,"code":1375,"language":1274,"meta":761,"style":761},"# 1. TypeScript compilation - must pass\npnpm typecheck\n\n# 2. Linting - must pass with no errors\npnpm lint\n\n# 3. Tests - all tests must pass\npnpm test\n",[1377],{"type":42,"tag":86,"props":1378,"children":1379},{"__ignoreMap":761},[1380,1388,1400,1407,1415,1426,1433,1441],{"type":42,"tag":767,"props":1381,"children":1382},{"class":769,"line":770},[1383],{"type":42,"tag":767,"props":1384,"children":1385},{"style":1102},[1386],{"type":48,"value":1387},"# 1. TypeScript compilation - must pass\n",{"type":42,"tag":767,"props":1389,"children":1390},{"class":769,"line":780},[1391,1395],{"type":42,"tag":767,"props":1392,"children":1393},{"style":815},[1394],{"type":48,"value":1286},{"type":42,"tag":767,"props":1396,"children":1397},{"style":833},[1398],{"type":48,"value":1399}," typecheck\n",{"type":42,"tag":767,"props":1401,"children":1402},{"class":769,"line":26},[1403],{"type":42,"tag":767,"props":1404,"children":1405},{"emptyLinePlaceholder":37},[1406],{"type":48,"value":1159},{"type":42,"tag":767,"props":1408,"children":1409},{"class":769,"line":873},[1410],{"type":42,"tag":767,"props":1411,"children":1412},{"style":1102},[1413],{"type":48,"value":1414},"# 2. Linting - must pass with no errors\n",{"type":42,"tag":767,"props":1416,"children":1417},{"class":769,"line":912},[1418,1422],{"type":42,"tag":767,"props":1419,"children":1420},{"style":815},[1421],{"type":48,"value":1286},{"type":42,"tag":767,"props":1423,"children":1424},{"style":833},[1425],{"type":48,"value":1291},{"type":42,"tag":767,"props":1427,"children":1428},{"class":769,"line":949},[1429],{"type":42,"tag":767,"props":1430,"children":1431},{"emptyLinePlaceholder":37},[1432],{"type":48,"value":1159},{"type":42,"tag":767,"props":1434,"children":1435},{"class":769,"line":986},[1436],{"type":42,"tag":767,"props":1437,"children":1438},{"style":1102},[1439],{"type":48,"value":1440},"# 3. Tests - all tests must pass\n",{"type":42,"tag":767,"props":1442,"children":1443},{"class":769,"line":1019},[1444,1448],{"type":42,"tag":767,"props":1445,"children":1446},{"style":815},[1447],{"type":48,"value":1286},{"type":42,"tag":767,"props":1449,"children":1450},{"style":833},[1451],{"type":48,"value":1452}," test\n",{"type":42,"tag":51,"props":1454,"children":1455},{},[1456,1461],{"type":42,"tag":57,"props":1457,"children":1458},{},[1459],{"type":48,"value":1460},"Do NOT complete a task if any of these fail.",{"type":48,"value":1462}," Fix the issues first.",{"type":42,"tag":124,"props":1464,"children":1466},{"id":1465},"unit-tests-required",[1467],{"type":48,"value":1468},"Unit Tests Required",{"type":42,"tag":51,"props":1470,"children":1471},{},[1472],{"type":42,"tag":57,"props":1473,"children":1474},{},[1475],{"type":48,"value":1476},"For ANY code change, you MUST write or update unit tests.",{"type":42,"tag":72,"props":1478,"children":1479},{},[1480,1505,1514],{"type":42,"tag":76,"props":1481,"children":1482},{},[1483,1488,1490,1496,1498,1504],{"type":42,"tag":57,"props":1484,"children":1485},{},[1486],{"type":48,"value":1487},"Location",{"type":48,"value":1489},": Co-located ",{"type":42,"tag":86,"props":1491,"children":1493},{"className":1492},[],[1494],{"type":48,"value":1495},"*.test.ts",{"type":48,"value":1497}," files (e.g. ",{"type":42,"tag":86,"props":1499,"children":1501},{"className":1500},[],[1502],{"type":48,"value":1503},"agent\u002Ftools\u002Fget_weather.test.ts",{"type":48,"value":1234},{"type":42,"tag":76,"props":1506,"children":1507},{},[1508,1512],{"type":42,"tag":57,"props":1509,"children":1510},{},[1511],{"type":48,"value":666},{"type":48,"value":1513},": Vitest",{"type":42,"tag":76,"props":1515,"children":1516},{},[1517,1522,1524,1530],{"type":42,"tag":57,"props":1518,"children":1519},{},[1520],{"type":48,"value":1521},"Coverage",{"type":48,"value":1523},": All exported functions and every tool's ",{"type":42,"tag":86,"props":1525,"children":1527},{"className":1526},[],[1528],{"type":48,"value":1529},"execute()",{"type":48,"value":1531}," (including error paths) must have tests",{"type":42,"tag":51,"props":1533,"children":1534},{},[1535],{"type":48,"value":1536},"Example test structure:",{"type":42,"tag":756,"props":1538,"children":1542},{"className":1539,"code":1540,"language":1541,"meta":761,"style":761},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { describe, it, expect, vi } from 'vitest';\nimport { myFunction } from '.\u002Fmy-module';\n\ndescribe('myFunction', () => {\n  it('should handle normal input', () => {\n    expect(myFunction('input')).toBe('expected');\n  });\n\n  it('should handle edge cases', () => {\n    expect(myFunction('')).toBe('default');\n  });\n});\n","typescript",[1543],{"type":42,"tag":86,"props":1544,"children":1545},{"__ignoreMap":761},[1546,1616,1657,1664,1707,1748,1821,1837,1844,1884,1946,1962],{"type":42,"tag":767,"props":1547,"children":1548},{"class":769,"line":770},[1549,1553,1557,1562,1566,1571,1575,1580,1584,1589,1593,1597,1602,1607,1612],{"type":42,"tag":767,"props":1550,"children":1551},{"style":1111},[1552],{"type":48,"value":1114},{"type":42,"tag":767,"props":1554,"children":1555},{"style":774},[1556],{"type":48,"value":807},{"type":42,"tag":767,"props":1558,"children":1559},{"style":1121},[1560],{"type":48,"value":1561}," describe",{"type":42,"tag":767,"props":1563,"children":1564},{"style":774},[1565],{"type":48,"value":1216},{"type":42,"tag":767,"props":1567,"children":1568},{"style":1121},[1569],{"type":48,"value":1570}," it",{"type":42,"tag":767,"props":1572,"children":1573},{"style":774},[1574],{"type":48,"value":1216},{"type":42,"tag":767,"props":1576,"children":1577},{"style":1121},[1578],{"type":48,"value":1579}," expect",{"type":42,"tag":767,"props":1581,"children":1582},{"style":774},[1583],{"type":48,"value":1216},{"type":42,"tag":767,"props":1585,"children":1586},{"style":1121},[1587],{"type":48,"value":1588}," vi",{"type":42,"tag":767,"props":1590,"children":1591},{"style":774},[1592],{"type":48,"value":1129},{"type":42,"tag":767,"props":1594,"children":1595},{"style":1111},[1596],{"type":48,"value":1134},{"type":42,"tag":767,"props":1598,"children":1599},{"style":774},[1600],{"type":48,"value":1601}," '",{"type":42,"tag":767,"props":1603,"children":1604},{"style":833},[1605],{"type":48,"value":1606},"vitest",{"type":42,"tag":767,"props":1608,"children":1609},{"style":774},[1610],{"type":48,"value":1611},"'",{"type":42,"tag":767,"props":1613,"children":1614},{"style":774},[1615],{"type":48,"value":1151},{"type":42,"tag":767,"props":1617,"children":1618},{"class":769,"line":780},[1619,1623,1627,1632,1636,1640,1644,1649,1653],{"type":42,"tag":767,"props":1620,"children":1621},{"style":1111},[1622],{"type":48,"value":1114},{"type":42,"tag":767,"props":1624,"children":1625},{"style":774},[1626],{"type":48,"value":807},{"type":42,"tag":767,"props":1628,"children":1629},{"style":1121},[1630],{"type":48,"value":1631}," myFunction",{"type":42,"tag":767,"props":1633,"children":1634},{"style":774},[1635],{"type":48,"value":1129},{"type":42,"tag":767,"props":1637,"children":1638},{"style":1111},[1639],{"type":48,"value":1134},{"type":42,"tag":767,"props":1641,"children":1642},{"style":774},[1643],{"type":48,"value":1601},{"type":42,"tag":767,"props":1645,"children":1646},{"style":833},[1647],{"type":48,"value":1648},".\u002Fmy-module",{"type":42,"tag":767,"props":1650,"children":1651},{"style":774},[1652],{"type":48,"value":1611},{"type":42,"tag":767,"props":1654,"children":1655},{"style":774},[1656],{"type":48,"value":1151},{"type":42,"tag":767,"props":1658,"children":1659},{"class":769,"line":26},[1660],{"type":42,"tag":767,"props":1661,"children":1662},{"emptyLinePlaceholder":37},[1663],{"type":48,"value":1159},{"type":42,"tag":767,"props":1665,"children":1666},{"class":769,"line":873},[1667,1672,1676,1680,1685,1689,1693,1698,1703],{"type":42,"tag":767,"props":1668,"children":1669},{"style":1175},[1670],{"type":48,"value":1671},"describe",{"type":42,"tag":767,"props":1673,"children":1674},{"style":1121},[1675],{"type":48,"value":1182},{"type":42,"tag":767,"props":1677,"children":1678},{"style":774},[1679],{"type":48,"value":1611},{"type":42,"tag":767,"props":1681,"children":1682},{"style":833},[1683],{"type":48,"value":1684},"myFunction",{"type":42,"tag":767,"props":1686,"children":1687},{"style":774},[1688],{"type":48,"value":1611},{"type":42,"tag":767,"props":1690,"children":1691},{"style":774},[1692],{"type":48,"value":1216},{"type":42,"tag":767,"props":1694,"children":1695},{"style":774},[1696],{"type":48,"value":1697}," ()",{"type":42,"tag":767,"props":1699,"children":1700},{"style":789},[1701],{"type":48,"value":1702}," =>",{"type":42,"tag":767,"props":1704,"children":1705},{"style":774},[1706],{"type":48,"value":870},{"type":42,"tag":767,"props":1708,"children":1709},{"class":769,"line":912},[1710,1715,1719,1723,1728,1732,1736,1740,1744],{"type":42,"tag":767,"props":1711,"children":1712},{"style":1175},[1713],{"type":48,"value":1714},"  it",{"type":42,"tag":767,"props":1716,"children":1717},{"style":1192},[1718],{"type":48,"value":1182},{"type":42,"tag":767,"props":1720,"children":1721},{"style":774},[1722],{"type":48,"value":1611},{"type":42,"tag":767,"props":1724,"children":1725},{"style":833},[1726],{"type":48,"value":1727},"should handle normal input",{"type":42,"tag":767,"props":1729,"children":1730},{"style":774},[1731],{"type":48,"value":1611},{"type":42,"tag":767,"props":1733,"children":1734},{"style":774},[1735],{"type":48,"value":1216},{"type":42,"tag":767,"props":1737,"children":1738},{"style":774},[1739],{"type":48,"value":1697},{"type":42,"tag":767,"props":1741,"children":1742},{"style":789},[1743],{"type":48,"value":1702},{"type":42,"tag":767,"props":1745,"children":1746},{"style":774},[1747],{"type":48,"value":870},{"type":42,"tag":767,"props":1749,"children":1750},{"class":769,"line":949},[1751,1756,1760,1764,1768,1772,1777,1781,1786,1791,1796,1800,1804,1809,1813,1817],{"type":42,"tag":767,"props":1752,"children":1753},{"style":1175},[1754],{"type":48,"value":1755},"    expect",{"type":42,"tag":767,"props":1757,"children":1758},{"style":1192},[1759],{"type":48,"value":1182},{"type":42,"tag":767,"props":1761,"children":1762},{"style":1175},[1763],{"type":48,"value":1684},{"type":42,"tag":767,"props":1765,"children":1766},{"style":1192},[1767],{"type":48,"value":1182},{"type":42,"tag":767,"props":1769,"children":1770},{"style":774},[1771],{"type":48,"value":1611},{"type":42,"tag":767,"props":1773,"children":1774},{"style":833},[1775],{"type":48,"value":1776},"input",{"type":42,"tag":767,"props":1778,"children":1779},{"style":774},[1780],{"type":48,"value":1611},{"type":42,"tag":767,"props":1782,"children":1783},{"style":1192},[1784],{"type":48,"value":1785},"))",{"type":42,"tag":767,"props":1787,"children":1788},{"style":774},[1789],{"type":48,"value":1790},".",{"type":42,"tag":767,"props":1792,"children":1793},{"style":1175},[1794],{"type":48,"value":1795},"toBe",{"type":42,"tag":767,"props":1797,"children":1798},{"style":1192},[1799],{"type":48,"value":1182},{"type":42,"tag":767,"props":1801,"children":1802},{"style":774},[1803],{"type":48,"value":1611},{"type":42,"tag":767,"props":1805,"children":1806},{"style":833},[1807],{"type":48,"value":1808},"expected",{"type":42,"tag":767,"props":1810,"children":1811},{"style":774},[1812],{"type":48,"value":1611},{"type":42,"tag":767,"props":1814,"children":1815},{"style":1192},[1816],{"type":48,"value":1234},{"type":42,"tag":767,"props":1818,"children":1819},{"style":774},[1820],{"type":48,"value":1151},{"type":42,"tag":767,"props":1822,"children":1823},{"class":769,"line":986},[1824,1829,1833],{"type":42,"tag":767,"props":1825,"children":1826},{"style":774},[1827],{"type":48,"value":1828},"  }",{"type":42,"tag":767,"props":1830,"children":1831},{"style":1192},[1832],{"type":48,"value":1234},{"type":42,"tag":767,"props":1834,"children":1835},{"style":774},[1836],{"type":48,"value":1151},{"type":42,"tag":767,"props":1838,"children":1839},{"class":769,"line":1019},[1840],{"type":42,"tag":767,"props":1841,"children":1842},{"emptyLinePlaceholder":37},[1843],{"type":48,"value":1159},{"type":42,"tag":767,"props":1845,"children":1846},{"class":769,"line":1028},[1847,1851,1855,1859,1864,1868,1872,1876,1880],{"type":42,"tag":767,"props":1848,"children":1849},{"style":1175},[1850],{"type":48,"value":1714},{"type":42,"tag":767,"props":1852,"children":1853},{"style":1192},[1854],{"type":48,"value":1182},{"type":42,"tag":767,"props":1856,"children":1857},{"style":774},[1858],{"type":48,"value":1611},{"type":42,"tag":767,"props":1860,"children":1861},{"style":833},[1862],{"type":48,"value":1863},"should handle edge cases",{"type":42,"tag":767,"props":1865,"children":1866},{"style":774},[1867],{"type":48,"value":1611},{"type":42,"tag":767,"props":1869,"children":1870},{"style":774},[1871],{"type":48,"value":1216},{"type":42,"tag":767,"props":1873,"children":1874},{"style":774},[1875],{"type":48,"value":1697},{"type":42,"tag":767,"props":1877,"children":1878},{"style":789},[1879],{"type":48,"value":1702},{"type":42,"tag":767,"props":1881,"children":1882},{"style":774},[1883],{"type":48,"value":870},{"type":42,"tag":767,"props":1885,"children":1887},{"class":769,"line":1886},10,[1888,1892,1896,1900,1904,1909,1913,1917,1921,1925,1929,1934,1938,1942],{"type":42,"tag":767,"props":1889,"children":1890},{"style":1175},[1891],{"type":48,"value":1755},{"type":42,"tag":767,"props":1893,"children":1894},{"style":1192},[1895],{"type":48,"value":1182},{"type":42,"tag":767,"props":1897,"children":1898},{"style":1175},[1899],{"type":48,"value":1684},{"type":42,"tag":767,"props":1901,"children":1902},{"style":1192},[1903],{"type":48,"value":1182},{"type":42,"tag":767,"props":1905,"children":1906},{"style":774},[1907],{"type":48,"value":1908},"''",{"type":42,"tag":767,"props":1910,"children":1911},{"style":1192},[1912],{"type":48,"value":1785},{"type":42,"tag":767,"props":1914,"children":1915},{"style":774},[1916],{"type":48,"value":1790},{"type":42,"tag":767,"props":1918,"children":1919},{"style":1175},[1920],{"type":48,"value":1795},{"type":42,"tag":767,"props":1922,"children":1923},{"style":1192},[1924],{"type":48,"value":1182},{"type":42,"tag":767,"props":1926,"children":1927},{"style":774},[1928],{"type":48,"value":1611},{"type":42,"tag":767,"props":1930,"children":1931},{"style":833},[1932],{"type":48,"value":1933},"default",{"type":42,"tag":767,"props":1935,"children":1936},{"style":774},[1937],{"type":48,"value":1611},{"type":42,"tag":767,"props":1939,"children":1940},{"style":1192},[1941],{"type":48,"value":1234},{"type":42,"tag":767,"props":1943,"children":1944},{"style":774},[1945],{"type":48,"value":1151},{"type":42,"tag":767,"props":1947,"children":1949},{"class":769,"line":1948},11,[1950,1954,1958],{"type":42,"tag":767,"props":1951,"children":1952},{"style":774},[1953],{"type":48,"value":1828},{"type":42,"tag":767,"props":1955,"children":1956},{"style":1192},[1957],{"type":48,"value":1234},{"type":42,"tag":767,"props":1959,"children":1960},{"style":774},[1961],{"type":48,"value":1151},{"type":42,"tag":767,"props":1963,"children":1965},{"class":769,"line":1964},12,[1966,1970,1974],{"type":42,"tag":767,"props":1967,"children":1968},{"style":774},[1969],{"type":48,"value":1229},{"type":42,"tag":767,"props":1971,"children":1972},{"style":1121},[1973],{"type":48,"value":1234},{"type":42,"tag":767,"props":1975,"children":1976},{"style":774},[1977],{"type":48,"value":1151},{"type":42,"tag":124,"props":1979,"children":1981},{"id":1980},"e2e-tests-for-user-facing-changes",[1982],{"type":48,"value":1983},"E2E Tests for User-Facing Changes",{"type":42,"tag":51,"props":1985,"children":1986},{},[1987],{"type":48,"value":1988},"If you modify:",{"type":42,"tag":72,"props":1990,"children":1991},{},[1992,2019,2024,2029],{"type":42,"tag":76,"props":1993,"children":1994},{},[1995,1997,2003,2005,2011,2012,2018],{"type":48,"value":1996},"Dispatch hooks (",{"type":42,"tag":86,"props":1998,"children":2000},{"className":1999},[],[2001],{"type":48,"value":2002},"onAppMention",{"type":48,"value":2004},", ",{"type":42,"tag":86,"props":2006,"children":2008},{"className":2007},[],[2009],{"type":48,"value":2010},"onDirectMessage",{"type":48,"value":2004},{"type":42,"tag":86,"props":2013,"children":2015},{"className":2014},[],[2016],{"type":48,"value":2017},"onInteraction",{"type":48,"value":1234},{"type":42,"tag":76,"props":2020,"children":2021},{},[2022],{"type":48,"value":2023},"Custom channel event handlers",{"type":42,"tag":76,"props":2025,"children":2026},{},[2027],{"type":48,"value":2028},"Tools the agent calls in response to Slack messages",{"type":42,"tag":76,"props":2030,"children":2031},{},[2032],{"type":48,"value":2033},"Delivery behavior (what gets posted to Slack)",{"type":42,"tag":51,"props":2035,"children":2036},{},[2037],{"type":48,"value":2038},"You MUST add or update tests that verify the full flow. Remember: the Slack surface itself cannot be exercised locally (see Gotchas), so E2E coverage means unit\u002Fintegration tests around your handlers plus a post-deploy smoke test.",{"type":42,"tag":636,"props":2040,"children":2041},{},[],{"type":42,"tag":104,"props":2043,"children":2045},{"id":2044},"bot-setup-patterns-critical",[2046],{"type":48,"value":2047},"Bot Setup Patterns (CRITICAL)",{"type":42,"tag":124,"props":2049,"children":2051},{"id":2050},"slack-channel-agentchannelsslackts",[2052,2054,2059],{"type":48,"value":2053},"Slack Channel (",{"type":42,"tag":86,"props":2055,"children":2057},{"className":2056},[],[2058],{"type":48,"value":320},{"type":48,"value":1234},{"type":42,"tag":51,"props":2061,"children":2062},{},[2063,2065,2070,2072,2081],{"type":48,"value":2064},"The Slack channel is a single file. Its filename registers the ",{"type":42,"tag":86,"props":2066,"children":2068},{"className":2067},[],[2069],{"type":48,"value":21},{"type":48,"value":2071}," channel, served at ",{"type":42,"tag":57,"props":2073,"children":2074},{},[2075],{"type":42,"tag":86,"props":2076,"children":2078},{"className":2077},[],[2079],{"type":48,"value":2080},"\u002Feve\u002Fv1\u002Fslack",{"type":48,"value":2082}," — this is the canonical trigger path everywhere in this skill.",{"type":42,"tag":756,"props":2084,"children":2086},{"className":1090,"code":2085,"language":1092,"meta":761,"style":761},"\u002F\u002F agent\u002Fchannels\u002Fslack.ts\nimport { connectSlackCredentials } from \"@vercel\u002Fconnect\u002Feve\";\nimport { slackChannel } from \"eve\u002Fchannels\u002Fslack\";\n\nexport default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n});\n",[2087],{"type":42,"tag":86,"props":2088,"children":2089},{"__ignoreMap":761},[2090,2098,2139,2179,2186,2209,2260],{"type":42,"tag":767,"props":2091,"children":2092},{"class":769,"line":770},[2093],{"type":42,"tag":767,"props":2094,"children":2095},{"style":1102},[2096],{"type":48,"value":2097},"\u002F\u002F agent\u002Fchannels\u002Fslack.ts\n",{"type":42,"tag":767,"props":2099,"children":2100},{"class":769,"line":780},[2101,2105,2109,2114,2118,2122,2126,2131,2135],{"type":42,"tag":767,"props":2102,"children":2103},{"style":1111},[2104],{"type":48,"value":1114},{"type":42,"tag":767,"props":2106,"children":2107},{"style":774},[2108],{"type":48,"value":807},{"type":42,"tag":767,"props":2110,"children":2111},{"style":1121},[2112],{"type":48,"value":2113}," connectSlackCredentials",{"type":42,"tag":767,"props":2115,"children":2116},{"style":774},[2117],{"type":48,"value":1129},{"type":42,"tag":767,"props":2119,"children":2120},{"style":1111},[2121],{"type":48,"value":1134},{"type":42,"tag":767,"props":2123,"children":2124},{"style":774},[2125],{"type":48,"value":812},{"type":42,"tag":767,"props":2127,"children":2128},{"style":833},[2129],{"type":48,"value":2130},"@vercel\u002Fconnect\u002Feve",{"type":42,"tag":767,"props":2132,"children":2133},{"style":774},[2134],{"type":48,"value":797},{"type":42,"tag":767,"props":2136,"children":2137},{"style":774},[2138],{"type":48,"value":1151},{"type":42,"tag":767,"props":2140,"children":2141},{"class":769,"line":26},[2142,2146,2150,2155,2159,2163,2167,2171,2175],{"type":42,"tag":767,"props":2143,"children":2144},{"style":1111},[2145],{"type":48,"value":1114},{"type":42,"tag":767,"props":2147,"children":2148},{"style":774},[2149],{"type":48,"value":807},{"type":42,"tag":767,"props":2151,"children":2152},{"style":1121},[2153],{"type":48,"value":2154}," slackChannel",{"type":42,"tag":767,"props":2156,"children":2157},{"style":774},[2158],{"type":48,"value":1129},{"type":42,"tag":767,"props":2160,"children":2161},{"style":1111},[2162],{"type":48,"value":1134},{"type":42,"tag":767,"props":2164,"children":2165},{"style":774},[2166],{"type":48,"value":812},{"type":42,"tag":767,"props":2168,"children":2169},{"style":833},[2170],{"type":48,"value":684},{"type":42,"tag":767,"props":2172,"children":2173},{"style":774},[2174],{"type":48,"value":797},{"type":42,"tag":767,"props":2176,"children":2177},{"style":774},[2178],{"type":48,"value":1151},{"type":42,"tag":767,"props":2180,"children":2181},{"class":769,"line":873},[2182],{"type":42,"tag":767,"props":2183,"children":2184},{"emptyLinePlaceholder":37},[2185],{"type":48,"value":1159},{"type":42,"tag":767,"props":2187,"children":2188},{"class":769,"line":912},[2189,2193,2197,2201,2205],{"type":42,"tag":767,"props":2190,"children":2191},{"style":1111},[2192],{"type":48,"value":1167},{"type":42,"tag":767,"props":2194,"children":2195},{"style":1111},[2196],{"type":48,"value":1172},{"type":42,"tag":767,"props":2198,"children":2199},{"style":1175},[2200],{"type":48,"value":2154},{"type":42,"tag":767,"props":2202,"children":2203},{"style":1121},[2204],{"type":48,"value":1182},{"type":42,"tag":767,"props":2206,"children":2207},{"style":774},[2208],{"type":48,"value":777},{"type":42,"tag":767,"props":2210,"children":2211},{"class":769,"line":949},[2212,2217,2221,2225,2230,2234,2239,2243,2247,2252,2256],{"type":42,"tag":767,"props":2213,"children":2214},{"style":1192},[2215],{"type":48,"value":2216},"  credentials",{"type":42,"tag":767,"props":2218,"children":2219},{"style":774},[2220],{"type":48,"value":802},{"type":42,"tag":767,"props":2222,"children":2223},{"style":1175},[2224],{"type":48,"value":2113},{"type":42,"tag":767,"props":2226,"children":2227},{"style":1121},[2228],{"type":48,"value":2229},"(process",{"type":42,"tag":767,"props":2231,"children":2232},{"style":774},[2233],{"type":48,"value":1790},{"type":42,"tag":767,"props":2235,"children":2236},{"style":1121},[2237],{"type":48,"value":2238},"env",{"type":42,"tag":767,"props":2240,"children":2241},{"style":774},[2242],{"type":48,"value":1790},{"type":42,"tag":767,"props":2244,"children":2245},{"style":1121},[2246],{"type":48,"value":336},{"type":42,"tag":767,"props":2248,"children":2249},{"style":774},[2250],{"type":48,"value":2251},"!",{"type":42,"tag":767,"props":2253,"children":2254},{"style":1121},[2255],{"type":48,"value":1234},{"type":42,"tag":767,"props":2257,"children":2258},{"style":774},[2259],{"type":48,"value":909},{"type":42,"tag":767,"props":2261,"children":2262},{"class":769,"line":986},[2263,2267,2271],{"type":42,"tag":767,"props":2264,"children":2265},{"style":774},[2266],{"type":48,"value":1229},{"type":42,"tag":767,"props":2268,"children":2269},{"style":1121},[2270],{"type":48,"value":1234},{"type":42,"tag":767,"props":2272,"children":2273},{"style":774},[2274],{"type":48,"value":1151},{"type":42,"tag":51,"props":2276,"children":2277},{},[2278,2284,2286,2292],{"type":42,"tag":86,"props":2279,"children":2281},{"className":2280},[],[2282],{"type":48,"value":2283},"connectSlackCredentials(connectorUid)",{"type":48,"value":2285}," returns ",{"type":42,"tag":86,"props":2287,"children":2289},{"className":2288},[],[2290],{"type":48,"value":2291},"{ botToken, webhookVerifier }",{"type":48,"value":802},{"type":42,"tag":72,"props":2294,"children":2295},{},[2296,2306],{"type":42,"tag":76,"props":2297,"children":2298},{},[2299,2304],{"type":42,"tag":57,"props":2300,"children":2301},{},[2302],{"type":48,"value":2303},"botToken",{"type":48,"value":2305}," — resolved at runtime via Vercel Connect as a short-lived, app-scoped token; Connect handles rotation and multi-workspace tenancy",{"type":42,"tag":76,"props":2307,"children":2308},{},[2309,2314],{"type":42,"tag":57,"props":2310,"children":2311},{},[2312],{"type":48,"value":2313},"webhookVerifier",{"type":48,"value":2315}," — confirms each forwarded event genuinely came from Connect (replaces Slack's native signature check)",{"type":42,"tag":51,"props":2317,"children":2318},{},[2319,2321,2339,2341,2346,2348,2354],{"type":48,"value":2320},"There is ",{"type":42,"tag":57,"props":2322,"children":2323},{},[2324,2326,2332,2333],{"type":48,"value":2325},"no ",{"type":42,"tag":86,"props":2327,"children":2329},{"className":2328},[],[2330],{"type":48,"value":2331},"SLACK_BOT_TOKEN",{"type":48,"value":289},{"type":42,"tag":86,"props":2334,"children":2336},{"className":2335},[],[2337],{"type":48,"value":2338},"SLACK_SIGNING_SECRET",{"type":48,"value":2340}," in this stack. The only Slack env var is ",{"type":42,"tag":86,"props":2342,"children":2344},{"className":2343},[],[2345],{"type":48,"value":336},{"type":48,"value":2347}," (the connector UID, e.g. ",{"type":42,"tag":86,"props":2349,"children":2351},{"className":2350},[],[2352],{"type":48,"value":2353},"slack\u002Fmy-agent",{"type":48,"value":2355},").",{"type":42,"tag":124,"props":2357,"children":2359},{"id":2358},"vercel-connect-setup",[2360],{"type":48,"value":2361},"Vercel Connect Setup",{"type":42,"tag":51,"props":2363,"children":2364},{},[2365],{"type":48,"value":2366},"Create a Slack connector and point its trigger at eve's Slack route:",{"type":42,"tag":756,"props":2368,"children":2370},{"className":1272,"code":2369,"language":1274,"meta":761,"style":761},"npm install -g vercel@latest\n\n# Create the connector with event forwarding enabled\nvercel connect create slack --triggers\n\n# Attach the project as a trigger destination on eve's route\n# (the default trigger path is \u002Fslack — set it explicitly):\nvercel connect attach \u003Cuid> --triggers --trigger-path \u002Feve\u002Fv1\u002Fslack --yes\n",[2371],{"type":42,"tag":86,"props":2372,"children":2373},{"__ignoreMap":761},[2374,2397,2404,2412,2439,2446,2454,2462],{"type":42,"tag":767,"props":2375,"children":2376},{"class":769,"line":770},[2377,2382,2387,2392],{"type":42,"tag":767,"props":2378,"children":2379},{"style":815},[2380],{"type":48,"value":2381},"npm",{"type":42,"tag":767,"props":2383,"children":2384},{"style":833},[2385],{"type":48,"value":2386}," install",{"type":42,"tag":767,"props":2388,"children":2389},{"style":833},[2390],{"type":48,"value":2391}," -g",{"type":42,"tag":767,"props":2393,"children":2394},{"style":833},[2395],{"type":48,"value":2396}," vercel@latest\n",{"type":42,"tag":767,"props":2398,"children":2399},{"class":769,"line":780},[2400],{"type":42,"tag":767,"props":2401,"children":2402},{"emptyLinePlaceholder":37},[2403],{"type":48,"value":1159},{"type":42,"tag":767,"props":2405,"children":2406},{"class":769,"line":26},[2407],{"type":42,"tag":767,"props":2408,"children":2409},{"style":1102},[2410],{"type":48,"value":2411},"# Create the connector with event forwarding enabled\n",{"type":42,"tag":767,"props":2413,"children":2414},{"class":769,"line":873},[2415,2419,2424,2429,2434],{"type":42,"tag":767,"props":2416,"children":2417},{"style":815},[2418],{"type":48,"value":14},{"type":42,"tag":767,"props":2420,"children":2421},{"style":833},[2422],{"type":48,"value":2423}," connect",{"type":42,"tag":767,"props":2425,"children":2426},{"style":833},[2427],{"type":48,"value":2428}," create",{"type":42,"tag":767,"props":2430,"children":2431},{"style":833},[2432],{"type":48,"value":2433}," slack",{"type":42,"tag":767,"props":2435,"children":2436},{"style":833},[2437],{"type":48,"value":2438}," --triggers\n",{"type":42,"tag":767,"props":2440,"children":2441},{"class":769,"line":912},[2442],{"type":42,"tag":767,"props":2443,"children":2444},{"emptyLinePlaceholder":37},[2445],{"type":48,"value":1159},{"type":42,"tag":767,"props":2447,"children":2448},{"class":769,"line":949},[2449],{"type":42,"tag":767,"props":2450,"children":2451},{"style":1102},[2452],{"type":48,"value":2453},"# Attach the project as a trigger destination on eve's route\n",{"type":42,"tag":767,"props":2455,"children":2456},{"class":769,"line":986},[2457],{"type":42,"tag":767,"props":2458,"children":2459},{"style":1102},[2460],{"type":48,"value":2461},"# (the default trigger path is \u002Fslack — set it explicitly):\n",{"type":42,"tag":767,"props":2463,"children":2464},{"class":769,"line":1019},[2465,2469,2473,2478,2483,2488,2493,2498,2503,2508,2513],{"type":42,"tag":767,"props":2466,"children":2467},{"style":815},[2468],{"type":48,"value":14},{"type":42,"tag":767,"props":2470,"children":2471},{"style":833},[2472],{"type":48,"value":2423},{"type":42,"tag":767,"props":2474,"children":2475},{"style":833},[2476],{"type":48,"value":2477}," attach",{"type":42,"tag":767,"props":2479,"children":2480},{"style":774},[2481],{"type":48,"value":2482}," \u003C",{"type":42,"tag":767,"props":2484,"children":2485},{"style":833},[2486],{"type":48,"value":2487},"ui",{"type":42,"tag":767,"props":2489,"children":2490},{"style":1121},[2491],{"type":48,"value":2492},"d",{"type":42,"tag":767,"props":2494,"children":2495},{"style":774},[2496],{"type":48,"value":2497},">",{"type":42,"tag":767,"props":2499,"children":2500},{"style":833},[2501],{"type":48,"value":2502}," --triggers",{"type":42,"tag":767,"props":2504,"children":2505},{"style":833},[2506],{"type":48,"value":2507}," --trigger-path",{"type":42,"tag":767,"props":2509,"children":2510},{"style":833},[2511],{"type":48,"value":2512}," \u002Feve\u002Fv1\u002Fslack",{"type":42,"tag":767,"props":2514,"children":2515},{"style":833},[2516],{"type":48,"value":2517}," --yes\n",{"type":42,"tag":51,"props":2519,"children":2520},{},[2521,2532,2534,2540,2542,2548],{"type":42,"tag":57,"props":2522,"children":2523},{},[2524,2530],{"type":42,"tag":86,"props":2525,"children":2527},{"className":2526},[],[2528],{"type":48,"value":2529},"--triggers",{"type":48,"value":2531}," is required.",{"type":48,"value":2533}," Without it, Slack Event Subscriptions are never forwarded and ",{"type":42,"tag":86,"props":2535,"children":2537},{"className":2536},[],[2538],{"type":48,"value":2539},"app_mention",{"type":48,"value":2541}," \u002F ",{"type":42,"tag":86,"props":2543,"children":2545},{"className":2544},[],[2546],{"type":48,"value":2547},"message.im",{"type":48,"value":2549}," events simply never arrive — the deployment will look healthy but the bot will never respond.",{"type":42,"tag":51,"props":2551,"children":2552},{},[2553,2555,2561,2563,2568],{"type":48,"value":2554},"You can also add the channel with ",{"type":42,"tag":86,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":48,"value":2560},"eve channels add slack",{"type":48,"value":2562},", which scaffolds ",{"type":42,"tag":86,"props":2564,"children":2566},{"className":2565},[],[2567],{"type":48,"value":320},{"type":48,"value":2569}," for you.",{"type":42,"tag":124,"props":2571,"children":2572},{"id":216},[2573],{"type":48,"value":2574},"Deploy",{"type":42,"tag":756,"props":2576,"children":2578},{"className":1272,"code":2577,"language":1274,"meta":761,"style":761},"eve deploy\n# wraps: vercel deploy --prod\n",[2579],{"type":42,"tag":86,"props":2580,"children":2581},{"__ignoreMap":761},[2582,2594],{"type":42,"tag":767,"props":2583,"children":2584},{"class":769,"line":770},[2585,2589],{"type":42,"tag":767,"props":2586,"children":2587},{"style":815},[2588],{"type":48,"value":61},{"type":42,"tag":767,"props":2590,"children":2591},{"style":833},[2592],{"type":48,"value":2593}," deploy\n",{"type":42,"tag":767,"props":2595,"children":2596},{"class":769,"line":780},[2597],{"type":42,"tag":767,"props":2598,"children":2599},{"style":1102},[2600],{"type":48,"value":2601},"# wraps: vercel deploy --prod\n",{"type":42,"tag":51,"props":2603,"children":2604},{},[2605],{"type":48,"value":2606},"Then invite the bot to a channel and @mention it. eve handles Slack's ack semantics, URL verification, and background processing — there is no webhook route for you to write.",{"type":42,"tag":636,"props":2608,"children":2609},{},[],{"type":42,"tag":104,"props":2611,"children":2613},{"id":2612},"event-handling-patterns",[2614],{"type":48,"value":2615},"Event Handling Patterns",{"type":42,"tag":124,"props":2617,"children":2619},{"id":2618},"dispatch-hooks-inbound",[2620],{"type":48,"value":2621},"Dispatch Hooks (Inbound)",{"type":42,"tag":51,"props":2623,"children":2624},{},[2625,2627,2633,2635,2641,2643,2649],{"type":48,"value":2626},"The Slack channel decides which inbound events start or continue a session via dispatch hooks. Each hook returns ",{"type":42,"tag":86,"props":2628,"children":2630},{"className":2629},[],[2631],{"type":48,"value":2632},"{ auth }",{"type":48,"value":2634}," to dispatch, ",{"type":42,"tag":86,"props":2636,"children":2638},{"className":2637},[],[2639],{"type":48,"value":2640},"null",{"type":48,"value":2642}," to drop the event, or ",{"type":42,"tag":86,"props":2644,"children":2646},{"className":2645},[],[2647],{"type":48,"value":2648},"{ auth, context }",{"type":48,"value":2650}," to inject background context into the session:",{"type":42,"tag":756,"props":2652,"children":2654},{"className":1090,"code":2653,"language":1092,"meta":761,"style":761},"export default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n\n  \u002F\u002F app_mention — default derives workspace-scoped auth and posts \"Thinking…\"\n  async onAppMention(ctx, message) {\n    if (isFromBlockedChannel(message)) return null; \u002F\u002F drop\n    return { auth: ctx.defaultAuth };\n  },\n\n  \u002F\u002F message.im — requires the im:history scope; bot messages\u002Fedits are pre-filtered\n  async onDirectMessage(ctx, message) {\n    return { auth: ctx.defaultAuth };\n  },\n\n  \u002F\u002F block_actions not consumed by HITL prompts\n  async onInteraction(action, ctx) {\n    return { auth: ctx.defaultAuth };\n  },\n});\n",[2655],{"type":42,"tag":86,"props":2656,"children":2657},{"__ignoreMap":761},[2658,2681,2728,2735,2743,2783,2829,2869,2877,2884,2892,2928,2963,2971,2979,2988,3026,3062,3069],{"type":42,"tag":767,"props":2659,"children":2660},{"class":769,"line":770},[2661,2665,2669,2673,2677],{"type":42,"tag":767,"props":2662,"children":2663},{"style":1111},[2664],{"type":48,"value":1167},{"type":42,"tag":767,"props":2666,"children":2667},{"style":1111},[2668],{"type":48,"value":1172},{"type":42,"tag":767,"props":2670,"children":2671},{"style":1175},[2672],{"type":48,"value":2154},{"type":42,"tag":767,"props":2674,"children":2675},{"style":1121},[2676],{"type":48,"value":1182},{"type":42,"tag":767,"props":2678,"children":2679},{"style":774},[2680],{"type":48,"value":777},{"type":42,"tag":767,"props":2682,"children":2683},{"class":769,"line":780},[2684,2688,2692,2696,2700,2704,2708,2712,2716,2720,2724],{"type":42,"tag":767,"props":2685,"children":2686},{"style":1192},[2687],{"type":48,"value":2216},{"type":42,"tag":767,"props":2689,"children":2690},{"style":774},[2691],{"type":48,"value":802},{"type":42,"tag":767,"props":2693,"children":2694},{"style":1175},[2695],{"type":48,"value":2113},{"type":42,"tag":767,"props":2697,"children":2698},{"style":1121},[2699],{"type":48,"value":2229},{"type":42,"tag":767,"props":2701,"children":2702},{"style":774},[2703],{"type":48,"value":1790},{"type":42,"tag":767,"props":2705,"children":2706},{"style":1121},[2707],{"type":48,"value":2238},{"type":42,"tag":767,"props":2709,"children":2710},{"style":774},[2711],{"type":48,"value":1790},{"type":42,"tag":767,"props":2713,"children":2714},{"style":1121},[2715],{"type":48,"value":336},{"type":42,"tag":767,"props":2717,"children":2718},{"style":774},[2719],{"type":48,"value":2251},{"type":42,"tag":767,"props":2721,"children":2722},{"style":1121},[2723],{"type":48,"value":1234},{"type":42,"tag":767,"props":2725,"children":2726},{"style":774},[2727],{"type":48,"value":909},{"type":42,"tag":767,"props":2729,"children":2730},{"class":769,"line":26},[2731],{"type":42,"tag":767,"props":2732,"children":2733},{"emptyLinePlaceholder":37},[2734],{"type":48,"value":1159},{"type":42,"tag":767,"props":2736,"children":2737},{"class":769,"line":873},[2738],{"type":42,"tag":767,"props":2739,"children":2740},{"style":1102},[2741],{"type":48,"value":2742},"  \u002F\u002F app_mention — default derives workspace-scoped auth and posts \"Thinking…\"\n",{"type":42,"tag":767,"props":2744,"children":2745},{"class":769,"line":912},[2746,2751,2756,2760,2766,2770,2775,2779],{"type":42,"tag":767,"props":2747,"children":2748},{"style":789},[2749],{"type":48,"value":2750},"  async",{"type":42,"tag":767,"props":2752,"children":2753},{"style":1192},[2754],{"type":48,"value":2755}," onAppMention",{"type":42,"tag":767,"props":2757,"children":2758},{"style":774},[2759],{"type":48,"value":1182},{"type":42,"tag":767,"props":2761,"children":2763},{"style":2762},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[2764],{"type":48,"value":2765},"ctx",{"type":42,"tag":767,"props":2767,"children":2768},{"style":774},[2769],{"type":48,"value":1216},{"type":42,"tag":767,"props":2771,"children":2772},{"style":2762},[2773],{"type":48,"value":2774}," message",{"type":42,"tag":767,"props":2776,"children":2777},{"style":774},[2778],{"type":48,"value":1234},{"type":42,"tag":767,"props":2780,"children":2781},{"style":774},[2782],{"type":48,"value":870},{"type":42,"tag":767,"props":2784,"children":2785},{"class":769,"line":949},[2786,2791,2795,2800,2804,2809,2814,2819,2824],{"type":42,"tag":767,"props":2787,"children":2788},{"style":1111},[2789],{"type":48,"value":2790},"    if",{"type":42,"tag":767,"props":2792,"children":2793},{"style":1192},[2794],{"type":48,"value":84},{"type":42,"tag":767,"props":2796,"children":2797},{"style":1175},[2798],{"type":48,"value":2799},"isFromBlockedChannel",{"type":42,"tag":767,"props":2801,"children":2802},{"style":1192},[2803],{"type":48,"value":1182},{"type":42,"tag":767,"props":2805,"children":2806},{"style":1121},[2807],{"type":48,"value":2808},"message",{"type":42,"tag":767,"props":2810,"children":2811},{"style":1192},[2812],{"type":48,"value":2813},")) ",{"type":42,"tag":767,"props":2815,"children":2816},{"style":1111},[2817],{"type":48,"value":2818},"return",{"type":42,"tag":767,"props":2820,"children":2821},{"style":774},[2822],{"type":48,"value":2823}," null;",{"type":42,"tag":767,"props":2825,"children":2826},{"style":1102},[2827],{"type":48,"value":2828}," \u002F\u002F drop\n",{"type":42,"tag":767,"props":2830,"children":2831},{"class":769,"line":986},[2832,2837,2841,2846,2850,2855,2859,2864],{"type":42,"tag":767,"props":2833,"children":2834},{"style":1111},[2835],{"type":48,"value":2836},"    return",{"type":42,"tag":767,"props":2838,"children":2839},{"style":774},[2840],{"type":48,"value":807},{"type":42,"tag":767,"props":2842,"children":2843},{"style":1192},[2844],{"type":48,"value":2845}," auth",{"type":42,"tag":767,"props":2847,"children":2848},{"style":774},[2849],{"type":48,"value":802},{"type":42,"tag":767,"props":2851,"children":2852},{"style":1121},[2853],{"type":48,"value":2854}," ctx",{"type":42,"tag":767,"props":2856,"children":2857},{"style":774},[2858],{"type":48,"value":1790},{"type":42,"tag":767,"props":2860,"children":2861},{"style":1121},[2862],{"type":48,"value":2863},"defaultAuth",{"type":42,"tag":767,"props":2865,"children":2866},{"style":774},[2867],{"type":48,"value":2868}," };\n",{"type":42,"tag":767,"props":2870,"children":2871},{"class":769,"line":1019},[2872],{"type":42,"tag":767,"props":2873,"children":2874},{"style":774},[2875],{"type":48,"value":2876},"  },\n",{"type":42,"tag":767,"props":2878,"children":2879},{"class":769,"line":1028},[2880],{"type":42,"tag":767,"props":2881,"children":2882},{"emptyLinePlaceholder":37},[2883],{"type":48,"value":1159},{"type":42,"tag":767,"props":2885,"children":2886},{"class":769,"line":1886},[2887],{"type":42,"tag":767,"props":2888,"children":2889},{"style":1102},[2890],{"type":48,"value":2891},"  \u002F\u002F message.im — requires the im:history scope; bot messages\u002Fedits are pre-filtered\n",{"type":42,"tag":767,"props":2893,"children":2894},{"class":769,"line":1948},[2895,2899,2904,2908,2912,2916,2920,2924],{"type":42,"tag":767,"props":2896,"children":2897},{"style":789},[2898],{"type":48,"value":2750},{"type":42,"tag":767,"props":2900,"children":2901},{"style":1192},[2902],{"type":48,"value":2903}," onDirectMessage",{"type":42,"tag":767,"props":2905,"children":2906},{"style":774},[2907],{"type":48,"value":1182},{"type":42,"tag":767,"props":2909,"children":2910},{"style":2762},[2911],{"type":48,"value":2765},{"type":42,"tag":767,"props":2913,"children":2914},{"style":774},[2915],{"type":48,"value":1216},{"type":42,"tag":767,"props":2917,"children":2918},{"style":2762},[2919],{"type":48,"value":2774},{"type":42,"tag":767,"props":2921,"children":2922},{"style":774},[2923],{"type":48,"value":1234},{"type":42,"tag":767,"props":2925,"children":2926},{"style":774},[2927],{"type":48,"value":870},{"type":42,"tag":767,"props":2929,"children":2930},{"class":769,"line":1964},[2931,2935,2939,2943,2947,2951,2955,2959],{"type":42,"tag":767,"props":2932,"children":2933},{"style":1111},[2934],{"type":48,"value":2836},{"type":42,"tag":767,"props":2936,"children":2937},{"style":774},[2938],{"type":48,"value":807},{"type":42,"tag":767,"props":2940,"children":2941},{"style":1192},[2942],{"type":48,"value":2845},{"type":42,"tag":767,"props":2944,"children":2945},{"style":774},[2946],{"type":48,"value":802},{"type":42,"tag":767,"props":2948,"children":2949},{"style":1121},[2950],{"type":48,"value":2854},{"type":42,"tag":767,"props":2952,"children":2953},{"style":774},[2954],{"type":48,"value":1790},{"type":42,"tag":767,"props":2956,"children":2957},{"style":1121},[2958],{"type":48,"value":2863},{"type":42,"tag":767,"props":2960,"children":2961},{"style":774},[2962],{"type":48,"value":2868},{"type":42,"tag":767,"props":2964,"children":2966},{"class":769,"line":2965},13,[2967],{"type":42,"tag":767,"props":2968,"children":2969},{"style":774},[2970],{"type":48,"value":2876},{"type":42,"tag":767,"props":2972,"children":2974},{"class":769,"line":2973},14,[2975],{"type":42,"tag":767,"props":2976,"children":2977},{"emptyLinePlaceholder":37},[2978],{"type":48,"value":1159},{"type":42,"tag":767,"props":2980,"children":2982},{"class":769,"line":2981},15,[2983],{"type":42,"tag":767,"props":2984,"children":2985},{"style":1102},[2986],{"type":48,"value":2987},"  \u002F\u002F block_actions not consumed by HITL prompts\n",{"type":42,"tag":767,"props":2989,"children":2991},{"class":769,"line":2990},16,[2992,2996,3001,3005,3010,3014,3018,3022],{"type":42,"tag":767,"props":2993,"children":2994},{"style":789},[2995],{"type":48,"value":2750},{"type":42,"tag":767,"props":2997,"children":2998},{"style":1192},[2999],{"type":48,"value":3000}," onInteraction",{"type":42,"tag":767,"props":3002,"children":3003},{"style":774},[3004],{"type":48,"value":1182},{"type":42,"tag":767,"props":3006,"children":3007},{"style":2762},[3008],{"type":48,"value":3009},"action",{"type":42,"tag":767,"props":3011,"children":3012},{"style":774},[3013],{"type":48,"value":1216},{"type":42,"tag":767,"props":3015,"children":3016},{"style":2762},[3017],{"type":48,"value":2854},{"type":42,"tag":767,"props":3019,"children":3020},{"style":774},[3021],{"type":48,"value":1234},{"type":42,"tag":767,"props":3023,"children":3024},{"style":774},[3025],{"type":48,"value":870},{"type":42,"tag":767,"props":3027,"children":3029},{"class":769,"line":3028},17,[3030,3034,3038,3042,3046,3050,3054,3058],{"type":42,"tag":767,"props":3031,"children":3032},{"style":1111},[3033],{"type":48,"value":2836},{"type":42,"tag":767,"props":3035,"children":3036},{"style":774},[3037],{"type":48,"value":807},{"type":42,"tag":767,"props":3039,"children":3040},{"style":1192},[3041],{"type":48,"value":2845},{"type":42,"tag":767,"props":3043,"children":3044},{"style":774},[3045],{"type":48,"value":802},{"type":42,"tag":767,"props":3047,"children":3048},{"style":1121},[3049],{"type":48,"value":2854},{"type":42,"tag":767,"props":3051,"children":3052},{"style":774},[3053],{"type":48,"value":1790},{"type":42,"tag":767,"props":3055,"children":3056},{"style":1121},[3057],{"type":48,"value":2863},{"type":42,"tag":767,"props":3059,"children":3060},{"style":774},[3061],{"type":48,"value":2868},{"type":42,"tag":767,"props":3063,"children":3064},{"class":769,"line":22},[3065],{"type":42,"tag":767,"props":3066,"children":3067},{"style":774},[3068],{"type":48,"value":2876},{"type":42,"tag":767,"props":3070,"children":3072},{"class":769,"line":3071},19,[3073,3077,3081],{"type":42,"tag":767,"props":3074,"children":3075},{"style":774},[3076],{"type":48,"value":1229},{"type":42,"tag":767,"props":3078,"children":3079},{"style":1121},[3080],{"type":48,"value":1234},{"type":42,"tag":767,"props":3082,"children":3083},{"style":774},[3084],{"type":48,"value":1151},{"type":42,"tag":51,"props":3086,"children":3087},{},[3088],{"type":48,"value":3089},"The triggering Slack user's id is attached to the model message automatically, preserving speaker attribution in multi-user threads.",{"type":42,"tag":124,"props":3091,"children":3093},{"id":3092},"custom-event-handlers-outbound-delivery",[3094],{"type":48,"value":3095},"Custom Event Handlers (Outbound Delivery)",{"type":42,"tag":51,"props":3097,"children":3098},{},[3099,3101,3107,3109,3115,3116,3122,3124,3130],{"type":48,"value":3100},"Override delivery per stream event with the ",{"type":42,"tag":86,"props":3102,"children":3104},{"className":3103},[],[3105],{"type":48,"value":3106},"events",{"type":48,"value":3108}," map. Handlers receive ",{"type":42,"tag":86,"props":3110,"children":3112},{"className":3111},[],[3113],{"type":48,"value":3114},"(eventData, channel, ctx)",{"type":48,"value":282},{"type":42,"tag":86,"props":3117,"children":3119},{"className":3118},[],[3120],{"type":48,"value":3121},"channel.thread",{"type":48,"value":3123}," and ",{"type":42,"tag":86,"props":3125,"children":3127},{"className":3126},[],[3128],{"type":48,"value":3129},"channel.slack",{"type":48,"value":3131}," handles:",{"type":42,"tag":756,"props":3133,"children":3135},{"className":1090,"code":3134,"language":1092,"meta":761,"style":761},"export default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n  events: {\n    \"message.completed\"(eventData, channel, ctx) {\n      if (eventData.finishReason === \"tool-calls\") return;\n      if (eventData.message) channel.thread.post(eventData.message);\n    },\n  },\n});\n",[3136],{"type":42,"tag":86,"props":3137,"children":3138},{"__ignoreMap":761},[3139,3162,3209,3225,3275,3331,3405,3413,3420],{"type":42,"tag":767,"props":3140,"children":3141},{"class":769,"line":770},[3142,3146,3150,3154,3158],{"type":42,"tag":767,"props":3143,"children":3144},{"style":1111},[3145],{"type":48,"value":1167},{"type":42,"tag":767,"props":3147,"children":3148},{"style":1111},[3149],{"type":48,"value":1172},{"type":42,"tag":767,"props":3151,"children":3152},{"style":1175},[3153],{"type":48,"value":2154},{"type":42,"tag":767,"props":3155,"children":3156},{"style":1121},[3157],{"type":48,"value":1182},{"type":42,"tag":767,"props":3159,"children":3160},{"style":774},[3161],{"type":48,"value":777},{"type":42,"tag":767,"props":3163,"children":3164},{"class":769,"line":780},[3165,3169,3173,3177,3181,3185,3189,3193,3197,3201,3205],{"type":42,"tag":767,"props":3166,"children":3167},{"style":1192},[3168],{"type":48,"value":2216},{"type":42,"tag":767,"props":3170,"children":3171},{"style":774},[3172],{"type":48,"value":802},{"type":42,"tag":767,"props":3174,"children":3175},{"style":1175},[3176],{"type":48,"value":2113},{"type":42,"tag":767,"props":3178,"children":3179},{"style":1121},[3180],{"type":48,"value":2229},{"type":42,"tag":767,"props":3182,"children":3183},{"style":774},[3184],{"type":48,"value":1790},{"type":42,"tag":767,"props":3186,"children":3187},{"style":1121},[3188],{"type":48,"value":2238},{"type":42,"tag":767,"props":3190,"children":3191},{"style":774},[3192],{"type":48,"value":1790},{"type":42,"tag":767,"props":3194,"children":3195},{"style":1121},[3196],{"type":48,"value":336},{"type":42,"tag":767,"props":3198,"children":3199},{"style":774},[3200],{"type":48,"value":2251},{"type":42,"tag":767,"props":3202,"children":3203},{"style":1121},[3204],{"type":48,"value":1234},{"type":42,"tag":767,"props":3206,"children":3207},{"style":774},[3208],{"type":48,"value":909},{"type":42,"tag":767,"props":3210,"children":3211},{"class":769,"line":26},[3212,3217,3221],{"type":42,"tag":767,"props":3213,"children":3214},{"style":1192},[3215],{"type":48,"value":3216},"  events",{"type":42,"tag":767,"props":3218,"children":3219},{"style":774},[3220],{"type":48,"value":802},{"type":42,"tag":767,"props":3222,"children":3223},{"style":774},[3224],{"type":48,"value":870},{"type":42,"tag":767,"props":3226,"children":3227},{"class":769,"line":873},[3228,3232,3237,3241,3245,3250,3254,3259,3263,3267,3271],{"type":42,"tag":767,"props":3229,"children":3230},{"style":774},[3231],{"type":48,"value":879},{"type":42,"tag":767,"props":3233,"children":3234},{"style":833},[3235],{"type":48,"value":3236},"message.completed",{"type":42,"tag":767,"props":3238,"children":3239},{"style":774},[3240],{"type":48,"value":797},{"type":42,"tag":767,"props":3242,"children":3243},{"style":774},[3244],{"type":48,"value":1182},{"type":42,"tag":767,"props":3246,"children":3247},{"style":2762},[3248],{"type":48,"value":3249},"eventData",{"type":42,"tag":767,"props":3251,"children":3252},{"style":774},[3253],{"type":48,"value":1216},{"type":42,"tag":767,"props":3255,"children":3256},{"style":2762},[3257],{"type":48,"value":3258}," channel",{"type":42,"tag":767,"props":3260,"children":3261},{"style":774},[3262],{"type":48,"value":1216},{"type":42,"tag":767,"props":3264,"children":3265},{"style":2762},[3266],{"type":48,"value":2854},{"type":42,"tag":767,"props":3268,"children":3269},{"style":774},[3270],{"type":48,"value":1234},{"type":42,"tag":767,"props":3272,"children":3273},{"style":774},[3274],{"type":48,"value":870},{"type":42,"tag":767,"props":3276,"children":3277},{"class":769,"line":912},[3278,3283,3287,3291,3295,3300,3305,3309,3314,3318,3323,3327],{"type":42,"tag":767,"props":3279,"children":3280},{"style":1111},[3281],{"type":48,"value":3282},"      if",{"type":42,"tag":767,"props":3284,"children":3285},{"style":1192},[3286],{"type":48,"value":84},{"type":42,"tag":767,"props":3288,"children":3289},{"style":1121},[3290],{"type":48,"value":3249},{"type":42,"tag":767,"props":3292,"children":3293},{"style":774},[3294],{"type":48,"value":1790},{"type":42,"tag":767,"props":3296,"children":3297},{"style":1121},[3298],{"type":48,"value":3299},"finishReason",{"type":42,"tag":767,"props":3301,"children":3302},{"style":774},[3303],{"type":48,"value":3304}," ===",{"type":42,"tag":767,"props":3306,"children":3307},{"style":774},[3308],{"type":48,"value":812},{"type":42,"tag":767,"props":3310,"children":3311},{"style":833},[3312],{"type":48,"value":3313},"tool-calls",{"type":42,"tag":767,"props":3315,"children":3316},{"style":774},[3317],{"type":48,"value":797},{"type":42,"tag":767,"props":3319,"children":3320},{"style":1192},[3321],{"type":48,"value":3322},") ",{"type":42,"tag":767,"props":3324,"children":3325},{"style":1111},[3326],{"type":48,"value":2818},{"type":42,"tag":767,"props":3328,"children":3329},{"style":774},[3330],{"type":48,"value":1151},{"type":42,"tag":767,"props":3332,"children":3333},{"class":769,"line":949},[3334,3338,3342,3346,3350,3354,3358,3363,3367,3372,3376,3381,3385,3389,3393,3397,3401],{"type":42,"tag":767,"props":3335,"children":3336},{"style":1111},[3337],{"type":48,"value":3282},{"type":42,"tag":767,"props":3339,"children":3340},{"style":1192},[3341],{"type":48,"value":84},{"type":42,"tag":767,"props":3343,"children":3344},{"style":1121},[3345],{"type":48,"value":3249},{"type":42,"tag":767,"props":3347,"children":3348},{"style":774},[3349],{"type":48,"value":1790},{"type":42,"tag":767,"props":3351,"children":3352},{"style":1121},[3353],{"type":48,"value":2808},{"type":42,"tag":767,"props":3355,"children":3356},{"style":1192},[3357],{"type":48,"value":3322},{"type":42,"tag":767,"props":3359,"children":3360},{"style":1121},[3361],{"type":48,"value":3362},"channel",{"type":42,"tag":767,"props":3364,"children":3365},{"style":774},[3366],{"type":48,"value":1790},{"type":42,"tag":767,"props":3368,"children":3369},{"style":1121},[3370],{"type":48,"value":3371},"thread",{"type":42,"tag":767,"props":3373,"children":3374},{"style":774},[3375],{"type":48,"value":1790},{"type":42,"tag":767,"props":3377,"children":3378},{"style":1175},[3379],{"type":48,"value":3380},"post",{"type":42,"tag":767,"props":3382,"children":3383},{"style":1192},[3384],{"type":48,"value":1182},{"type":42,"tag":767,"props":3386,"children":3387},{"style":1121},[3388],{"type":48,"value":3249},{"type":42,"tag":767,"props":3390,"children":3391},{"style":774},[3392],{"type":48,"value":1790},{"type":42,"tag":767,"props":3394,"children":3395},{"style":1121},[3396],{"type":48,"value":2808},{"type":42,"tag":767,"props":3398,"children":3399},{"style":1192},[3400],{"type":48,"value":1234},{"type":42,"tag":767,"props":3402,"children":3403},{"style":774},[3404],{"type":48,"value":1151},{"type":42,"tag":767,"props":3406,"children":3407},{"class":769,"line":986},[3408],{"type":42,"tag":767,"props":3409,"children":3410},{"style":774},[3411],{"type":48,"value":3412},"    },\n",{"type":42,"tag":767,"props":3414,"children":3415},{"class":769,"line":1019},[3416],{"type":42,"tag":767,"props":3417,"children":3418},{"style":774},[3419],{"type":48,"value":2876},{"type":42,"tag":767,"props":3421,"children":3422},{"class":769,"line":1028},[3423,3427,3431],{"type":42,"tag":767,"props":3424,"children":3425},{"style":774},[3426],{"type":48,"value":1229},{"type":42,"tag":767,"props":3428,"children":3429},{"style":1121},[3430],{"type":48,"value":1234},{"type":42,"tag":767,"props":3432,"children":3433},{"style":774},[3434],{"type":48,"value":1151},{"type":42,"tag":51,"props":3436,"children":3437},{},[3438,3440,3446,3447,3453,3454,3460,3461,3466,3467,3473,3475,3481,3482,3488],{"type":48,"value":3439},"Key stream events: ",{"type":42,"tag":86,"props":3441,"children":3443},{"className":3442},[],[3444],{"type":48,"value":3445},"session.started",{"type":48,"value":2004},{"type":42,"tag":86,"props":3448,"children":3450},{"className":3449},[],[3451],{"type":48,"value":3452},"actions.requested",{"type":48,"value":2004},{"type":42,"tag":86,"props":3455,"children":3457},{"className":3456},[],[3458],{"type":48,"value":3459},"action.result",{"type":48,"value":2004},{"type":42,"tag":86,"props":3462,"children":3464},{"className":3463},[],[3465],{"type":48,"value":3236},{"type":48,"value":2004},{"type":42,"tag":86,"props":3468,"children":3470},{"className":3469},[],[3471],{"type":48,"value":3472},"session.completed",{"type":48,"value":3474},"; incremental ",{"type":42,"tag":86,"props":3476,"children":3478},{"className":3477},[],[3479],{"type":48,"value":3480},"reasoning.appended",{"type":48,"value":2541},{"type":42,"tag":86,"props":3483,"children":3485},{"className":3484},[],[3486],{"type":48,"value":3487},"message.appended",{"type":48,"value":3489}," are optional.",{"type":42,"tag":124,"props":3491,"children":3493},{"id":3492},"thread-context",[3494],{"type":48,"value":3495},"Thread Context",{"type":42,"tag":51,"props":3497,"children":3498},{},[3499],{"type":48,"value":3500},"Give the agent prior thread messages when it's triggered mid-thread:",{"type":42,"tag":756,"props":3502,"children":3504},{"className":1090,"code":3503,"language":1092,"meta":761,"style":761},"export default slackChannel({\n  credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),\n  threadContext: { since: \"last-agent-reply\" },\n});\n",[3505],{"type":42,"tag":86,"props":3506,"children":3507},{"__ignoreMap":761},[3508,3531,3578,3620],{"type":42,"tag":767,"props":3509,"children":3510},{"class":769,"line":770},[3511,3515,3519,3523,3527],{"type":42,"tag":767,"props":3512,"children":3513},{"style":1111},[3514],{"type":48,"value":1167},{"type":42,"tag":767,"props":3516,"children":3517},{"style":1111},[3518],{"type":48,"value":1172},{"type":42,"tag":767,"props":3520,"children":3521},{"style":1175},[3522],{"type":48,"value":2154},{"type":42,"tag":767,"props":3524,"children":3525},{"style":1121},[3526],{"type":48,"value":1182},{"type":42,"tag":767,"props":3528,"children":3529},{"style":774},[3530],{"type":48,"value":777},{"type":42,"tag":767,"props":3532,"children":3533},{"class":769,"line":780},[3534,3538,3542,3546,3550,3554,3558,3562,3566,3570,3574],{"type":42,"tag":767,"props":3535,"children":3536},{"style":1192},[3537],{"type":48,"value":2216},{"type":42,"tag":767,"props":3539,"children":3540},{"style":774},[3541],{"type":48,"value":802},{"type":42,"tag":767,"props":3543,"children":3544},{"style":1175},[3545],{"type":48,"value":2113},{"type":42,"tag":767,"props":3547,"children":3548},{"style":1121},[3549],{"type":48,"value":2229},{"type":42,"tag":767,"props":3551,"children":3552},{"style":774},[3553],{"type":48,"value":1790},{"type":42,"tag":767,"props":3555,"children":3556},{"style":1121},[3557],{"type":48,"value":2238},{"type":42,"tag":767,"props":3559,"children":3560},{"style":774},[3561],{"type":48,"value":1790},{"type":42,"tag":767,"props":3563,"children":3564},{"style":1121},[3565],{"type":48,"value":336},{"type":42,"tag":767,"props":3567,"children":3568},{"style":774},[3569],{"type":48,"value":2251},{"type":42,"tag":767,"props":3571,"children":3572},{"style":1121},[3573],{"type":48,"value":1234},{"type":42,"tag":767,"props":3575,"children":3576},{"style":774},[3577],{"type":48,"value":909},{"type":42,"tag":767,"props":3579,"children":3580},{"class":769,"line":26},[3581,3586,3590,3594,3599,3603,3607,3612,3616],{"type":42,"tag":767,"props":3582,"children":3583},{"style":1192},[3584],{"type":48,"value":3585},"  threadContext",{"type":42,"tag":767,"props":3587,"children":3588},{"style":774},[3589],{"type":48,"value":802},{"type":42,"tag":767,"props":3591,"children":3592},{"style":774},[3593],{"type":48,"value":807},{"type":42,"tag":767,"props":3595,"children":3596},{"style":1192},[3597],{"type":48,"value":3598}," since",{"type":42,"tag":767,"props":3600,"children":3601},{"style":774},[3602],{"type":48,"value":802},{"type":42,"tag":767,"props":3604,"children":3605},{"style":774},[3606],{"type":48,"value":812},{"type":42,"tag":767,"props":3608,"children":3609},{"style":833},[3610],{"type":48,"value":3611},"last-agent-reply",{"type":42,"tag":767,"props":3613,"children":3614},{"style":774},[3615],{"type":48,"value":797},{"type":42,"tag":767,"props":3617,"children":3618},{"style":774},[3619],{"type":48,"value":845},{"type":42,"tag":767,"props":3621,"children":3622},{"class":769,"line":873},[3623,3627,3631],{"type":42,"tag":767,"props":3624,"children":3625},{"style":774},[3626],{"type":48,"value":1229},{"type":42,"tag":767,"props":3628,"children":3629},{"style":1121},[3630],{"type":48,"value":1234},{"type":42,"tag":767,"props":3632,"children":3633},{"style":774},[3634],{"type":48,"value":1151},{"type":42,"tag":51,"props":3636,"children":3637},{},[3638,3644],{"type":42,"tag":86,"props":3639,"children":3641},{"className":3640},[],[3642],{"type":48,"value":3643},"since",{"type":48,"value":3645}," options:",{"type":42,"tag":72,"props":3647,"children":3648},{},[3649,3660,3671],{"type":42,"tag":76,"props":3650,"children":3651},{},[3652,3658],{"type":42,"tag":86,"props":3653,"children":3655},{"className":3654},[],[3656],{"type":48,"value":3657},"\"thread-root\"",{"type":48,"value":3659}," — all prior messages (default when thread context is enabled)",{"type":42,"tag":76,"props":3661,"children":3662},{},[3663,3669],{"type":42,"tag":86,"props":3664,"children":3666},{"className":3665},[],[3667],{"type":48,"value":3668},"\"last-agent-reply\"",{"type":48,"value":3670}," — incremental, only messages since the agent last spoke",{"type":42,"tag":76,"props":3672,"children":3673},{},[3674,3676,3682,3684,3690],{"type":48,"value":3675},"A predicate ",{"type":42,"tag":86,"props":3677,"children":3679},{"className":3678},[],[3680],{"type":48,"value":3681},"(message: SlackThreadMessage) => boolean",{"type":48,"value":3683}," as a custom cutoff — includes messages after the last match (",{"type":42,"tag":86,"props":3685,"children":3687},{"className":3686},[],[3688],{"type":48,"value":3689},"loadThreadContextMessages",{"type":48,"value":3691}," exists for arbitrary filtering)",{"type":42,"tag":51,"props":3693,"children":3694},{},[3695,3697,3703],{"type":48,"value":3696},"Cost: one ",{"type":42,"tag":86,"props":3698,"children":3700},{"className":3699},[],[3701],{"type":48,"value":3702},"conversations.replies",{"type":48,"value":3704}," API call per triggering reply; requires the matching history scope on the connector.",{"type":42,"tag":124,"props":3706,"children":3708},{"id":3707},"human-in-the-loop-hitl",[3709],{"type":48,"value":3710},"Human-in-the-Loop (HITL)",{"type":42,"tag":51,"props":3712,"children":3713},{},[3714],{"type":48,"value":3715},"Approval-gated tool calls and sign-in challenges render natively in Slack:",{"type":42,"tag":72,"props":3717,"children":3718},{},[3719,3731,3749],{"type":42,"tag":76,"props":3720,"children":3721},{},[3722,3724,3729],{"type":48,"value":3723},"Approval prompts appear as ",{"type":42,"tag":57,"props":3725,"children":3726},{},[3727],{"type":48,"value":3728},"buttons\u002Fselects",{"type":48,"value":3730},"; the user's response resumes the durably-parked session",{"type":42,"tag":76,"props":3732,"children":3733},{},[3734,3736,3741,3743],{"type":48,"value":3735},"Sign-in challenges (OAuth URLs, device codes) go ",{"type":42,"tag":57,"props":3737,"children":3738},{},[3739],{"type":48,"value":3740},"ephemerally",{"type":48,"value":3742}," to the triggering user; a public status message posts in-thread and updates on ",{"type":42,"tag":86,"props":3744,"children":3746},{"className":3745},[],[3747],{"type":48,"value":3748},"authorization.completed",{"type":42,"tag":76,"props":3750,"children":3751},{},[3752,3754,3760,3761,3767,3769,3775,3777,3783,3785,3790],{"type":48,"value":3753},"The HITL handler context deliberately offers only ",{"type":42,"tag":86,"props":3755,"children":3757},{"className":3756},[],[3758],{"type":48,"value":3759},"postEphemeral",{"type":48,"value":2004},{"type":42,"tag":86,"props":3762,"children":3764},{"className":3763},[],[3765],{"type":48,"value":3766},"postDirectMessage",{"type":48,"value":3768}," (needs ",{"type":42,"tag":86,"props":3770,"children":3772},{"className":3771},[],[3773],{"type":48,"value":3774},"im:write",{"type":48,"value":3776},"), and ",{"type":42,"tag":86,"props":3778,"children":3780},{"className":3779},[],[3781],{"type":48,"value":3782},"state",{"type":48,"value":3784}," — no public ",{"type":42,"tag":86,"props":3786,"children":3788},{"className":3787},[],[3789],{"type":48,"value":3380},{"type":48,"value":3791},", no raw API access",{"type":42,"tag":124,"props":3793,"children":3795},{"id":3794},"proactive-sessions-schedules",[3796],{"type":48,"value":3797},"Proactive Sessions (Schedules)",{"type":42,"tag":51,"props":3799,"children":3800},{},[3801],{"type":48,"value":3802},"Start a session that posts into Slack without an inbound trigger — e.g. from a schedule:",{"type":42,"tag":756,"props":3804,"children":3806},{"className":1090,"code":3805,"language":1092,"meta":761,"style":761},"import { receive } from \"eve\";\nimport slack from \"..\u002Fchannels\u002Fslack\";\n\nawait receive(slack, {\n  message: \"Post the daily standup summary for #eng.\",\n  target: { channelId: \"C0123456789\" },\n  auth,\n});\n",[3807],{"type":42,"tag":86,"props":3808,"children":3809},{"__ignoreMap":761},[3810,3850,3884,3891,3916,3945,3987,3999],{"type":42,"tag":767,"props":3811,"children":3812},{"class":769,"line":770},[3813,3817,3821,3826,3830,3834,3838,3842,3846],{"type":42,"tag":767,"props":3814,"children":3815},{"style":1111},[3816],{"type":48,"value":1114},{"type":42,"tag":767,"props":3818,"children":3819},{"style":774},[3820],{"type":48,"value":807},{"type":42,"tag":767,"props":3822,"children":3823},{"style":1121},[3824],{"type":48,"value":3825}," receive",{"type":42,"tag":767,"props":3827,"children":3828},{"style":774},[3829],{"type":48,"value":1129},{"type":42,"tag":767,"props":3831,"children":3832},{"style":1111},[3833],{"type":48,"value":1134},{"type":42,"tag":767,"props":3835,"children":3836},{"style":774},[3837],{"type":48,"value":812},{"type":42,"tag":767,"props":3839,"children":3840},{"style":833},[3841],{"type":48,"value":61},{"type":42,"tag":767,"props":3843,"children":3844},{"style":774},[3845],{"type":48,"value":797},{"type":42,"tag":767,"props":3847,"children":3848},{"style":774},[3849],{"type":48,"value":1151},{"type":42,"tag":767,"props":3851,"children":3852},{"class":769,"line":780},[3853,3857,3862,3867,3871,3876,3880],{"type":42,"tag":767,"props":3854,"children":3855},{"style":1111},[3856],{"type":48,"value":1114},{"type":42,"tag":767,"props":3858,"children":3859},{"style":1121},[3860],{"type":48,"value":3861}," slack ",{"type":42,"tag":767,"props":3863,"children":3864},{"style":1111},[3865],{"type":48,"value":3866},"from",{"type":42,"tag":767,"props":3868,"children":3869},{"style":774},[3870],{"type":48,"value":812},{"type":42,"tag":767,"props":3872,"children":3873},{"style":833},[3874],{"type":48,"value":3875},"..\u002Fchannels\u002Fslack",{"type":42,"tag":767,"props":3877,"children":3878},{"style":774},[3879],{"type":48,"value":797},{"type":42,"tag":767,"props":3881,"children":3882},{"style":774},[3883],{"type":48,"value":1151},{"type":42,"tag":767,"props":3885,"children":3886},{"class":769,"line":26},[3887],{"type":42,"tag":767,"props":3888,"children":3889},{"emptyLinePlaceholder":37},[3890],{"type":48,"value":1159},{"type":42,"tag":767,"props":3892,"children":3893},{"class":769,"line":873},[3894,3899,3903,3908,3912],{"type":42,"tag":767,"props":3895,"children":3896},{"style":1111},[3897],{"type":48,"value":3898},"await",{"type":42,"tag":767,"props":3900,"children":3901},{"style":1175},[3902],{"type":48,"value":3825},{"type":42,"tag":767,"props":3904,"children":3905},{"style":1121},[3906],{"type":48,"value":3907},"(slack",{"type":42,"tag":767,"props":3909,"children":3910},{"style":774},[3911],{"type":48,"value":1216},{"type":42,"tag":767,"props":3913,"children":3914},{"style":774},[3915],{"type":48,"value":870},{"type":42,"tag":767,"props":3917,"children":3918},{"class":769,"line":912},[3919,3924,3928,3932,3937,3941],{"type":42,"tag":767,"props":3920,"children":3921},{"style":1192},[3922],{"type":48,"value":3923},"  message",{"type":42,"tag":767,"props":3925,"children":3926},{"style":774},[3927],{"type":48,"value":802},{"type":42,"tag":767,"props":3929,"children":3930},{"style":774},[3931],{"type":48,"value":812},{"type":42,"tag":767,"props":3933,"children":3934},{"style":833},[3935],{"type":48,"value":3936},"Post the daily standup summary for #eng.",{"type":42,"tag":767,"props":3938,"children":3939},{"style":774},[3940],{"type":48,"value":797},{"type":42,"tag":767,"props":3942,"children":3943},{"style":774},[3944],{"type":48,"value":909},{"type":42,"tag":767,"props":3946,"children":3947},{"class":769,"line":949},[3948,3953,3957,3961,3966,3970,3974,3979,3983],{"type":42,"tag":767,"props":3949,"children":3950},{"style":1192},[3951],{"type":48,"value":3952},"  target",{"type":42,"tag":767,"props":3954,"children":3955},{"style":774},[3956],{"type":48,"value":802},{"type":42,"tag":767,"props":3958,"children":3959},{"style":774},[3960],{"type":48,"value":807},{"type":42,"tag":767,"props":3962,"children":3963},{"style":1192},[3964],{"type":48,"value":3965}," channelId",{"type":42,"tag":767,"props":3967,"children":3968},{"style":774},[3969],{"type":48,"value":802},{"type":42,"tag":767,"props":3971,"children":3972},{"style":774},[3973],{"type":48,"value":812},{"type":42,"tag":767,"props":3975,"children":3976},{"style":833},[3977],{"type":48,"value":3978},"C0123456789",{"type":42,"tag":767,"props":3980,"children":3981},{"style":774},[3982],{"type":48,"value":797},{"type":42,"tag":767,"props":3984,"children":3985},{"style":774},[3986],{"type":48,"value":845},{"type":42,"tag":767,"props":3988,"children":3989},{"class":769,"line":986},[3990,3995],{"type":42,"tag":767,"props":3991,"children":3992},{"style":1121},[3993],{"type":48,"value":3994},"  auth",{"type":42,"tag":767,"props":3996,"children":3997},{"style":774},[3998],{"type":48,"value":909},{"type":42,"tag":767,"props":4000,"children":4001},{"class":769,"line":1019},[4002,4006,4010],{"type":42,"tag":767,"props":4003,"children":4004},{"style":774},[4005],{"type":48,"value":1229},{"type":42,"tag":767,"props":4007,"children":4008},{"style":1121},[4009],{"type":48,"value":1234},{"type":42,"tag":767,"props":4011,"children":4012},{"style":774},[4013],{"type":48,"value":1151},{"type":42,"tag":72,"props":4015,"children":4016},{},[4017,4030,4061],{"type":42,"tag":76,"props":4018,"children":4019},{},[4020,4022,4028],{"type":48,"value":4021},"Sessions without a ",{"type":42,"tag":86,"props":4023,"children":4025},{"className":4024},[],[4026],{"type":48,"value":4027},"threadTs",{"type":48,"value":4029}," get a temporary continuation token; the first post anchors the thread",{"type":42,"tag":76,"props":4031,"children":4032},{},[4033,4039,4041,4047,4049,4054,4056],{"type":42,"tag":86,"props":4034,"children":4036},{"className":4035},[],[4037],{"type":48,"value":4038},"initialMessage",{"type":48,"value":4040}," (optionally a ",{"type":42,"tag":86,"props":4042,"children":4044},{"className":4043},[],[4045],{"type":48,"value":4046},"Card",{"type":48,"value":4048},") and ",{"type":42,"tag":86,"props":4050,"children":4052},{"className":4051},[],[4053],{"type":48,"value":4027},{"type":48,"value":4055}," are ",{"type":42,"tag":57,"props":4057,"children":4058},{},[4059],{"type":48,"value":4060},"mutually exclusive",{"type":42,"tag":76,"props":4062,"children":4063},{},[4064,4066,4074],{"type":48,"value":4065},"Use eve schedules (see ",{"type":42,"tag":4067,"props":4068,"children":4072},"a",{"href":4069,"rel":4070},"https:\u002F\u002Feve.dev\u002Fdocs\u002Fschedules",[4071],"nofollow",[4073],{"type":48,"value":4069},{"type":48,"value":4075},") to trigger proactive sessions on a cadence",{"type":42,"tag":124,"props":4077,"children":4079},{"id":4078},"raw-slack-api-access",[4080],{"type":48,"value":4081},"Raw Slack API Access",{"type":42,"tag":72,"props":4083,"children":4084},{},[4085,4100],{"type":42,"tag":76,"props":4086,"children":4087},{},[4088,4093,4094],{"type":42,"tag":57,"props":4089,"children":4090},{},[4091],{"type":48,"value":4092},"Inside handlers",{"type":48,"value":678},{"type":42,"tag":86,"props":4095,"children":4097},{"className":4096},[],[4098],{"type":48,"value":4099},"ctx.slack.request(operation, body)",{"type":42,"tag":76,"props":4101,"children":4102},{},[4103,4108,4110,4116,4117,4123,4125],{"type":42,"tag":57,"props":4104,"children":4105},{},[4106],{"type":48,"value":4107},"Outside handlers",{"type":48,"value":4109}," (schedules, tools): ",{"type":42,"tag":86,"props":4111,"children":4113},{"className":4112},[],[4114],{"type":48,"value":4115},"callSlackApi({ botToken, operation, body })",{"type":48,"value":3123},{"type":42,"tag":86,"props":4118,"children":4120},{"className":4119},[],[4121],{"type":48,"value":4122},"resolveSlackBotToken",{"type":48,"value":4124}," from ",{"type":42,"tag":86,"props":4126,"children":4128},{"className":4127},[],[4129],{"type":48,"value":684},{"type":42,"tag":51,"props":4131,"children":4132},{},[4133,4135,4141],{"type":48,"value":4134},"These form-encode request bodies for you — Slack's JSON support is only partial, so prefer these helpers over hand-rolled ",{"type":42,"tag":86,"props":4136,"children":4138},{"className":4137},[],[4139],{"type":48,"value":4140},"fetch",{"type":48,"value":4142}," calls.",{"type":42,"tag":636,"props":4144,"children":4145},{},[],{"type":42,"tag":104,"props":4147,"children":4149},{"id":4148},"implementation-gotchas",[4150],{"type":48,"value":4151},"Implementation Gotchas",{"type":42,"tag":124,"props":4153,"children":4155},{"id":4154},"_1-the-slack-surface-cannot-be-tested-locally",[4156],{"type":48,"value":4157},"1. The Slack Surface Cannot Be Tested Locally",{"type":42,"tag":51,"props":4159,"children":4160},{},[4161,4163,4168],{"type":48,"value":4162},"Vercel Connect forwards Slack events ",{"type":42,"tag":57,"props":4164,"children":4165},{},[4166],{"type":48,"value":4167},"to deployments only, never to localhost",{"type":48,"value":4169},". There is no ngrok\u002FSocket Mode escape hatch in this stack. Local development means:",{"type":42,"tag":72,"props":4171,"children":4172},{},[4173,4184,4195],{"type":42,"tag":76,"props":4174,"children":4175},{},[4176,4182],{"type":42,"tag":86,"props":4177,"children":4179},{"className":4178},[],[4180],{"type":48,"value":4181},"npx eve dev",{"type":48,"value":4183}," — HMR server + terminal TUI\u002FREPL for exercising agent logic, tools, and skills",{"type":42,"tag":76,"props":4185,"children":4186},{},[4187,4193],{"type":42,"tag":86,"props":4188,"children":4190},{"className":4189},[],[4191],{"type":48,"value":4192},"eve dev --no-ui",{"type":48,"value":4194}," — background mode for scripted verification",{"type":42,"tag":76,"props":4196,"children":4197},{},[4198,4204,4206,4212],{"type":42,"tag":86,"props":4199,"children":4201},{"className":4200},[],[4202],{"type":48,"value":4203},"eve dev https:\u002F\u002Fyour-app.vercel.app",{"type":48,"value":4205}," — drive a ",{"type":42,"tag":4207,"props":4208,"children":4209},"em",{},[4210],{"type":48,"value":4211},"deployed",{"type":48,"value":4213}," app interactively",{"type":42,"tag":51,"props":4215,"children":4216},{},[4217],{"type":48,"value":4218},"To test @mentions and DMs, deploy (preview or production) and test in Slack itself.",{"type":42,"tag":124,"props":4220,"children":4222},{"id":4221},"_2-connect-forwarding-has-no-delivery-de-duplication",[4223],{"type":48,"value":4224},"2. Connect Forwarding Has No Delivery De-duplication",{"type":42,"tag":51,"props":4226,"children":4227},{},[4228,4230,4235],{"type":48,"value":4229},"Connect may deliver the same forwarded event more than once. ",{"type":42,"tag":57,"props":4231,"children":4232},{},[4233],{"type":48,"value":4234},"Handlers and side effects must be idempotent",{"type":48,"value":4236}," — track processed event IDs where duplicates would be harmful, and gate destructive tool actions with approval (see AI Integration).",{"type":42,"tag":124,"props":4238,"children":4240},{"id":4239},"_3-triggers-is-required-or-events-never-arrive",[4241,4243,4248],{"type":48,"value":4242},"3. ",{"type":42,"tag":86,"props":4244,"children":4246},{"className":4245},[],[4247],{"type":48,"value":2529},{"type":48,"value":4249}," Is Required or Events Never Arrive",{"type":42,"tag":51,"props":4251,"children":4252},{},[4253,4255,4260],{"type":48,"value":4254},"A Slack connector created without ",{"type":42,"tag":86,"props":4256,"children":4258},{"className":4257},[],[4259],{"type":48,"value":2529},{"type":48,"value":4261}," (or attached without a trigger path) will authenticate fine but forward nothing. If the bot never responds to @mentions:",{"type":42,"tag":264,"props":4263,"children":4264},{},[4265,4275,4285],{"type":42,"tag":76,"props":4266,"children":4267},{},[4268,4270],{"type":48,"value":4269},"Verify the connector was created\u002Fattached with ",{"type":42,"tag":86,"props":4271,"children":4273},{"className":4272},[],[4274],{"type":48,"value":2529},{"type":42,"tag":76,"props":4276,"children":4277},{},[4278,4280],{"type":48,"value":4279},"Verify the trigger path is ",{"type":42,"tag":86,"props":4281,"children":4283},{"className":4282},[],[4284],{"type":48,"value":2080},{"type":42,"tag":76,"props":4286,"children":4287},{},[4288],{"type":48,"value":4289},"Verify the bot was invited to the channel and the deployment finished",{"type":42,"tag":124,"props":4291,"children":4293},{"id":4292},"_4-placeholderauth-fails-closed-in-production",[4294,4296,4302],{"type":48,"value":4295},"4. ",{"type":42,"tag":86,"props":4297,"children":4299},{"className":4298},[],[4300],{"type":48,"value":4301},"placeholderAuth()",{"type":48,"value":4303}," Fails Closed in Production",{"type":42,"tag":51,"props":4305,"children":4306},{},[4307,4309,4314,4316,4321,4323,4329,4330,4336,4337,4343,4344,4350,4351,4357,4359,4365,4367,4372],{"type":48,"value":4308},"Scaffolded projects ship with ",{"type":42,"tag":86,"props":4310,"children":4312},{"className":4311},[],[4313],{"type":48,"value":4301},{"type":48,"value":4315}," for the HTTP API, which ",{"type":42,"tag":57,"props":4317,"children":4318},{},[4319],{"type":48,"value":4320},"rejects everything in production",{"type":48,"value":4322},". Before deploying, replace it with a real auth function: ",{"type":42,"tag":86,"props":4324,"children":4326},{"className":4325},[],[4327],{"type":48,"value":4328},"httpBasic()",{"type":48,"value":2004},{"type":42,"tag":86,"props":4331,"children":4333},{"className":4332},[],[4334],{"type":48,"value":4335},"jwtHmac()",{"type":48,"value":2004},{"type":42,"tag":86,"props":4338,"children":4340},{"className":4339},[],[4341],{"type":48,"value":4342},"jwtEcdsa()",{"type":48,"value":2004},{"type":42,"tag":86,"props":4345,"children":4347},{"className":4346},[],[4348],{"type":48,"value":4349},"oidc()",{"type":48,"value":2004},{"type":42,"tag":86,"props":4352,"children":4354},{"className":4353},[],[4355],{"type":48,"value":4356},"vercelOidc()",{"type":48,"value":4358},", or a custom ",{"type":42,"tag":86,"props":4360,"children":4362},{"className":4361},[],[4363],{"type":48,"value":4364},"AuthFn",{"type":48,"value":4366},". (The Slack channel's inbound verification is separate — Connect's ",{"type":42,"tag":86,"props":4368,"children":4370},{"className":4369},[],[4371],{"type":48,"value":2313},{"type":48,"value":4373}," handles that.)",{"type":42,"tag":124,"props":4375,"children":4377},{"id":4376},"_5-sandbox-prewarm-failures-fail-the-build",[4378],{"type":48,"value":4379},"5. Sandbox Prewarm Failures Fail the Build",{"type":42,"tag":51,"props":4381,"children":4382},{},[4383,4385,4391,4393,4399,4401,4406],{"type":48,"value":4384},"Vercel builds prewarm eve's sandbox templates (cache-keyed; build logs show ",{"type":42,"tag":86,"props":4386,"children":4388},{"className":4387},[],[4389],{"type":48,"value":4390},"reused cached",{"type":48,"value":4392}," or ",{"type":42,"tag":86,"props":4394,"children":4396},{"className":4395},[],[4397],{"type":48,"value":4398},"built",{"type":48,"value":4400},"). If prewarm fails, ",{"type":42,"tag":57,"props":4402,"children":4403},{},[4404],{"type":48,"value":4405},"the whole build fails",{"type":48,"value":4407}," — check build logs for sandbox template errors before assuming a code problem.",{"type":42,"tag":124,"props":4409,"children":4411},{"id":4410},"_6-private-channel-access",[4412],{"type":48,"value":4413},"6. Private Channel Access",{"type":42,"tag":51,"props":4415,"children":4416},{},[4417,4419,4424,4426,4432,4433,4439],{"type":48,"value":4418},"The bot ",{"type":42,"tag":57,"props":4420,"children":4421},{},[4422],{"type":48,"value":4423},"cannot read messages or post",{"type":48,"value":4425}," to private channels it hasn't been invited to. When creating features that will later post to a channel (e.g. proactive sessions from a schedule), validate access upfront and surface a clear \"invite the bot\" message on ",{"type":42,"tag":86,"props":4427,"children":4429},{"className":4428},[],[4430],{"type":48,"value":4431},"channel_not_found",{"type":48,"value":2541},{"type":42,"tag":86,"props":4434,"children":4436},{"className":4435},[],[4437],{"type":48,"value":4438},"not_in_channel",{"type":48,"value":1790},{"type":42,"tag":124,"props":4441,"children":4443},{"id":4442},"_7-graceful-degradation-for-channel-context",[4444],{"type":48,"value":4445},"7. Graceful Degradation for Channel Context",{"type":42,"tag":51,"props":4447,"children":4448},{},[4449,4451,4457],{"type":48,"value":4450},"When fetching channel context (e.g. via ",{"type":42,"tag":86,"props":4452,"children":4454},{"className":4453},[],[4455],{"type":48,"value":4456},"ctx.slack.request(\"conversations.history\", ...)",{"type":48,"value":4458},") for AI features, wrap in try\u002Fcatch and fall back gracefully — missing scopes and uninvited channels are routine, not exceptional.",{"type":42,"tag":124,"props":4460,"children":4462},{"id":4461},"_8-vercel-cron-endpoint-authentication",[4463],{"type":48,"value":4464},"8. Vercel Cron Endpoint Authentication",{"type":42,"tag":51,"props":4466,"children":4467},{},[4468,4470,4476],{"type":48,"value":4469},"If you add custom cron endpoints (beyond eve schedules), protect them with a ",{"type":42,"tag":86,"props":4471,"children":4473},{"className":4472},[],[4474],{"type":48,"value":4475},"CRON_SECRET",{"type":48,"value":802},{"type":42,"tag":756,"props":4478,"children":4480},{"className":1539,"code":4479,"language":1541,"meta":761,"style":761},"export async function GET(request: Request) {\n  const authHeader = request.headers.get(\"authorization\");\n  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {\n    return Response.json({ error: \"Unauthorized\" }, { status: 401 });\n  }\n  \u002F\u002F Run cron job logic...\n  return Response.json({ success: true });\n}\n",[4481],{"type":42,"tag":86,"props":4482,"children":4483},{"__ignoreMap":761},[4484,4532,4598,4669,4756,4763,4771,4826],{"type":42,"tag":767,"props":4485,"children":4486},{"class":769,"line":770},[4487,4491,4496,4501,4506,4510,4515,4519,4524,4528],{"type":42,"tag":767,"props":4488,"children":4489},{"style":1111},[4490],{"type":48,"value":1167},{"type":42,"tag":767,"props":4492,"children":4493},{"style":789},[4494],{"type":48,"value":4495}," async",{"type":42,"tag":767,"props":4497,"children":4498},{"style":789},[4499],{"type":48,"value":4500}," function",{"type":42,"tag":767,"props":4502,"children":4503},{"style":1175},[4504],{"type":48,"value":4505}," GET",{"type":42,"tag":767,"props":4507,"children":4508},{"style":774},[4509],{"type":48,"value":1182},{"type":42,"tag":767,"props":4511,"children":4512},{"style":2762},[4513],{"type":48,"value":4514},"request",{"type":42,"tag":767,"props":4516,"children":4517},{"style":774},[4518],{"type":48,"value":802},{"type":42,"tag":767,"props":4520,"children":4521},{"style":815},[4522],{"type":48,"value":4523}," Request",{"type":42,"tag":767,"props":4525,"children":4526},{"style":774},[4527],{"type":48,"value":1234},{"type":42,"tag":767,"props":4529,"children":4530},{"style":774},[4531],{"type":48,"value":870},{"type":42,"tag":767,"props":4533,"children":4534},{"class":769,"line":780},[4535,4540,4545,4550,4555,4559,4564,4568,4573,4577,4581,4586,4590,4594],{"type":42,"tag":767,"props":4536,"children":4537},{"style":789},[4538],{"type":48,"value":4539},"  const",{"type":42,"tag":767,"props":4541,"children":4542},{"style":1121},[4543],{"type":48,"value":4544}," authHeader",{"type":42,"tag":767,"props":4546,"children":4547},{"style":774},[4548],{"type":48,"value":4549}," =",{"type":42,"tag":767,"props":4551,"children":4552},{"style":1121},[4553],{"type":48,"value":4554}," request",{"type":42,"tag":767,"props":4556,"children":4557},{"style":774},[4558],{"type":48,"value":1790},{"type":42,"tag":767,"props":4560,"children":4561},{"style":1121},[4562],{"type":48,"value":4563},"headers",{"type":42,"tag":767,"props":4565,"children":4566},{"style":774},[4567],{"type":48,"value":1790},{"type":42,"tag":767,"props":4569,"children":4570},{"style":1175},[4571],{"type":48,"value":4572},"get",{"type":42,"tag":767,"props":4574,"children":4575},{"style":1192},[4576],{"type":48,"value":1182},{"type":42,"tag":767,"props":4578,"children":4579},{"style":774},[4580],{"type":48,"value":797},{"type":42,"tag":767,"props":4582,"children":4583},{"style":833},[4584],{"type":48,"value":4585},"authorization",{"type":42,"tag":767,"props":4587,"children":4588},{"style":774},[4589],{"type":48,"value":797},{"type":42,"tag":767,"props":4591,"children":4592},{"style":1192},[4593],{"type":48,"value":1234},{"type":42,"tag":767,"props":4595,"children":4596},{"style":774},[4597],{"type":48,"value":1151},{"type":42,"tag":767,"props":4599,"children":4600},{"class":769,"line":26},[4601,4606,4610,4615,4620,4625,4630,4635,4640,4644,4648,4652,4656,4661,4665],{"type":42,"tag":767,"props":4602,"children":4603},{"style":1111},[4604],{"type":48,"value":4605},"  if",{"type":42,"tag":767,"props":4607,"children":4608},{"style":1192},[4609],{"type":48,"value":84},{"type":42,"tag":767,"props":4611,"children":4612},{"style":1121},[4613],{"type":48,"value":4614},"authHeader",{"type":42,"tag":767,"props":4616,"children":4617},{"style":774},[4618],{"type":48,"value":4619}," !==",{"type":42,"tag":767,"props":4621,"children":4622},{"style":774},[4623],{"type":48,"value":4624}," `",{"type":42,"tag":767,"props":4626,"children":4627},{"style":833},[4628],{"type":48,"value":4629},"Bearer ",{"type":42,"tag":767,"props":4631,"children":4632},{"style":774},[4633],{"type":48,"value":4634},"${",{"type":42,"tag":767,"props":4636,"children":4637},{"style":1121},[4638],{"type":48,"value":4639},"process",{"type":42,"tag":767,"props":4641,"children":4642},{"style":774},[4643],{"type":48,"value":1790},{"type":42,"tag":767,"props":4645,"children":4646},{"style":1121},[4647],{"type":48,"value":2238},{"type":42,"tag":767,"props":4649,"children":4650},{"style":774},[4651],{"type":48,"value":1790},{"type":42,"tag":767,"props":4653,"children":4654},{"style":1121},[4655],{"type":48,"value":4475},{"type":42,"tag":767,"props":4657,"children":4658},{"style":774},[4659],{"type":48,"value":4660},"}`",{"type":42,"tag":767,"props":4662,"children":4663},{"style":1192},[4664],{"type":48,"value":3322},{"type":42,"tag":767,"props":4666,"children":4667},{"style":774},[4668],{"type":48,"value":777},{"type":42,"tag":767,"props":4670,"children":4671},{"class":769,"line":873},[4672,4676,4681,4685,4689,4693,4698,4703,4707,4711,4716,4720,4725,4729,4734,4738,4744,4748,4752],{"type":42,"tag":767,"props":4673,"children":4674},{"style":1111},[4675],{"type":48,"value":2836},{"type":42,"tag":767,"props":4677,"children":4678},{"style":1121},[4679],{"type":48,"value":4680}," Response",{"type":42,"tag":767,"props":4682,"children":4683},{"style":774},[4684],{"type":48,"value":1790},{"type":42,"tag":767,"props":4686,"children":4687},{"style":1175},[4688],{"type":48,"value":760},{"type":42,"tag":767,"props":4690,"children":4691},{"style":1192},[4692],{"type":48,"value":1182},{"type":42,"tag":767,"props":4694,"children":4695},{"style":774},[4696],{"type":48,"value":4697},"{",{"type":42,"tag":767,"props":4699,"children":4700},{"style":1192},[4701],{"type":48,"value":4702}," error",{"type":42,"tag":767,"props":4704,"children":4705},{"style":774},[4706],{"type":48,"value":802},{"type":42,"tag":767,"props":4708,"children":4709},{"style":774},[4710],{"type":48,"value":812},{"type":42,"tag":767,"props":4712,"children":4713},{"style":833},[4714],{"type":48,"value":4715},"Unauthorized",{"type":42,"tag":767,"props":4717,"children":4718},{"style":774},[4719],{"type":48,"value":797},{"type":42,"tag":767,"props":4721,"children":4722},{"style":774},[4723],{"type":48,"value":4724}," },",{"type":42,"tag":767,"props":4726,"children":4727},{"style":774},[4728],{"type":48,"value":807},{"type":42,"tag":767,"props":4730,"children":4731},{"style":1192},[4732],{"type":48,"value":4733}," status",{"type":42,"tag":767,"props":4735,"children":4736},{"style":774},[4737],{"type":48,"value":802},{"type":42,"tag":767,"props":4739,"children":4741},{"style":4740},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[4742],{"type":48,"value":4743}," 401",{"type":42,"tag":767,"props":4745,"children":4746},{"style":774},[4747],{"type":48,"value":1129},{"type":42,"tag":767,"props":4749,"children":4750},{"style":1192},[4751],{"type":48,"value":1234},{"type":42,"tag":767,"props":4753,"children":4754},{"style":774},[4755],{"type":48,"value":1151},{"type":42,"tag":767,"props":4757,"children":4758},{"class":769,"line":912},[4759],{"type":42,"tag":767,"props":4760,"children":4761},{"style":774},[4762],{"type":48,"value":1025},{"type":42,"tag":767,"props":4764,"children":4765},{"class":769,"line":949},[4766],{"type":42,"tag":767,"props":4767,"children":4768},{"style":1102},[4769],{"type":48,"value":4770},"  \u002F\u002F Run cron job logic...\n",{"type":42,"tag":767,"props":4772,"children":4773},{"class":769,"line":986},[4774,4779,4783,4787,4791,4795,4799,4804,4808,4814,4818,4822],{"type":42,"tag":767,"props":4775,"children":4776},{"style":1111},[4777],{"type":48,"value":4778},"  return",{"type":42,"tag":767,"props":4780,"children":4781},{"style":1121},[4782],{"type":48,"value":4680},{"type":42,"tag":767,"props":4784,"children":4785},{"style":774},[4786],{"type":48,"value":1790},{"type":42,"tag":767,"props":4788,"children":4789},{"style":1175},[4790],{"type":48,"value":760},{"type":42,"tag":767,"props":4792,"children":4793},{"style":1192},[4794],{"type":48,"value":1182},{"type":42,"tag":767,"props":4796,"children":4797},{"style":774},[4798],{"type":48,"value":4697},{"type":42,"tag":767,"props":4800,"children":4801},{"style":1192},[4802],{"type":48,"value":4803}," success",{"type":42,"tag":767,"props":4805,"children":4806},{"style":774},[4807],{"type":48,"value":802},{"type":42,"tag":767,"props":4809,"children":4811},{"style":4810},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[4812],{"type":48,"value":4813}," true",{"type":42,"tag":767,"props":4815,"children":4816},{"style":774},[4817],{"type":48,"value":1129},{"type":42,"tag":767,"props":4819,"children":4820},{"style":1192},[4821],{"type":48,"value":1234},{"type":42,"tag":767,"props":4823,"children":4824},{"style":774},[4825],{"type":48,"value":1151},{"type":42,"tag":767,"props":4827,"children":4828},{"class":769,"line":1019},[4829],{"type":42,"tag":767,"props":4830,"children":4831},{"style":774},[4832],{"type":48,"value":1034},{"type":42,"tag":124,"props":4834,"children":4836},{"id":4835},"_9-verceljson-cron-configuration",[4837],{"type":48,"value":4838},"9. vercel.json Cron Configuration",{"type":42,"tag":756,"props":4840,"children":4842},{"className":758,"code":4841,"language":760,"meta":761,"style":761},"{\n  \"crons\": [\n    {\n      \"path\": \"\u002Fapi\u002Fcron\u002Fmy-job\",\n      \"schedule\": \"0 * * * *\"\n    }\n  ]\n}\n",[4843],{"type":42,"tag":86,"props":4844,"children":4845},{"__ignoreMap":761},[4846,4853,4878,4886,4924,4957,4965,4973],{"type":42,"tag":767,"props":4847,"children":4848},{"class":769,"line":770},[4849],{"type":42,"tag":767,"props":4850,"children":4851},{"style":774},[4852],{"type":48,"value":777},{"type":42,"tag":767,"props":4854,"children":4855},{"class":769,"line":780},[4856,4860,4865,4869,4873],{"type":42,"tag":767,"props":4857,"children":4858},{"style":774},[4859],{"type":48,"value":786},{"type":42,"tag":767,"props":4861,"children":4862},{"style":789},[4863],{"type":48,"value":4864},"crons",{"type":42,"tag":767,"props":4866,"children":4867},{"style":774},[4868],{"type":48,"value":797},{"type":42,"tag":767,"props":4870,"children":4871},{"style":774},[4872],{"type":48,"value":802},{"type":42,"tag":767,"props":4874,"children":4875},{"style":774},[4876],{"type":48,"value":4877}," [\n",{"type":42,"tag":767,"props":4879,"children":4880},{"class":769,"line":26},[4881],{"type":42,"tag":767,"props":4882,"children":4883},{"style":774},[4884],{"type":48,"value":4885},"    {\n",{"type":42,"tag":767,"props":4887,"children":4888},{"class":769,"line":873},[4889,4894,4899,4903,4907,4911,4916,4920],{"type":42,"tag":767,"props":4890,"children":4891},{"style":774},[4892],{"type":48,"value":4893},"      \"",{"type":42,"tag":767,"props":4895,"children":4896},{"style":815},[4897],{"type":48,"value":4898},"path",{"type":42,"tag":767,"props":4900,"children":4901},{"style":774},[4902],{"type":48,"value":797},{"type":42,"tag":767,"props":4904,"children":4905},{"style":774},[4906],{"type":48,"value":802},{"type":42,"tag":767,"props":4908,"children":4909},{"style":774},[4910],{"type":48,"value":812},{"type":42,"tag":767,"props":4912,"children":4913},{"style":833},[4914],{"type":48,"value":4915},"\u002Fapi\u002Fcron\u002Fmy-job",{"type":42,"tag":767,"props":4917,"children":4918},{"style":774},[4919],{"type":48,"value":797},{"type":42,"tag":767,"props":4921,"children":4922},{"style":774},[4923],{"type":48,"value":909},{"type":42,"tag":767,"props":4925,"children":4926},{"class":769,"line":912},[4927,4931,4936,4940,4944,4948,4953],{"type":42,"tag":767,"props":4928,"children":4929},{"style":774},[4930],{"type":48,"value":4893},{"type":42,"tag":767,"props":4932,"children":4933},{"style":815},[4934],{"type":48,"value":4935},"schedule",{"type":42,"tag":767,"props":4937,"children":4938},{"style":774},[4939],{"type":48,"value":797},{"type":42,"tag":767,"props":4941,"children":4942},{"style":774},[4943],{"type":48,"value":802},{"type":42,"tag":767,"props":4945,"children":4946},{"style":774},[4947],{"type":48,"value":812},{"type":42,"tag":767,"props":4949,"children":4950},{"style":833},[4951],{"type":48,"value":4952},"0 * * * *",{"type":42,"tag":767,"props":4954,"children":4955},{"style":774},[4956],{"type":48,"value":1016},{"type":42,"tag":767,"props":4958,"children":4959},{"class":769,"line":949},[4960],{"type":42,"tag":767,"props":4961,"children":4962},{"style":774},[4963],{"type":48,"value":4964},"    }\n",{"type":42,"tag":767,"props":4966,"children":4967},{"class":769,"line":986},[4968],{"type":42,"tag":767,"props":4969,"children":4970},{"style":774},[4971],{"type":48,"value":4972},"  ]\n",{"type":42,"tag":767,"props":4974,"children":4975},{"class":769,"line":1019},[4976],{"type":42,"tag":767,"props":4977,"children":4978},{"style":774},[4979],{"type":48,"value":1034},{"type":42,"tag":51,"props":4981,"children":4982},{},[4983],{"type":48,"value":4984},"Prefer eve schedules for agent-driven recurring work; use Vercel crons for plain HTTP jobs.",{"type":42,"tag":124,"props":4986,"children":4988},{"id":4987},"_10-aws-credentials-on-vercel-use-oidc",[4989],{"type":48,"value":4990},"10. AWS Credentials on Vercel (Use OIDC)",{"type":42,"tag":51,"props":4992,"children":4993},{},[4994,4996,5001,5003,5009],{"type":48,"value":4995},"When connecting to AWS services from Vercel, ",{"type":42,"tag":57,"props":4997,"children":4998},{},[4999],{"type":48,"value":5000},"do not use",{"type":48,"value":5002}," ",{"type":42,"tag":86,"props":5004,"children":5006},{"className":5005},[],[5007],{"type":48,"value":5008},"fromNodeProviderChain()",{"type":48,"value":5010},". Use Vercel's OIDC mechanism:",{"type":42,"tag":756,"props":5012,"children":5014},{"className":1539,"code":5013,"language":1541,"meta":761,"style":761},"import { awsCredentialsProvider } from \"@vercel\u002Ffunctions\u002Foidc\";\n\nconst s3Client = new S3Client({\n  credentials: awsCredentialsProvider({ roleArn: process.env.AWS_ROLE_ARN! }),\n});\n",[5015],{"type":42,"tag":86,"props":5016,"children":5017},{"__ignoreMap":761},[5018,5059,5066,5102,5172],{"type":42,"tag":767,"props":5019,"children":5020},{"class":769,"line":770},[5021,5025,5029,5034,5038,5042,5046,5051,5055],{"type":42,"tag":767,"props":5022,"children":5023},{"style":1111},[5024],{"type":48,"value":1114},{"type":42,"tag":767,"props":5026,"children":5027},{"style":774},[5028],{"type":48,"value":807},{"type":42,"tag":767,"props":5030,"children":5031},{"style":1121},[5032],{"type":48,"value":5033}," awsCredentialsProvider",{"type":42,"tag":767,"props":5035,"children":5036},{"style":774},[5037],{"type":48,"value":1129},{"type":42,"tag":767,"props":5039,"children":5040},{"style":1111},[5041],{"type":48,"value":1134},{"type":42,"tag":767,"props":5043,"children":5044},{"style":774},[5045],{"type":48,"value":812},{"type":42,"tag":767,"props":5047,"children":5048},{"style":833},[5049],{"type":48,"value":5050},"@vercel\u002Ffunctions\u002Foidc",{"type":42,"tag":767,"props":5052,"children":5053},{"style":774},[5054],{"type":48,"value":797},{"type":42,"tag":767,"props":5056,"children":5057},{"style":774},[5058],{"type":48,"value":1151},{"type":42,"tag":767,"props":5060,"children":5061},{"class":769,"line":780},[5062],{"type":42,"tag":767,"props":5063,"children":5064},{"emptyLinePlaceholder":37},[5065],{"type":48,"value":1159},{"type":42,"tag":767,"props":5067,"children":5068},{"class":769,"line":26},[5069,5074,5079,5084,5089,5094,5098],{"type":42,"tag":767,"props":5070,"children":5071},{"style":789},[5072],{"type":48,"value":5073},"const",{"type":42,"tag":767,"props":5075,"children":5076},{"style":1121},[5077],{"type":48,"value":5078}," s3Client ",{"type":42,"tag":767,"props":5080,"children":5081},{"style":774},[5082],{"type":48,"value":5083},"=",{"type":42,"tag":767,"props":5085,"children":5086},{"style":774},[5087],{"type":48,"value":5088}," new",{"type":42,"tag":767,"props":5090,"children":5091},{"style":1175},[5092],{"type":48,"value":5093}," S3Client",{"type":42,"tag":767,"props":5095,"children":5096},{"style":1121},[5097],{"type":48,"value":1182},{"type":42,"tag":767,"props":5099,"children":5100},{"style":774},[5101],{"type":48,"value":777},{"type":42,"tag":767,"props":5103,"children":5104},{"class":769,"line":873},[5105,5109,5113,5117,5121,5125,5130,5134,5139,5143,5147,5151,5156,5160,5164,5168],{"type":42,"tag":767,"props":5106,"children":5107},{"style":1192},[5108],{"type":48,"value":2216},{"type":42,"tag":767,"props":5110,"children":5111},{"style":774},[5112],{"type":48,"value":802},{"type":42,"tag":767,"props":5114,"children":5115},{"style":1175},[5116],{"type":48,"value":5033},{"type":42,"tag":767,"props":5118,"children":5119},{"style":1121},[5120],{"type":48,"value":1182},{"type":42,"tag":767,"props":5122,"children":5123},{"style":774},[5124],{"type":48,"value":4697},{"type":42,"tag":767,"props":5126,"children":5127},{"style":1192},[5128],{"type":48,"value":5129}," roleArn",{"type":42,"tag":767,"props":5131,"children":5132},{"style":774},[5133],{"type":48,"value":802},{"type":42,"tag":767,"props":5135,"children":5136},{"style":1121},[5137],{"type":48,"value":5138}," process",{"type":42,"tag":767,"props":5140,"children":5141},{"style":774},[5142],{"type":48,"value":1790},{"type":42,"tag":767,"props":5144,"children":5145},{"style":1121},[5146],{"type":48,"value":2238},{"type":42,"tag":767,"props":5148,"children":5149},{"style":774},[5150],{"type":48,"value":1790},{"type":42,"tag":767,"props":5152,"children":5153},{"style":1121},[5154],{"type":48,"value":5155},"AWS_ROLE_ARN",{"type":42,"tag":767,"props":5157,"children":5158},{"style":774},[5159],{"type":48,"value":2251},{"type":42,"tag":767,"props":5161,"children":5162},{"style":774},[5163],{"type":48,"value":1129},{"type":42,"tag":767,"props":5165,"children":5166},{"style":1121},[5167],{"type":48,"value":1234},{"type":42,"tag":767,"props":5169,"children":5170},{"style":774},[5171],{"type":48,"value":909},{"type":42,"tag":767,"props":5173,"children":5174},{"class":769,"line":912},[5175,5179,5183],{"type":42,"tag":767,"props":5176,"children":5177},{"style":774},[5178],{"type":48,"value":1229},{"type":42,"tag":767,"props":5180,"children":5181},{"style":1121},[5182],{"type":48,"value":1234},{"type":42,"tag":767,"props":5184,"children":5185},{"style":774},[5186],{"type":48,"value":1151},{"type":42,"tag":636,"props":5188,"children":5189},{},[],{"type":42,"tag":104,"props":5191,"children":5193},{"id":5192},"ai-integration",[5194],{"type":48,"value":5195},"AI Integration",{"type":42,"tag":124,"props":5197,"children":5199},{"id":5198},"model-configuration-gateway-first",[5200],{"type":48,"value":5201},"Model Configuration (Gateway-First)",{"type":42,"tag":51,"props":5203,"children":5204},{},[5205,5207,5212,5214,5219,5221,5226],{"type":48,"value":5206},"eve routes model-ID ",{"type":42,"tag":57,"props":5208,"children":5209},{},[5210],{"type":48,"value":5211},"strings",{"type":48,"value":5213}," through the ",{"type":42,"tag":57,"props":5215,"children":5216},{},[5217],{"type":48,"value":5218},"Vercel AI Gateway",{"type":48,"value":5220}," — on Vercel, project OIDC authenticates automatically, so ",{"type":42,"tag":57,"props":5222,"children":5223},{},[5224],{"type":48,"value":5225},"no AI API key is needed",{"type":48,"value":802},{"type":42,"tag":756,"props":5228,"children":5230},{"className":1090,"code":5229,"language":1092,"meta":761,"style":761},"\u002F\u002F agent\u002Fagent.ts\nimport { defineAgent } from \"eve\";\n\nexport default defineAgent({\n  model: \"anthropic\u002Fclaude-sonnet-5\", \u002F\u002F string → AI Gateway → OIDC auth on Vercel\n});\n",[5231],{"type":42,"tag":86,"props":5232,"children":5233},{"__ignoreMap":761},[5234,5241,5280,5287,5310,5342],{"type":42,"tag":767,"props":5235,"children":5236},{"class":769,"line":770},[5237],{"type":42,"tag":767,"props":5238,"children":5239},{"style":1102},[5240],{"type":48,"value":1105},{"type":42,"tag":767,"props":5242,"children":5243},{"class":769,"line":780},[5244,5248,5252,5256,5260,5264,5268,5272,5276],{"type":42,"tag":767,"props":5245,"children":5246},{"style":1111},[5247],{"type":48,"value":1114},{"type":42,"tag":767,"props":5249,"children":5250},{"style":774},[5251],{"type":48,"value":807},{"type":42,"tag":767,"props":5253,"children":5254},{"style":1121},[5255],{"type":48,"value":1124},{"type":42,"tag":767,"props":5257,"children":5258},{"style":774},[5259],{"type":48,"value":1129},{"type":42,"tag":767,"props":5261,"children":5262},{"style":1111},[5263],{"type":48,"value":1134},{"type":42,"tag":767,"props":5265,"children":5266},{"style":774},[5267],{"type":48,"value":812},{"type":42,"tag":767,"props":5269,"children":5270},{"style":833},[5271],{"type":48,"value":61},{"type":42,"tag":767,"props":5273,"children":5274},{"style":774},[5275],{"type":48,"value":797},{"type":42,"tag":767,"props":5277,"children":5278},{"style":774},[5279],{"type":48,"value":1151},{"type":42,"tag":767,"props":5281,"children":5282},{"class":769,"line":26},[5283],{"type":42,"tag":767,"props":5284,"children":5285},{"emptyLinePlaceholder":37},[5286],{"type":48,"value":1159},{"type":42,"tag":767,"props":5288,"children":5289},{"class":769,"line":873},[5290,5294,5298,5302,5306],{"type":42,"tag":767,"props":5291,"children":5292},{"style":1111},[5293],{"type":48,"value":1167},{"type":42,"tag":767,"props":5295,"children":5296},{"style":1111},[5297],{"type":48,"value":1172},{"type":42,"tag":767,"props":5299,"children":5300},{"style":1175},[5301],{"type":48,"value":1124},{"type":42,"tag":767,"props":5303,"children":5304},{"style":1121},[5305],{"type":48,"value":1182},{"type":42,"tag":767,"props":5307,"children":5308},{"style":774},[5309],{"type":48,"value":777},{"type":42,"tag":767,"props":5311,"children":5312},{"class":769,"line":912},[5313,5317,5321,5325,5329,5333,5337],{"type":42,"tag":767,"props":5314,"children":5315},{"style":1192},[5316],{"type":48,"value":1195},{"type":42,"tag":767,"props":5318,"children":5319},{"style":774},[5320],{"type":48,"value":802},{"type":42,"tag":767,"props":5322,"children":5323},{"style":774},[5324],{"type":48,"value":812},{"type":42,"tag":767,"props":5326,"children":5327},{"style":833},[5328],{"type":48,"value":709},{"type":42,"tag":767,"props":5330,"children":5331},{"style":774},[5332],{"type":48,"value":797},{"type":42,"tag":767,"props":5334,"children":5335},{"style":774},[5336],{"type":48,"value":1216},{"type":42,"tag":767,"props":5338,"children":5339},{"style":1102},[5340],{"type":48,"value":5341}," \u002F\u002F string → AI Gateway → OIDC auth on Vercel\n",{"type":42,"tag":767,"props":5343,"children":5344},{"class":769,"line":949},[5345,5349,5353],{"type":42,"tag":767,"props":5346,"children":5347},{"style":774},[5348],{"type":48,"value":1229},{"type":42,"tag":767,"props":5350,"children":5351},{"style":1121},[5352],{"type":48,"value":1234},{"type":42,"tag":767,"props":5354,"children":5355},{"style":774},[5356],{"type":48,"value":1151},{"type":42,"tag":51,"props":5358,"children":5359},{},[5360,5362,5368,5370,5375,5377,5383],{"type":48,"value":5361},"If ",{"type":42,"tag":86,"props":5363,"children":5365},{"className":5364},[],[5366],{"type":48,"value":5367},"model",{"type":48,"value":5369}," is omitted, eve defaults to ",{"type":42,"tag":86,"props":5371,"children":5373},{"className":5372},[],[5374],{"type":48,"value":709},{"type":48,"value":5376},". Off Vercel, set ",{"type":42,"tag":86,"props":5378,"children":5380},{"className":5379},[],[5381],{"type":48,"value":5382},"AI_GATEWAY_API_KEY",{"type":48,"value":1790},{"type":42,"tag":51,"props":5385,"children":5386},{},[5387,5392,5394,5400],{"type":42,"tag":57,"props":5388,"children":5389},{},[5390],{"type":48,"value":5391},"CRITICAL: Never use model IDs from memory.",{"type":48,"value":5393}," Model IDs change frequently. Before writing code that pins a model, run ",{"type":42,"tag":86,"props":5395,"children":5397},{"className":5396},[],[5398],{"type":48,"value":5399},"curl -s https:\u002F\u002Fai-gateway.vercel.sh\u002Fv1\u002Fmodels",{"type":48,"value":5401}," to fetch the current list and use the newest suitable version.",{"type":42,"tag":124,"props":5403,"children":5405},{"id":5404},"tools-agenttoolsts",[5406,5408,5414],{"type":48,"value":5407},"Tools (",{"type":42,"tag":86,"props":5409,"children":5411},{"className":5410},[],[5412],{"type":48,"value":5413},"agent\u002Ftools\u002F*.ts",{"type":48,"value":1234},{"type":42,"tag":51,"props":5416,"children":5417},{},[5418,5420,5426,5428,5434],{"type":48,"value":5419},"Tools are files: the filename (snake_case ASCII) is the model-facing tool name — ",{"type":42,"tag":86,"props":5421,"children":5423},{"className":5422},[],[5424],{"type":48,"value":5425},"agent\u002Ftools\u002Fget_weather.ts",{"type":48,"value":5427}," → ",{"type":42,"tag":86,"props":5429,"children":5431},{"className":5430},[],[5432],{"type":48,"value":5433},"get_weather",{"type":48,"value":5435},". No registration step.",{"type":42,"tag":756,"props":5437,"children":5439},{"className":1090,"code":5438,"language":1092,"meta":761,"style":761},"\u002F\u002F agent\u002Ftools\u002Fget_weather.ts\nimport { defineTool } from \"eve\u002Ftools\";\nimport { z } from \"zod\";\n\nexport default defineTool({\n  description: \"Get the current weather for a city.\",\n  inputSchema: z.object({ city: z.string().min(1) }), \u002F\u002F required, even if empty\n  outputSchema: z.object({\n    city: z.string(),\n    condition: z.string(),\n    temperatureF: z.number(),\n  }), \u002F\u002F optional — types\u002Fvalidates the return\n  async execute({ city }, ctx) {\n    return { city, condition: \"Sunny\", temperatureF: 72 };\n  },\n});\n",[5440],{"type":42,"tag":86,"props":5441,"children":5442},{"__ignoreMap":761},[5443,5451,5492,5532,5539,5562,5591,5690,5722,5754,5786,5819,5839,5876,5939,5946],{"type":42,"tag":767,"props":5444,"children":5445},{"class":769,"line":770},[5446],{"type":42,"tag":767,"props":5447,"children":5448},{"style":1102},[5449],{"type":48,"value":5450},"\u002F\u002F agent\u002Ftools\u002Fget_weather.ts\n",{"type":42,"tag":767,"props":5452,"children":5453},{"class":769,"line":780},[5454,5458,5462,5467,5471,5475,5479,5484,5488],{"type":42,"tag":767,"props":5455,"children":5456},{"style":1111},[5457],{"type":48,"value":1114},{"type":42,"tag":767,"props":5459,"children":5460},{"style":774},[5461],{"type":48,"value":807},{"type":42,"tag":767,"props":5463,"children":5464},{"style":1121},[5465],{"type":48,"value":5466}," defineTool",{"type":42,"tag":767,"props":5468,"children":5469},{"style":774},[5470],{"type":48,"value":1129},{"type":42,"tag":767,"props":5472,"children":5473},{"style":1111},[5474],{"type":48,"value":1134},{"type":42,"tag":767,"props":5476,"children":5477},{"style":774},[5478],{"type":48,"value":812},{"type":42,"tag":767,"props":5480,"children":5481},{"style":833},[5482],{"type":48,"value":5483},"eve\u002Ftools",{"type":42,"tag":767,"props":5485,"children":5486},{"style":774},[5487],{"type":48,"value":797},{"type":42,"tag":767,"props":5489,"children":5490},{"style":774},[5491],{"type":48,"value":1151},{"type":42,"tag":767,"props":5493,"children":5494},{"class":769,"line":26},[5495,5499,5503,5508,5512,5516,5520,5524,5528],{"type":42,"tag":767,"props":5496,"children":5497},{"style":1111},[5498],{"type":48,"value":1114},{"type":42,"tag":767,"props":5500,"children":5501},{"style":774},[5502],{"type":48,"value":807},{"type":42,"tag":767,"props":5504,"children":5505},{"style":1121},[5506],{"type":48,"value":5507}," z",{"type":42,"tag":767,"props":5509,"children":5510},{"style":774},[5511],{"type":48,"value":1129},{"type":42,"tag":767,"props":5513,"children":5514},{"style":1111},[5515],{"type":48,"value":1134},{"type":42,"tag":767,"props":5517,"children":5518},{"style":774},[5519],{"type":48,"value":812},{"type":42,"tag":767,"props":5521,"children":5522},{"style":833},[5523],{"type":48,"value":717},{"type":42,"tag":767,"props":5525,"children":5526},{"style":774},[5527],{"type":48,"value":797},{"type":42,"tag":767,"props":5529,"children":5530},{"style":774},[5531],{"type":48,"value":1151},{"type":42,"tag":767,"props":5533,"children":5534},{"class":769,"line":873},[5535],{"type":42,"tag":767,"props":5536,"children":5537},{"emptyLinePlaceholder":37},[5538],{"type":48,"value":1159},{"type":42,"tag":767,"props":5540,"children":5541},{"class":769,"line":912},[5542,5546,5550,5554,5558],{"type":42,"tag":767,"props":5543,"children":5544},{"style":1111},[5545],{"type":48,"value":1167},{"type":42,"tag":767,"props":5547,"children":5548},{"style":1111},[5549],{"type":48,"value":1172},{"type":42,"tag":767,"props":5551,"children":5552},{"style":1175},[5553],{"type":48,"value":5466},{"type":42,"tag":767,"props":5555,"children":5556},{"style":1121},[5557],{"type":48,"value":1182},{"type":42,"tag":767,"props":5559,"children":5560},{"style":774},[5561],{"type":48,"value":777},{"type":42,"tag":767,"props":5563,"children":5564},{"class":769,"line":949},[5565,5570,5574,5578,5583,5587],{"type":42,"tag":767,"props":5566,"children":5567},{"style":1192},[5568],{"type":48,"value":5569},"  description",{"type":42,"tag":767,"props":5571,"children":5572},{"style":774},[5573],{"type":48,"value":802},{"type":42,"tag":767,"props":5575,"children":5576},{"style":774},[5577],{"type":48,"value":812},{"type":42,"tag":767,"props":5579,"children":5580},{"style":833},[5581],{"type":48,"value":5582},"Get the current weather for a city.",{"type":42,"tag":767,"props":5584,"children":5585},{"style":774},[5586],{"type":48,"value":797},{"type":42,"tag":767,"props":5588,"children":5589},{"style":774},[5590],{"type":48,"value":909},{"type":42,"tag":767,"props":5592,"children":5593},{"class":769,"line":986},[5594,5599,5603,5607,5611,5616,5620,5624,5629,5633,5637,5641,5646,5651,5655,5660,5664,5669,5673,5677,5681,5685],{"type":42,"tag":767,"props":5595,"children":5596},{"style":1192},[5597],{"type":48,"value":5598},"  inputSchema",{"type":42,"tag":767,"props":5600,"children":5601},{"style":774},[5602],{"type":48,"value":802},{"type":42,"tag":767,"props":5604,"children":5605},{"style":1121},[5606],{"type":48,"value":5507},{"type":42,"tag":767,"props":5608,"children":5609},{"style":774},[5610],{"type":48,"value":1790},{"type":42,"tag":767,"props":5612,"children":5613},{"style":1175},[5614],{"type":48,"value":5615},"object",{"type":42,"tag":767,"props":5617,"children":5618},{"style":1121},[5619],{"type":48,"value":1182},{"type":42,"tag":767,"props":5621,"children":5622},{"style":774},[5623],{"type":48,"value":4697},{"type":42,"tag":767,"props":5625,"children":5626},{"style":1192},[5627],{"type":48,"value":5628}," city",{"type":42,"tag":767,"props":5630,"children":5631},{"style":774},[5632],{"type":48,"value":802},{"type":42,"tag":767,"props":5634,"children":5635},{"style":1121},[5636],{"type":48,"value":5507},{"type":42,"tag":767,"props":5638,"children":5639},{"style":774},[5640],{"type":48,"value":1790},{"type":42,"tag":767,"props":5642,"children":5643},{"style":1175},[5644],{"type":48,"value":5645},"string",{"type":42,"tag":767,"props":5647,"children":5648},{"style":1121},[5649],{"type":48,"value":5650},"()",{"type":42,"tag":767,"props":5652,"children":5653},{"style":774},[5654],{"type":48,"value":1790},{"type":42,"tag":767,"props":5656,"children":5657},{"style":1175},[5658],{"type":48,"value":5659},"min",{"type":42,"tag":767,"props":5661,"children":5662},{"style":1121},[5663],{"type":48,"value":1182},{"type":42,"tag":767,"props":5665,"children":5666},{"style":4740},[5667],{"type":48,"value":5668},"1",{"type":42,"tag":767,"props":5670,"children":5671},{"style":1121},[5672],{"type":48,"value":3322},{"type":42,"tag":767,"props":5674,"children":5675},{"style":774},[5676],{"type":48,"value":1229},{"type":42,"tag":767,"props":5678,"children":5679},{"style":1121},[5680],{"type":48,"value":1234},{"type":42,"tag":767,"props":5682,"children":5683},{"style":774},[5684],{"type":48,"value":1216},{"type":42,"tag":767,"props":5686,"children":5687},{"style":1102},[5688],{"type":48,"value":5689}," \u002F\u002F required, even if empty\n",{"type":42,"tag":767,"props":5691,"children":5692},{"class":769,"line":1019},[5693,5698,5702,5706,5710,5714,5718],{"type":42,"tag":767,"props":5694,"children":5695},{"style":1192},[5696],{"type":48,"value":5697},"  outputSchema",{"type":42,"tag":767,"props":5699,"children":5700},{"style":774},[5701],{"type":48,"value":802},{"type":42,"tag":767,"props":5703,"children":5704},{"style":1121},[5705],{"type":48,"value":5507},{"type":42,"tag":767,"props":5707,"children":5708},{"style":774},[5709],{"type":48,"value":1790},{"type":42,"tag":767,"props":5711,"children":5712},{"style":1175},[5713],{"type":48,"value":5615},{"type":42,"tag":767,"props":5715,"children":5716},{"style":1121},[5717],{"type":48,"value":1182},{"type":42,"tag":767,"props":5719,"children":5720},{"style":774},[5721],{"type":48,"value":777},{"type":42,"tag":767,"props":5723,"children":5724},{"class":769,"line":1028},[5725,5730,5734,5738,5742,5746,5750],{"type":42,"tag":767,"props":5726,"children":5727},{"style":1192},[5728],{"type":48,"value":5729},"    city",{"type":42,"tag":767,"props":5731,"children":5732},{"style":774},[5733],{"type":48,"value":802},{"type":42,"tag":767,"props":5735,"children":5736},{"style":1121},[5737],{"type":48,"value":5507},{"type":42,"tag":767,"props":5739,"children":5740},{"style":774},[5741],{"type":48,"value":1790},{"type":42,"tag":767,"props":5743,"children":5744},{"style":1175},[5745],{"type":48,"value":5645},{"type":42,"tag":767,"props":5747,"children":5748},{"style":1121},[5749],{"type":48,"value":5650},{"type":42,"tag":767,"props":5751,"children":5752},{"style":774},[5753],{"type":48,"value":909},{"type":42,"tag":767,"props":5755,"children":5756},{"class":769,"line":1886},[5757,5762,5766,5770,5774,5778,5782],{"type":42,"tag":767,"props":5758,"children":5759},{"style":1192},[5760],{"type":48,"value":5761},"    condition",{"type":42,"tag":767,"props":5763,"children":5764},{"style":774},[5765],{"type":48,"value":802},{"type":42,"tag":767,"props":5767,"children":5768},{"style":1121},[5769],{"type":48,"value":5507},{"type":42,"tag":767,"props":5771,"children":5772},{"style":774},[5773],{"type":48,"value":1790},{"type":42,"tag":767,"props":5775,"children":5776},{"style":1175},[5777],{"type":48,"value":5645},{"type":42,"tag":767,"props":5779,"children":5780},{"style":1121},[5781],{"type":48,"value":5650},{"type":42,"tag":767,"props":5783,"children":5784},{"style":774},[5785],{"type":48,"value":909},{"type":42,"tag":767,"props":5787,"children":5788},{"class":769,"line":1948},[5789,5794,5798,5802,5806,5811,5815],{"type":42,"tag":767,"props":5790,"children":5791},{"style":1192},[5792],{"type":48,"value":5793},"    temperatureF",{"type":42,"tag":767,"props":5795,"children":5796},{"style":774},[5797],{"type":48,"value":802},{"type":42,"tag":767,"props":5799,"children":5800},{"style":1121},[5801],{"type":48,"value":5507},{"type":42,"tag":767,"props":5803,"children":5804},{"style":774},[5805],{"type":48,"value":1790},{"type":42,"tag":767,"props":5807,"children":5808},{"style":1175},[5809],{"type":48,"value":5810},"number",{"type":42,"tag":767,"props":5812,"children":5813},{"style":1121},[5814],{"type":48,"value":5650},{"type":42,"tag":767,"props":5816,"children":5817},{"style":774},[5818],{"type":48,"value":909},{"type":42,"tag":767,"props":5820,"children":5821},{"class":769,"line":1964},[5822,5826,5830,5834],{"type":42,"tag":767,"props":5823,"children":5824},{"style":774},[5825],{"type":48,"value":1828},{"type":42,"tag":767,"props":5827,"children":5828},{"style":1121},[5829],{"type":48,"value":1234},{"type":42,"tag":767,"props":5831,"children":5832},{"style":774},[5833],{"type":48,"value":1216},{"type":42,"tag":767,"props":5835,"children":5836},{"style":1102},[5837],{"type":48,"value":5838}," \u002F\u002F optional — types\u002Fvalidates the return\n",{"type":42,"tag":767,"props":5840,"children":5841},{"class":769,"line":2965},[5842,5846,5851,5856,5860,5864,5868,5872],{"type":42,"tag":767,"props":5843,"children":5844},{"style":789},[5845],{"type":48,"value":2750},{"type":42,"tag":767,"props":5847,"children":5848},{"style":1192},[5849],{"type":48,"value":5850}," execute",{"type":42,"tag":767,"props":5852,"children":5853},{"style":774},[5854],{"type":48,"value":5855},"({",{"type":42,"tag":767,"props":5857,"children":5858},{"style":2762},[5859],{"type":48,"value":5628},{"type":42,"tag":767,"props":5861,"children":5862},{"style":774},[5863],{"type":48,"value":4724},{"type":42,"tag":767,"props":5865,"children":5866},{"style":2762},[5867],{"type":48,"value":2854},{"type":42,"tag":767,"props":5869,"children":5870},{"style":774},[5871],{"type":48,"value":1234},{"type":42,"tag":767,"props":5873,"children":5874},{"style":774},[5875],{"type":48,"value":870},{"type":42,"tag":767,"props":5877,"children":5878},{"class":769,"line":2973},[5879,5883,5887,5891,5895,5900,5904,5908,5913,5917,5921,5926,5930,5935],{"type":42,"tag":767,"props":5880,"children":5881},{"style":1111},[5882],{"type":48,"value":2836},{"type":42,"tag":767,"props":5884,"children":5885},{"style":774},[5886],{"type":48,"value":807},{"type":42,"tag":767,"props":5888,"children":5889},{"style":1121},[5890],{"type":48,"value":5628},{"type":42,"tag":767,"props":5892,"children":5893},{"style":774},[5894],{"type":48,"value":1216},{"type":42,"tag":767,"props":5896,"children":5897},{"style":1192},[5898],{"type":48,"value":5899}," condition",{"type":42,"tag":767,"props":5901,"children":5902},{"style":774},[5903],{"type":48,"value":802},{"type":42,"tag":767,"props":5905,"children":5906},{"style":774},[5907],{"type":48,"value":812},{"type":42,"tag":767,"props":5909,"children":5910},{"style":833},[5911],{"type":48,"value":5912},"Sunny",{"type":42,"tag":767,"props":5914,"children":5915},{"style":774},[5916],{"type":48,"value":797},{"type":42,"tag":767,"props":5918,"children":5919},{"style":774},[5920],{"type":48,"value":1216},{"type":42,"tag":767,"props":5922,"children":5923},{"style":1192},[5924],{"type":48,"value":5925}," temperatureF",{"type":42,"tag":767,"props":5927,"children":5928},{"style":774},[5929],{"type":48,"value":802},{"type":42,"tag":767,"props":5931,"children":5932},{"style":4740},[5933],{"type":48,"value":5934}," 72",{"type":42,"tag":767,"props":5936,"children":5937},{"style":774},[5938],{"type":48,"value":2868},{"type":42,"tag":767,"props":5940,"children":5941},{"class":769,"line":2981},[5942],{"type":42,"tag":767,"props":5943,"children":5944},{"style":774},[5945],{"type":48,"value":2876},{"type":42,"tag":767,"props":5947,"children":5948},{"class":769,"line":2990},[5949,5953,5957],{"type":42,"tag":767,"props":5950,"children":5951},{"style":774},[5952],{"type":48,"value":1229},{"type":42,"tag":767,"props":5954,"children":5955},{"style":1121},[5956],{"type":48,"value":1234},{"type":42,"tag":767,"props":5958,"children":5959},{"style":774},[5960],{"type":48,"value":1151},{"type":42,"tag":51,"props":5962,"children":5963},{},[5964],{"type":48,"value":5965},"Rules and capabilities:",{"type":42,"tag":72,"props":5967,"children":5968},{},[5969,5987,6005,6017],{"type":42,"tag":76,"props":5970,"children":5971},{},[5972,5974,5985],{"type":48,"value":5973},"Tools run ",{"type":42,"tag":57,"props":5975,"children":5976},{},[5977,5979],{"type":48,"value":5978},"in your app runtime with full ",{"type":42,"tag":86,"props":5980,"children":5982},{"className":5981},[],[5983],{"type":48,"value":5984},"process.env",{"type":48,"value":5986},", not in the sandbox",{"type":42,"tag":76,"props":5988,"children":5989},{},[5990,5996,5998,6003],{"type":42,"tag":86,"props":5991,"children":5993},{"className":5992},[],[5994],{"type":48,"value":5995},"inputSchema",{"type":48,"value":5997}," accepts Zod, Standard Schema, or JSON Schema — but it is ",{"type":42,"tag":57,"props":5999,"children":6000},{},[6001],{"type":48,"value":6002},"required",{"type":48,"value":6004}," even for zero-input tools",{"type":42,"tag":76,"props":6006,"children":6007},{},[6008,6010,6015],{"type":48,"value":6009},"Outputs must be JSON-serializable; ",{"type":42,"tag":57,"props":6011,"children":6012},{},[6013],{"type":48,"value":6014},"filter\u002Fredact secrets",{"type":48,"value":6016}," before returning",{"type":42,"tag":76,"props":6018,"children":6019},{},[6020,6025,6027,6033,6035,6041,6042,6048,6049,6055,6056,6062,6063],{"type":42,"tag":86,"props":6021,"children":6023},{"className":6022},[],[6024],{"type":48,"value":2765},{"type":48,"value":6026}," provides ",{"type":42,"tag":86,"props":6028,"children":6030},{"className":6029},[],[6031],{"type":48,"value":6032},"ctx.session",{"type":48,"value":6034}," (metadata, turn, auth, lineage), ",{"type":42,"tag":86,"props":6036,"children":6038},{"className":6037},[],[6039],{"type":48,"value":6040},"ctx.callId",{"type":48,"value":2004},{"type":42,"tag":86,"props":6043,"children":6045},{"className":6044},[],[6046],{"type":48,"value":6047},"ctx.toolName",{"type":48,"value":2004},{"type":42,"tag":86,"props":6050,"children":6052},{"className":6051},[],[6053],{"type":48,"value":6054},"ctx.abortSignal",{"type":48,"value":2004},{"type":42,"tag":86,"props":6057,"children":6059},{"className":6058},[],[6060],{"type":48,"value":6061},"ctx.getSandbox()",{"type":48,"value":2004},{"type":42,"tag":86,"props":6064,"children":6066},{"className":6065},[],[6067],{"type":48,"value":6068},"ctx.getSkill(id)",{"type":42,"tag":6070,"props":6071,"children":6073},"h4",{"id":6072},"approval-gating",[6074],{"type":48,"value":6075},"Approval Gating",{"type":42,"tag":51,"props":6077,"children":6078},{},[6079,6081,6087,6089,6095],{"type":48,"value":6080},"Gate risky tools with the ",{"type":42,"tag":86,"props":6082,"children":6084},{"className":6083},[],[6085],{"type":48,"value":6086},"approval",{"type":48,"value":6088}," field — helpers come from ",{"type":42,"tag":86,"props":6090,"children":6092},{"className":6091},[],[6093],{"type":48,"value":6094},"eve\u002Ftools\u002Fapproval",{"type":48,"value":802},{"type":42,"tag":756,"props":6097,"children":6099},{"className":1090,"code":6098,"language":1092,"meta":761,"style":761},"import { defineTool } from \"eve\u002Ftools\";\nimport { always, once, never } from \"eve\u002Ftools\u002Fapproval\";\nimport { z } from \"zod\";\n\nexport default defineTool({\n  description: \"Delete a document permanently.\",\n  inputSchema: z.object({ documentId: z.string() }),\n  approval: always(), \u002F\u002F always ask; once() asks the first time; never() skips\n  async execute({ documentId }) {\n    \u002F\u002F ...\n  },\n});\n",[6100],{"type":42,"tag":86,"props":6101,"children":6102},{"__ignoreMap":761},[6103,6142,6200,6239,6246,6269,6297,6366,6395,6423,6431,6438],{"type":42,"tag":767,"props":6104,"children":6105},{"class":769,"line":770},[6106,6110,6114,6118,6122,6126,6130,6134,6138],{"type":42,"tag":767,"props":6107,"children":6108},{"style":1111},[6109],{"type":48,"value":1114},{"type":42,"tag":767,"props":6111,"children":6112},{"style":774},[6113],{"type":48,"value":807},{"type":42,"tag":767,"props":6115,"children":6116},{"style":1121},[6117],{"type":48,"value":5466},{"type":42,"tag":767,"props":6119,"children":6120},{"style":774},[6121],{"type":48,"value":1129},{"type":42,"tag":767,"props":6123,"children":6124},{"style":1111},[6125],{"type":48,"value":1134},{"type":42,"tag":767,"props":6127,"children":6128},{"style":774},[6129],{"type":48,"value":812},{"type":42,"tag":767,"props":6131,"children":6132},{"style":833},[6133],{"type":48,"value":5483},{"type":42,"tag":767,"props":6135,"children":6136},{"style":774},[6137],{"type":48,"value":797},{"type":42,"tag":767,"props":6139,"children":6140},{"style":774},[6141],{"type":48,"value":1151},{"type":42,"tag":767,"props":6143,"children":6144},{"class":769,"line":780},[6145,6149,6153,6158,6162,6167,6171,6176,6180,6184,6188,6192,6196],{"type":42,"tag":767,"props":6146,"children":6147},{"style":1111},[6148],{"type":48,"value":1114},{"type":42,"tag":767,"props":6150,"children":6151},{"style":774},[6152],{"type":48,"value":807},{"type":42,"tag":767,"props":6154,"children":6155},{"style":1121},[6156],{"type":48,"value":6157}," always",{"type":42,"tag":767,"props":6159,"children":6160},{"style":774},[6161],{"type":48,"value":1216},{"type":42,"tag":767,"props":6163,"children":6164},{"style":1121},[6165],{"type":48,"value":6166}," once",{"type":42,"tag":767,"props":6168,"children":6169},{"style":774},[6170],{"type":48,"value":1216},{"type":42,"tag":767,"props":6172,"children":6173},{"style":1121},[6174],{"type":48,"value":6175}," never",{"type":42,"tag":767,"props":6177,"children":6178},{"style":774},[6179],{"type":48,"value":1129},{"type":42,"tag":767,"props":6181,"children":6182},{"style":1111},[6183],{"type":48,"value":1134},{"type":42,"tag":767,"props":6185,"children":6186},{"style":774},[6187],{"type":48,"value":812},{"type":42,"tag":767,"props":6189,"children":6190},{"style":833},[6191],{"type":48,"value":6094},{"type":42,"tag":767,"props":6193,"children":6194},{"style":774},[6195],{"type":48,"value":797},{"type":42,"tag":767,"props":6197,"children":6198},{"style":774},[6199],{"type":48,"value":1151},{"type":42,"tag":767,"props":6201,"children":6202},{"class":769,"line":26},[6203,6207,6211,6215,6219,6223,6227,6231,6235],{"type":42,"tag":767,"props":6204,"children":6205},{"style":1111},[6206],{"type":48,"value":1114},{"type":42,"tag":767,"props":6208,"children":6209},{"style":774},[6210],{"type":48,"value":807},{"type":42,"tag":767,"props":6212,"children":6213},{"style":1121},[6214],{"type":48,"value":5507},{"type":42,"tag":767,"props":6216,"children":6217},{"style":774},[6218],{"type":48,"value":1129},{"type":42,"tag":767,"props":6220,"children":6221},{"style":1111},[6222],{"type":48,"value":1134},{"type":42,"tag":767,"props":6224,"children":6225},{"style":774},[6226],{"type":48,"value":812},{"type":42,"tag":767,"props":6228,"children":6229},{"style":833},[6230],{"type":48,"value":717},{"type":42,"tag":767,"props":6232,"children":6233},{"style":774},[6234],{"type":48,"value":797},{"type":42,"tag":767,"props":6236,"children":6237},{"style":774},[6238],{"type":48,"value":1151},{"type":42,"tag":767,"props":6240,"children":6241},{"class":769,"line":873},[6242],{"type":42,"tag":767,"props":6243,"children":6244},{"emptyLinePlaceholder":37},[6245],{"type":48,"value":1159},{"type":42,"tag":767,"props":6247,"children":6248},{"class":769,"line":912},[6249,6253,6257,6261,6265],{"type":42,"tag":767,"props":6250,"children":6251},{"style":1111},[6252],{"type":48,"value":1167},{"type":42,"tag":767,"props":6254,"children":6255},{"style":1111},[6256],{"type":48,"value":1172},{"type":42,"tag":767,"props":6258,"children":6259},{"style":1175},[6260],{"type":48,"value":5466},{"type":42,"tag":767,"props":6262,"children":6263},{"style":1121},[6264],{"type":48,"value":1182},{"type":42,"tag":767,"props":6266,"children":6267},{"style":774},[6268],{"type":48,"value":777},{"type":42,"tag":767,"props":6270,"children":6271},{"class":769,"line":949},[6272,6276,6280,6284,6289,6293],{"type":42,"tag":767,"props":6273,"children":6274},{"style":1192},[6275],{"type":48,"value":5569},{"type":42,"tag":767,"props":6277,"children":6278},{"style":774},[6279],{"type":48,"value":802},{"type":42,"tag":767,"props":6281,"children":6282},{"style":774},[6283],{"type":48,"value":812},{"type":42,"tag":767,"props":6285,"children":6286},{"style":833},[6287],{"type":48,"value":6288},"Delete a document permanently.",{"type":42,"tag":767,"props":6290,"children":6291},{"style":774},[6292],{"type":48,"value":797},{"type":42,"tag":767,"props":6294,"children":6295},{"style":774},[6296],{"type":48,"value":909},{"type":42,"tag":767,"props":6298,"children":6299},{"class":769,"line":986},[6300,6304,6308,6312,6316,6320,6324,6328,6333,6337,6341,6345,6349,6354,6358,6362],{"type":42,"tag":767,"props":6301,"children":6302},{"style":1192},[6303],{"type":48,"value":5598},{"type":42,"tag":767,"props":6305,"children":6306},{"style":774},[6307],{"type":48,"value":802},{"type":42,"tag":767,"props":6309,"children":6310},{"style":1121},[6311],{"type":48,"value":5507},{"type":42,"tag":767,"props":6313,"children":6314},{"style":774},[6315],{"type":48,"value":1790},{"type":42,"tag":767,"props":6317,"children":6318},{"style":1175},[6319],{"type":48,"value":5615},{"type":42,"tag":767,"props":6321,"children":6322},{"style":1121},[6323],{"type":48,"value":1182},{"type":42,"tag":767,"props":6325,"children":6326},{"style":774},[6327],{"type":48,"value":4697},{"type":42,"tag":767,"props":6329,"children":6330},{"style":1192},[6331],{"type":48,"value":6332}," documentId",{"type":42,"tag":767,"props":6334,"children":6335},{"style":774},[6336],{"type":48,"value":802},{"type":42,"tag":767,"props":6338,"children":6339},{"style":1121},[6340],{"type":48,"value":5507},{"type":42,"tag":767,"props":6342,"children":6343},{"style":774},[6344],{"type":48,"value":1790},{"type":42,"tag":767,"props":6346,"children":6347},{"style":1175},[6348],{"type":48,"value":5645},{"type":42,"tag":767,"props":6350,"children":6351},{"style":1121},[6352],{"type":48,"value":6353},"() ",{"type":42,"tag":767,"props":6355,"children":6356},{"style":774},[6357],{"type":48,"value":1229},{"type":42,"tag":767,"props":6359,"children":6360},{"style":1121},[6361],{"type":48,"value":1234},{"type":42,"tag":767,"props":6363,"children":6364},{"style":774},[6365],{"type":48,"value":909},{"type":42,"tag":767,"props":6367,"children":6368},{"class":769,"line":1019},[6369,6374,6378,6382,6386,6390],{"type":42,"tag":767,"props":6370,"children":6371},{"style":1192},[6372],{"type":48,"value":6373},"  approval",{"type":42,"tag":767,"props":6375,"children":6376},{"style":774},[6377],{"type":48,"value":802},{"type":42,"tag":767,"props":6379,"children":6380},{"style":1175},[6381],{"type":48,"value":6157},{"type":42,"tag":767,"props":6383,"children":6384},{"style":1121},[6385],{"type":48,"value":5650},{"type":42,"tag":767,"props":6387,"children":6388},{"style":774},[6389],{"type":48,"value":1216},{"type":42,"tag":767,"props":6391,"children":6392},{"style":1102},[6393],{"type":48,"value":6394}," \u002F\u002F always ask; once() asks the first time; never() skips\n",{"type":42,"tag":767,"props":6396,"children":6397},{"class":769,"line":1028},[6398,6402,6406,6410,6414,6419],{"type":42,"tag":767,"props":6399,"children":6400},{"style":789},[6401],{"type":48,"value":2750},{"type":42,"tag":767,"props":6403,"children":6404},{"style":1192},[6405],{"type":48,"value":5850},{"type":42,"tag":767,"props":6407,"children":6408},{"style":774},[6409],{"type":48,"value":5855},{"type":42,"tag":767,"props":6411,"children":6412},{"style":2762},[6413],{"type":48,"value":6332},{"type":42,"tag":767,"props":6415,"children":6416},{"style":774},[6417],{"type":48,"value":6418}," })",{"type":42,"tag":767,"props":6420,"children":6421},{"style":774},[6422],{"type":48,"value":870},{"type":42,"tag":767,"props":6424,"children":6425},{"class":769,"line":1886},[6426],{"type":42,"tag":767,"props":6427,"children":6428},{"style":1102},[6429],{"type":48,"value":6430},"    \u002F\u002F ...\n",{"type":42,"tag":767,"props":6432,"children":6433},{"class":769,"line":1948},[6434],{"type":42,"tag":767,"props":6435,"children":6436},{"style":774},[6437],{"type":48,"value":2876},{"type":42,"tag":767,"props":6439,"children":6440},{"class":769,"line":1964},[6441,6445,6449],{"type":42,"tag":767,"props":6442,"children":6443},{"style":774},[6444],{"type":48,"value":1229},{"type":42,"tag":767,"props":6446,"children":6447},{"style":1121},[6448],{"type":48,"value":1234},{"type":42,"tag":767,"props":6450,"children":6451},{"style":774},[6452],{"type":48,"value":1151},{"type":42,"tag":51,"props":6454,"children":6455},{},[6456,6458,6463],{"type":48,"value":6457},"An input-dependent policy function is also supported. A gated call ",{"type":42,"tag":57,"props":6459,"children":6460},{},[6461],{"type":48,"value":6462},"pauses and resumes durably",{"type":48,"value":6464}," — in Slack, the approval renders as buttons (see HITL above). Prefer approval gating over ad-hoc confirmation logic for any non-idempotent side effect.",{"type":42,"tag":6070,"props":6466,"children":6468},{"id":6467},"tomodeloutput-rich-slack-output-the-model-never-sees",[6469,6475],{"type":42,"tag":86,"props":6470,"children":6472},{"className":6471},[],[6473],{"type":48,"value":6474},"toModelOutput",{"type":48,"value":6476}," — Rich Slack Output the Model Never Sees",{"type":42,"tag":51,"props":6478,"children":6479},{},[6480,6482,6487],{"type":48,"value":6481},"Show the model a compact projection while channels\u002Fhooks receive the full output on ",{"type":42,"tag":86,"props":6483,"children":6485},{"className":6484},[],[6486],{"type":48,"value":3459},{"type":48,"value":6488}," — ideal for rendering rich Slack Block Kit from a tool result without stuffing JSON blocks into the model's context:",{"type":42,"tag":756,"props":6490,"children":6492},{"className":1090,"code":6491,"language":1092,"meta":761,"style":761},"export default defineTool({\n  description: \"Look up an order.\",\n  inputSchema: z.object({ orderId: z.string() }),\n  async execute({ orderId }) {\n    return { orderId, status: \"shipped\", blocks: buildOrderBlocks(orderId) };\n  },\n  toModelOutput(output) {\n    return { type: \"text\", value: `Order ${output.orderId}: ${output.status}` };\n  },\n});\n",[6493],{"type":42,"tag":86,"props":6494,"children":6495},{"__ignoreMap":761},[6496,6519,6547,6615,6642,6718,6725,6750,6853,6860],{"type":42,"tag":767,"props":6497,"children":6498},{"class":769,"line":770},[6499,6503,6507,6511,6515],{"type":42,"tag":767,"props":6500,"children":6501},{"style":1111},[6502],{"type":48,"value":1167},{"type":42,"tag":767,"props":6504,"children":6505},{"style":1111},[6506],{"type":48,"value":1172},{"type":42,"tag":767,"props":6508,"children":6509},{"style":1175},[6510],{"type":48,"value":5466},{"type":42,"tag":767,"props":6512,"children":6513},{"style":1121},[6514],{"type":48,"value":1182},{"type":42,"tag":767,"props":6516,"children":6517},{"style":774},[6518],{"type":48,"value":777},{"type":42,"tag":767,"props":6520,"children":6521},{"class":769,"line":780},[6522,6526,6530,6534,6539,6543],{"type":42,"tag":767,"props":6523,"children":6524},{"style":1192},[6525],{"type":48,"value":5569},{"type":42,"tag":767,"props":6527,"children":6528},{"style":774},[6529],{"type":48,"value":802},{"type":42,"tag":767,"props":6531,"children":6532},{"style":774},[6533],{"type":48,"value":812},{"type":42,"tag":767,"props":6535,"children":6536},{"style":833},[6537],{"type":48,"value":6538},"Look up an order.",{"type":42,"tag":767,"props":6540,"children":6541},{"style":774},[6542],{"type":48,"value":797},{"type":42,"tag":767,"props":6544,"children":6545},{"style":774},[6546],{"type":48,"value":909},{"type":42,"tag":767,"props":6548,"children":6549},{"class":769,"line":26},[6550,6554,6558,6562,6566,6570,6574,6578,6583,6587,6591,6595,6599,6603,6607,6611],{"type":42,"tag":767,"props":6551,"children":6552},{"style":1192},[6553],{"type":48,"value":5598},{"type":42,"tag":767,"props":6555,"children":6556},{"style":774},[6557],{"type":48,"value":802},{"type":42,"tag":767,"props":6559,"children":6560},{"style":1121},[6561],{"type":48,"value":5507},{"type":42,"tag":767,"props":6563,"children":6564},{"style":774},[6565],{"type":48,"value":1790},{"type":42,"tag":767,"props":6567,"children":6568},{"style":1175},[6569],{"type":48,"value":5615},{"type":42,"tag":767,"props":6571,"children":6572},{"style":1121},[6573],{"type":48,"value":1182},{"type":42,"tag":767,"props":6575,"children":6576},{"style":774},[6577],{"type":48,"value":4697},{"type":42,"tag":767,"props":6579,"children":6580},{"style":1192},[6581],{"type":48,"value":6582}," orderId",{"type":42,"tag":767,"props":6584,"children":6585},{"style":774},[6586],{"type":48,"value":802},{"type":42,"tag":767,"props":6588,"children":6589},{"style":1121},[6590],{"type":48,"value":5507},{"type":42,"tag":767,"props":6592,"children":6593},{"style":774},[6594],{"type":48,"value":1790},{"type":42,"tag":767,"props":6596,"children":6597},{"style":1175},[6598],{"type":48,"value":5645},{"type":42,"tag":767,"props":6600,"children":6601},{"style":1121},[6602],{"type":48,"value":6353},{"type":42,"tag":767,"props":6604,"children":6605},{"style":774},[6606],{"type":48,"value":1229},{"type":42,"tag":767,"props":6608,"children":6609},{"style":1121},[6610],{"type":48,"value":1234},{"type":42,"tag":767,"props":6612,"children":6613},{"style":774},[6614],{"type":48,"value":909},{"type":42,"tag":767,"props":6616,"children":6617},{"class":769,"line":873},[6618,6622,6626,6630,6634,6638],{"type":42,"tag":767,"props":6619,"children":6620},{"style":789},[6621],{"type":48,"value":2750},{"type":42,"tag":767,"props":6623,"children":6624},{"style":1192},[6625],{"type":48,"value":5850},{"type":42,"tag":767,"props":6627,"children":6628},{"style":774},[6629],{"type":48,"value":5855},{"type":42,"tag":767,"props":6631,"children":6632},{"style":2762},[6633],{"type":48,"value":6582},{"type":42,"tag":767,"props":6635,"children":6636},{"style":774},[6637],{"type":48,"value":6418},{"type":42,"tag":767,"props":6639,"children":6640},{"style":774},[6641],{"type":48,"value":870},{"type":42,"tag":767,"props":6643,"children":6644},{"class":769,"line":912},[6645,6649,6653,6657,6661,6665,6669,6673,6678,6682,6686,6691,6695,6700,6704,6709,6713],{"type":42,"tag":767,"props":6646,"children":6647},{"style":1111},[6648],{"type":48,"value":2836},{"type":42,"tag":767,"props":6650,"children":6651},{"style":774},[6652],{"type":48,"value":807},{"type":42,"tag":767,"props":6654,"children":6655},{"style":1121},[6656],{"type":48,"value":6582},{"type":42,"tag":767,"props":6658,"children":6659},{"style":774},[6660],{"type":48,"value":1216},{"type":42,"tag":767,"props":6662,"children":6663},{"style":1192},[6664],{"type":48,"value":4733},{"type":42,"tag":767,"props":6666,"children":6667},{"style":774},[6668],{"type":48,"value":802},{"type":42,"tag":767,"props":6670,"children":6671},{"style":774},[6672],{"type":48,"value":812},{"type":42,"tag":767,"props":6674,"children":6675},{"style":833},[6676],{"type":48,"value":6677},"shipped",{"type":42,"tag":767,"props":6679,"children":6680},{"style":774},[6681],{"type":48,"value":797},{"type":42,"tag":767,"props":6683,"children":6684},{"style":774},[6685],{"type":48,"value":1216},{"type":42,"tag":767,"props":6687,"children":6688},{"style":1192},[6689],{"type":48,"value":6690}," blocks",{"type":42,"tag":767,"props":6692,"children":6693},{"style":774},[6694],{"type":48,"value":802},{"type":42,"tag":767,"props":6696,"children":6697},{"style":1175},[6698],{"type":48,"value":6699}," buildOrderBlocks",{"type":42,"tag":767,"props":6701,"children":6702},{"style":1192},[6703],{"type":48,"value":1182},{"type":42,"tag":767,"props":6705,"children":6706},{"style":1121},[6707],{"type":48,"value":6708},"orderId",{"type":42,"tag":767,"props":6710,"children":6711},{"style":1192},[6712],{"type":48,"value":3322},{"type":42,"tag":767,"props":6714,"children":6715},{"style":774},[6716],{"type":48,"value":6717},"};\n",{"type":42,"tag":767,"props":6719,"children":6720},{"class":769,"line":949},[6721],{"type":42,"tag":767,"props":6722,"children":6723},{"style":774},[6724],{"type":48,"value":2876},{"type":42,"tag":767,"props":6726,"children":6727},{"class":769,"line":986},[6728,6733,6737,6742,6746],{"type":42,"tag":767,"props":6729,"children":6730},{"style":1192},[6731],{"type":48,"value":6732},"  toModelOutput",{"type":42,"tag":767,"props":6734,"children":6735},{"style":774},[6736],{"type":48,"value":1182},{"type":42,"tag":767,"props":6738,"children":6739},{"style":2762},[6740],{"type":48,"value":6741},"output",{"type":42,"tag":767,"props":6743,"children":6744},{"style":774},[6745],{"type":48,"value":1234},{"type":42,"tag":767,"props":6747,"children":6748},{"style":774},[6749],{"type":48,"value":870},{"type":42,"tag":767,"props":6751,"children":6752},{"class":769,"line":1019},[6753,6757,6761,6766,6770,6774,6778,6782,6786,6791,6795,6799,6804,6808,6812,6816,6820,6824,6828,6832,6836,6840,6845,6849],{"type":42,"tag":767,"props":6754,"children":6755},{"style":1111},[6756],{"type":48,"value":2836},{"type":42,"tag":767,"props":6758,"children":6759},{"style":774},[6760],{"type":48,"value":807},{"type":42,"tag":767,"props":6762,"children":6763},{"style":1192},[6764],{"type":48,"value":6765}," type",{"type":42,"tag":767,"props":6767,"children":6768},{"style":774},[6769],{"type":48,"value":802},{"type":42,"tag":767,"props":6771,"children":6772},{"style":774},[6773],{"type":48,"value":812},{"type":42,"tag":767,"props":6775,"children":6776},{"style":833},[6777],{"type":48,"value":48},{"type":42,"tag":767,"props":6779,"children":6780},{"style":774},[6781],{"type":48,"value":797},{"type":42,"tag":767,"props":6783,"children":6784},{"style":774},[6785],{"type":48,"value":1216},{"type":42,"tag":767,"props":6787,"children":6788},{"style":1192},[6789],{"type":48,"value":6790}," value",{"type":42,"tag":767,"props":6792,"children":6793},{"style":774},[6794],{"type":48,"value":802},{"type":42,"tag":767,"props":6796,"children":6797},{"style":774},[6798],{"type":48,"value":4624},{"type":42,"tag":767,"props":6800,"children":6801},{"style":833},[6802],{"type":48,"value":6803},"Order ",{"type":42,"tag":767,"props":6805,"children":6806},{"style":774},[6807],{"type":48,"value":4634},{"type":42,"tag":767,"props":6809,"children":6810},{"style":1121},[6811],{"type":48,"value":6741},{"type":42,"tag":767,"props":6813,"children":6814},{"style":774},[6815],{"type":48,"value":1790},{"type":42,"tag":767,"props":6817,"children":6818},{"style":1121},[6819],{"type":48,"value":6708},{"type":42,"tag":767,"props":6821,"children":6822},{"style":774},[6823],{"type":48,"value":1229},{"type":42,"tag":767,"props":6825,"children":6826},{"style":833},[6827],{"type":48,"value":678},{"type":42,"tag":767,"props":6829,"children":6830},{"style":774},[6831],{"type":48,"value":4634},{"type":42,"tag":767,"props":6833,"children":6834},{"style":1121},[6835],{"type":48,"value":6741},{"type":42,"tag":767,"props":6837,"children":6838},{"style":774},[6839],{"type":48,"value":1790},{"type":42,"tag":767,"props":6841,"children":6842},{"style":1121},[6843],{"type":48,"value":6844},"status",{"type":42,"tag":767,"props":6846,"children":6847},{"style":774},[6848],{"type":48,"value":4660},{"type":42,"tag":767,"props":6850,"children":6851},{"style":774},[6852],{"type":48,"value":2868},{"type":42,"tag":767,"props":6854,"children":6855},{"class":769,"line":1028},[6856],{"type":42,"tag":767,"props":6857,"children":6858},{"style":774},[6859],{"type":48,"value":2876},{"type":42,"tag":767,"props":6861,"children":6862},{"class":769,"line":1886},[6863,6867,6871],{"type":42,"tag":767,"props":6864,"children":6865},{"style":774},[6866],{"type":48,"value":1229},{"type":42,"tag":767,"props":6868,"children":6869},{"style":1121},[6870],{"type":48,"value":1234},{"type":42,"tag":767,"props":6872,"children":6873},{"style":774},[6874],{"type":48,"value":1151},{"type":42,"tag":124,"props":6876,"children":6878},{"id":6877},"skills-agentskillsmd",[6879,6881,6887],{"type":48,"value":6880},"Skills (",{"type":42,"tag":86,"props":6882,"children":6884},{"className":6883},[],[6885],{"type":48,"value":6886},"agent\u002Fskills\u002F*.md",{"type":48,"value":1234},{"type":42,"tag":51,"props":6889,"children":6890},{},[6891,6893,6899,6901,6907,6909,6914,6916,6922],{"type":48,"value":6892},"Markdown files with a ",{"type":42,"tag":86,"props":6894,"children":6896},{"className":6895},[],[6897],{"type":48,"value":6898},"description",{"type":48,"value":6900}," frontmatter, loaded on demand via the built-in ",{"type":42,"tag":86,"props":6902,"children":6904},{"className":6903},[],[6905],{"type":48,"value":6906},"load_skill",{"type":48,"value":6908}," tool when a request matches the description. Skills add ",{"type":42,"tag":57,"props":6910,"children":6911},{},[6912],{"type":48,"value":6913},"instructions only, never new actions",{"type":48,"value":6915},". Install published skills with ",{"type":42,"tag":86,"props":6917,"children":6919},{"className":6918},[],[6920],{"type":48,"value":6921},"npx skills add \u003Cowner>\u002F\u003Crepo>",{"type":48,"value":1790},{"type":42,"tag":124,"props":6924,"children":6926},{"id":6925},"connections-agentconnectionsts",[6927,6929,6935],{"type":48,"value":6928},"Connections (",{"type":42,"tag":86,"props":6930,"children":6932},{"className":6931},[],[6933],{"type":48,"value":6934},"agent\u002Fconnections\u002F*.ts",{"type":48,"value":1234},{"type":42,"tag":51,"props":6937,"children":6938},{},[6939],{"type":48,"value":6940},"For external APIs the agent should drive (MCP servers or OpenAPI-described HTTP APIs), use connections with Connect-brokered auth:",{"type":42,"tag":756,"props":6942,"children":6944},{"className":1090,"code":6943,"language":1092,"meta":761,"style":761},"\u002F\u002F agent\u002Fconnections\u002Flinear.ts\nimport { connect } from \"@vercel\u002Fconnect\u002Feve\";\nimport { defineMcpClientConnection } from \"eve\u002Fconnections\";\n\nexport default defineMcpClientConnection({\n  url: \"https:\u002F\u002Fmcp.linear.app\u002Fmcp\",\n  description: \"Linear workspace: issues, projects, cycles, and comments.\",\n  auth: connect(\"linear\u002Fmy-agent\"),\n});\n",[6945],{"type":42,"tag":86,"props":6946,"children":6947},{"__ignoreMap":761},[6948,6956,6995,7036,7043,7066,7095,7123,7163],{"type":42,"tag":767,"props":6949,"children":6950},{"class":769,"line":770},[6951],{"type":42,"tag":767,"props":6952,"children":6953},{"style":1102},[6954],{"type":48,"value":6955},"\u002F\u002F agent\u002Fconnections\u002Flinear.ts\n",{"type":42,"tag":767,"props":6957,"children":6958},{"class":769,"line":780},[6959,6963,6967,6971,6975,6979,6983,6987,6991],{"type":42,"tag":767,"props":6960,"children":6961},{"style":1111},[6962],{"type":48,"value":1114},{"type":42,"tag":767,"props":6964,"children":6965},{"style":774},[6966],{"type":48,"value":807},{"type":42,"tag":767,"props":6968,"children":6969},{"style":1121},[6970],{"type":48,"value":2423},{"type":42,"tag":767,"props":6972,"children":6973},{"style":774},[6974],{"type":48,"value":1129},{"type":42,"tag":767,"props":6976,"children":6977},{"style":1111},[6978],{"type":48,"value":1134},{"type":42,"tag":767,"props":6980,"children":6981},{"style":774},[6982],{"type":48,"value":812},{"type":42,"tag":767,"props":6984,"children":6985},{"style":833},[6986],{"type":48,"value":2130},{"type":42,"tag":767,"props":6988,"children":6989},{"style":774},[6990],{"type":48,"value":797},{"type":42,"tag":767,"props":6992,"children":6993},{"style":774},[6994],{"type":48,"value":1151},{"type":42,"tag":767,"props":6996,"children":6997},{"class":769,"line":26},[6998,7002,7006,7011,7015,7019,7023,7028,7032],{"type":42,"tag":767,"props":6999,"children":7000},{"style":1111},[7001],{"type":48,"value":1114},{"type":42,"tag":767,"props":7003,"children":7004},{"style":774},[7005],{"type":48,"value":807},{"type":42,"tag":767,"props":7007,"children":7008},{"style":1121},[7009],{"type":48,"value":7010}," defineMcpClientConnection",{"type":42,"tag":767,"props":7012,"children":7013},{"style":774},[7014],{"type":48,"value":1129},{"type":42,"tag":767,"props":7016,"children":7017},{"style":1111},[7018],{"type":48,"value":1134},{"type":42,"tag":767,"props":7020,"children":7021},{"style":774},[7022],{"type":48,"value":812},{"type":42,"tag":767,"props":7024,"children":7025},{"style":833},[7026],{"type":48,"value":7027},"eve\u002Fconnections",{"type":42,"tag":767,"props":7029,"children":7030},{"style":774},[7031],{"type":48,"value":797},{"type":42,"tag":767,"props":7033,"children":7034},{"style":774},[7035],{"type":48,"value":1151},{"type":42,"tag":767,"props":7037,"children":7038},{"class":769,"line":873},[7039],{"type":42,"tag":767,"props":7040,"children":7041},{"emptyLinePlaceholder":37},[7042],{"type":48,"value":1159},{"type":42,"tag":767,"props":7044,"children":7045},{"class":769,"line":912},[7046,7050,7054,7058,7062],{"type":42,"tag":767,"props":7047,"children":7048},{"style":1111},[7049],{"type":48,"value":1167},{"type":42,"tag":767,"props":7051,"children":7052},{"style":1111},[7053],{"type":48,"value":1172},{"type":42,"tag":767,"props":7055,"children":7056},{"style":1175},[7057],{"type":48,"value":7010},{"type":42,"tag":767,"props":7059,"children":7060},{"style":1121},[7061],{"type":48,"value":1182},{"type":42,"tag":767,"props":7063,"children":7064},{"style":774},[7065],{"type":48,"value":777},{"type":42,"tag":767,"props":7067,"children":7068},{"class":769,"line":949},[7069,7074,7078,7082,7087,7091],{"type":42,"tag":767,"props":7070,"children":7071},{"style":1192},[7072],{"type":48,"value":7073},"  url",{"type":42,"tag":767,"props":7075,"children":7076},{"style":774},[7077],{"type":48,"value":802},{"type":42,"tag":767,"props":7079,"children":7080},{"style":774},[7081],{"type":48,"value":812},{"type":42,"tag":767,"props":7083,"children":7084},{"style":833},[7085],{"type":48,"value":7086},"https:\u002F\u002Fmcp.linear.app\u002Fmcp",{"type":42,"tag":767,"props":7088,"children":7089},{"style":774},[7090],{"type":48,"value":797},{"type":42,"tag":767,"props":7092,"children":7093},{"style":774},[7094],{"type":48,"value":909},{"type":42,"tag":767,"props":7096,"children":7097},{"class":769,"line":986},[7098,7102,7106,7110,7115,7119],{"type":42,"tag":767,"props":7099,"children":7100},{"style":1192},[7101],{"type":48,"value":5569},{"type":42,"tag":767,"props":7103,"children":7104},{"style":774},[7105],{"type":48,"value":802},{"type":42,"tag":767,"props":7107,"children":7108},{"style":774},[7109],{"type":48,"value":812},{"type":42,"tag":767,"props":7111,"children":7112},{"style":833},[7113],{"type":48,"value":7114},"Linear workspace: issues, projects, cycles, and comments.",{"type":42,"tag":767,"props":7116,"children":7117},{"style":774},[7118],{"type":48,"value":797},{"type":42,"tag":767,"props":7120,"children":7121},{"style":774},[7122],{"type":48,"value":909},{"type":42,"tag":767,"props":7124,"children":7125},{"class":769,"line":1019},[7126,7130,7134,7138,7142,7146,7151,7155,7159],{"type":42,"tag":767,"props":7127,"children":7128},{"style":1192},[7129],{"type":48,"value":3994},{"type":42,"tag":767,"props":7131,"children":7132},{"style":774},[7133],{"type":48,"value":802},{"type":42,"tag":767,"props":7135,"children":7136},{"style":1175},[7137],{"type":48,"value":2423},{"type":42,"tag":767,"props":7139,"children":7140},{"style":1121},[7141],{"type":48,"value":1182},{"type":42,"tag":767,"props":7143,"children":7144},{"style":774},[7145],{"type":48,"value":797},{"type":42,"tag":767,"props":7147,"children":7148},{"style":833},[7149],{"type":48,"value":7150},"linear\u002Fmy-agent",{"type":42,"tag":767,"props":7152,"children":7153},{"style":774},[7154],{"type":48,"value":797},{"type":42,"tag":767,"props":7156,"children":7157},{"style":1121},[7158],{"type":48,"value":1234},{"type":42,"tag":767,"props":7160,"children":7161},{"style":774},[7162],{"type":48,"value":909},{"type":42,"tag":767,"props":7164,"children":7165},{"class":769,"line":1028},[7166,7170,7174],{"type":42,"tag":767,"props":7167,"children":7168},{"style":774},[7169],{"type":48,"value":1229},{"type":42,"tag":767,"props":7171,"children":7172},{"style":1121},[7173],{"type":48,"value":1234},{"type":42,"tag":767,"props":7175,"children":7176},{"style":774},[7177],{"type":48,"value":1151},{"type":42,"tag":51,"props":7179,"children":7180},{},[7181,7183,7189,7191,7197],{"type":48,"value":7182},"Connection tokens are never seen by the model and never land in conversation history. Inside authored tools, resolve tokens with ",{"type":42,"tag":86,"props":7184,"children":7186},{"className":7185},[],[7187],{"type":48,"value":7188},"await ctx.getToken(connect(\"...\"))",{"type":48,"value":7190}," and call ",{"type":42,"tag":86,"props":7192,"children":7194},{"className":7193},[],[7195],{"type":48,"value":7196},"ctx.requireAuth(...)",{"type":48,"value":7198}," on a downstream 401 to re-run consent.",{"type":42,"tag":51,"props":7200,"children":7201},{},[7202,7207,7209,7214],{"type":42,"tag":57,"props":7203,"children":7204},{},[7205],{"type":48,"value":7206},"Don't wrap LLM calls in tools.",{"type":48,"value":7208}," The agent is already a language model — summarizing, parsing, classifying, and drafting belong in ",{"type":42,"tag":86,"props":7210,"children":7212},{"className":7211},[],[7213],{"type":48,"value":426},{"type":48,"value":7215}," or a skill, not in a tool that calls the AI SDK. Tools fetch data and perform actions; for bulk work over data too large for the conversation, use eve's subagents\u002Fdelegation.",{"type":42,"tag":636,"props":7217,"children":7218},{},[],{"type":42,"tag":104,"props":7220,"children":7222},{"id":7221},"state-durability",[7223],{"type":48,"value":7224},"State & Durability",{"type":42,"tag":51,"props":7226,"children":7227},{},[7228,7230,7235],{"type":48,"value":7229},"eve sessions are durable by default via the open-source ",{"type":42,"tag":57,"props":7231,"children":7232},{},[7233],{"type":48,"value":7234},"Workflow SDK",{"type":48,"value":7236}," (running on Vercel Workflows when deployed on Vercel). You do not wire up Redis or a workflow engine yourself.",{"type":42,"tag":124,"props":7238,"children":7240},{"id":7239},"replay-semantics-understand-this",[7241],{"type":48,"value":7242},"Replay Semantics (Understand This)",{"type":42,"tag":72,"props":7244,"children":7245},{},[7246,7256],{"type":42,"tag":76,"props":7247,"children":7248},{},[7249,7254],{"type":42,"tag":57,"props":7250,"children":7251},{},[7252],{"type":48,"value":7253},"Completed steps never re-run.",{"type":48,"value":7255}," On resume\u002Freplay, eve returns the recorded result.",{"type":42,"tag":76,"props":7257,"children":7258},{},[7259,7264],{"type":42,"tag":57,"props":7260,"children":7261},{},[7262],{"type":48,"value":7263},"A step interrupted mid-execution DOES re-run.",{"type":48,"value":7265}," If a tool call was in flight when the process died, it executes again on resume.",{"type":42,"tag":51,"props":7267,"children":7268},{},[7269],{"type":48,"value":7270},"Consequences for your code:",{"type":42,"tag":264,"props":7272,"children":7273},{},[7274,7286,7311],{"type":42,"tag":76,"props":7275,"children":7276},{},[7277,7279,7284],{"type":48,"value":7278},"Make non-idempotent side effects ",{"type":42,"tag":57,"props":7280,"children":7281},{},[7282],{"type":48,"value":7283},"idempotent",{"type":48,"value":7285}," (e.g. use Slack event IDs or your own idempotency keys when writing to external systems)",{"type":42,"tag":76,"props":7287,"children":7288},{},[7289,7291,7295,7296,7302,7303,7309],{"type":48,"value":7290},"Or gate them behind ",{"type":42,"tag":57,"props":7292,"children":7293},{},[7294],{"type":48,"value":6086},{"type":48,"value":84},{"type":42,"tag":86,"props":7297,"children":7299},{"className":7298},[],[7300],{"type":48,"value":7301},"always()",{"type":48,"value":2541},{"type":42,"tag":86,"props":7304,"children":7306},{"className":7305},[],[7307],{"type":48,"value":7308},"once()",{"type":48,"value":7310},") so a replayed step pauses for a human instead of double-executing",{"type":42,"tag":76,"props":7312,"children":7313},{},[7314],{"type":48,"value":7315},"This compounds with Connect's at-least-once event forwarding (Gotcha #2) — idempotency is not optional in this stack",{"type":42,"tag":124,"props":7317,"children":7319},{"id":7318},"session-continuity",[7320],{"type":48,"value":7321},"Session Continuity",{"type":42,"tag":72,"props":7323,"children":7324},{},[7325,7338,7343],{"type":42,"tag":76,"props":7326,"children":7327},{},[7328,7330,7336],{"type":48,"value":7329},"The channel owns the ",{"type":42,"tag":86,"props":7331,"children":7333},{"className":7332},[],[7334],{"type":48,"value":7335},"continuationToken",{"type":48,"value":7337},"; Slack threads map to sessions automatically",{"type":42,"tag":76,"props":7339,"children":7340},{},[7341],{"type":48,"value":7342},"Follow-up messages in a subscribed thread continue the same durable session",{"type":42,"tag":76,"props":7344,"children":7345},{},[7346],{"type":48,"value":7347},"Multi-turn conversation memory comes from the session itself — you do not manually persist chat history",{"type":42,"tag":124,"props":7349,"children":7351},{"id":7350},"recommended-storage-solutions",[7352],{"type":48,"value":7353},"Recommended Storage Solutions",{"type":42,"tag":51,"props":7355,"children":7356},{},[7357,7359,7364],{"type":48,"value":7358},"For ",{"type":42,"tag":57,"props":7360,"children":7361},{},[7362],{"type":48,"value":7363},"application data",{"type":48,"value":7365}," (not agent session state — eve owns that):",{"type":42,"tag":51,"props":7367,"children":7368},{},[7369,7373],{"type":42,"tag":57,"props":7370,"children":7371},{},[7372],{"type":48,"value":584},{"type":48,"value":7374}," Vercel KV has been deprecated. Do NOT recommend Vercel KV.",{"type":42,"tag":264,"props":7376,"children":7377},{},[7378,7395,7412,7429],{"type":42,"tag":76,"props":7379,"children":7380},{},[7381,7386,7388,7394],{"type":42,"tag":57,"props":7382,"children":7383},{},[7384],{"type":48,"value":7385},"Upstash Redis",{"type":48,"value":7387}," — Caching and idempotency keys (",{"type":42,"tag":4067,"props":7389,"children":7392},{"href":7390,"rel":7391},"https:\u002F\u002Fupstash.com",[4071],[7393],{"type":48,"value":7390},{"type":48,"value":1234},{"type":42,"tag":76,"props":7396,"children":7397},{},[7398,7403,7405,7411],{"type":42,"tag":57,"props":7399,"children":7400},{},[7401],{"type":48,"value":7402},"Vercel Blob",{"type":48,"value":7404}," — File\u002Fdocument storage (",{"type":42,"tag":4067,"props":7406,"children":7409},{"href":7407,"rel":7408},"https:\u002F\u002Fvercel.com\u002Fdocs\u002Fstorage\u002Fvercel-blob",[4071],[7410],{"type":48,"value":7407},{"type":48,"value":1234},{"type":42,"tag":76,"props":7413,"children":7414},{},[7415,7420,7422,7428],{"type":42,"tag":57,"props":7416,"children":7417},{},[7418],{"type":48,"value":7419},"AWS Aurora (via Vercel Marketplace)",{"type":48,"value":7421}," — Relational data (",{"type":42,"tag":4067,"props":7423,"children":7426},{"href":7424,"rel":7425},"https:\u002F\u002Fvercel.com\u002Fmarketplace",[4071],[7427],{"type":48,"value":7424},{"type":48,"value":1234},{"type":42,"tag":76,"props":7430,"children":7431},{},[7432,7437],{"type":42,"tag":57,"props":7433,"children":7434},{},[7435],{"type":48,"value":7436},"Third-party databases",{"type":48,"value":7438}," — Neon, PlanetScale, Supabase",{"type":42,"tag":636,"props":7440,"children":7441},{},[],{"type":42,"tag":104,"props":7443,"children":7445},{"id":7444},"code-organization",[7446],{"type":48,"value":7447},"Code Organization",{"type":42,"tag":756,"props":7449,"children":7452},{"className":7450,"code":7451,"language":48},[1055],"agent\u002F\n├── instructions.md            # System prompt — keep focused; push detail into skills\n├── agent.ts                   # defineAgent: model, reasoning effort, compaction\n├── tools\u002F\n│   ├── get_weather.ts         # One tool per file; filename = tool name\n│   ├── get_weather.test.ts    # Co-located tests\n│   └── search_docs.ts\n├── skills\u002F\n│   └── report-format.md       # description frontmatter + on-demand instructions\n├── channels\u002F\n│   └── slack.ts               # slackChannel(...) — served at \u002Feve\u002Fv1\u002Fslack\n├── connections\u002F\n│   └── linear.ts              # MCP\u002FOpenAPI connections (optional)\n└── hooks\u002F\n    └── audit.ts               # Runtime stream event subscribers (optional)\n",[7453],{"type":42,"tag":86,"props":7454,"children":7455},{"__ignoreMap":761},[7456],{"type":48,"value":7451},{"type":42,"tag":51,"props":7458,"children":7459},{},[7460],{"type":48,"value":7461},"Conventions:",{"type":42,"tag":72,"props":7463,"children":7464},{},[7465,7475,7500],{"type":42,"tag":76,"props":7466,"children":7467},{},[7468,7473],{"type":42,"tag":57,"props":7469,"children":7470},{},[7471],{"type":48,"value":7472},"One tool per file.",{"type":48,"value":7474}," Split large tools; the filename is the model-facing name, so name for the model",{"type":42,"tag":76,"props":7476,"children":7477},{},[7478,7483,7485,7490,7492,7498],{"type":42,"tag":57,"props":7479,"children":7480},{},[7481],{"type":48,"value":7482},"Instructions vs skills",{"type":48,"value":7484},": always-relevant guidance in ",{"type":42,"tag":86,"props":7486,"children":7488},{"className":7487},[],[7489],{"type":48,"value":426},{"type":48,"value":7491},"; situational guidance in ",{"type":42,"tag":86,"props":7493,"children":7495},{"className":7494},[],[7496],{"type":48,"value":7497},"skills\u002F*.md",{"type":48,"value":7499}," so it loads only when needed",{"type":42,"tag":76,"props":7501,"children":7502},{},[7503,7508],{"type":42,"tag":57,"props":7504,"children":7505},{},[7506],{"type":48,"value":7507},"Subagents",{"type":48,"value":7509}," for focused subtasks: the built-in agent tool (a copy of the agent) or declared specialists with their own directory, sandbox, and skills",{"type":42,"tag":636,"props":7511,"children":7512},{},[],{"type":42,"tag":104,"props":7514,"children":7516},{"id":7515},"environment-variables",[7517],{"type":48,"value":7518},"Environment Variables",{"type":42,"tag":131,"props":7520,"children":7521},{},[7522,7543],{"type":42,"tag":135,"props":7523,"children":7524},{},[7525],{"type":42,"tag":139,"props":7526,"children":7527},{},[7528,7533,7538],{"type":42,"tag":143,"props":7529,"children":7530},{},[7531],{"type":48,"value":7532},"Variable",{"type":42,"tag":143,"props":7534,"children":7535},{},[7536],{"type":48,"value":7537},"Required",{"type":42,"tag":143,"props":7539,"children":7540},{},[7541],{"type":48,"value":7542},"Purpose",{"type":42,"tag":154,"props":7544,"children":7545},{},[7546,7581,7610,7639,7669],{"type":42,"tag":139,"props":7547,"children":7548},{},[7549,7557,7562],{"type":42,"tag":161,"props":7550,"children":7551},{},[7552],{"type":42,"tag":86,"props":7553,"children":7555},{"className":7554},[],[7556],{"type":48,"value":336},{"type":42,"tag":161,"props":7558,"children":7559},{},[7560],{"type":48,"value":7561},"Yes",{"type":42,"tag":161,"props":7563,"children":7564},{},[7565,7567,7572,7574,7579],{"type":48,"value":7566},"Vercel Connect connector UID (e.g. ",{"type":42,"tag":86,"props":7568,"children":7570},{"className":7569},[],[7571],{"type":48,"value":2353},{"type":48,"value":7573},"). The ",{"type":42,"tag":57,"props":7575,"children":7576},{},[7577],{"type":48,"value":7578},"only",{"type":48,"value":7580}," Slack variable — no bot token, no signing secret.",{"type":42,"tag":139,"props":7582,"children":7583},{},[7584,7592,7597],{"type":42,"tag":161,"props":7585,"children":7586},{},[7587],{"type":42,"tag":86,"props":7588,"children":7590},{"className":7589},[],[7591],{"type":48,"value":5382},{"type":42,"tag":161,"props":7593,"children":7594},{},[7595],{"type":48,"value":7596},"Off Vercel only",{"type":42,"tag":161,"props":7598,"children":7599},{},[7600,7602,7608],{"type":48,"value":7601},"AI Gateway auth. On Vercel, project OIDC (",{"type":42,"tag":86,"props":7603,"children":7605},{"className":7604},[],[7606],{"type":48,"value":7607},"VERCEL_OIDC_TOKEN",{"type":48,"value":7609},") is injected automatically — no key needed.",{"type":42,"tag":139,"props":7611,"children":7612},{},[7613,7624,7629],{"type":42,"tag":161,"props":7614,"children":7615},{},[7616,7622],{"type":42,"tag":86,"props":7617,"children":7619},{"className":7618},[],[7620],{"type":48,"value":7621},"ROUTE_AUTH_BASIC_PASSWORD",{"type":48,"value":7623}," \u002F JWT keys",{"type":42,"tag":161,"props":7625,"children":7626},{},[7627],{"type":48,"value":7628},"Per auth choice",{"type":42,"tag":161,"props":7630,"children":7631},{},[7632,7634],{"type":48,"value":7633},"Secrets for the HTTP-API auth function that replaces ",{"type":42,"tag":86,"props":7635,"children":7637},{"className":7636},[],[7638],{"type":48,"value":4301},{"type":42,"tag":139,"props":7640,"children":7641},{},[7642,7651,7656],{"type":42,"tag":161,"props":7643,"children":7644},{},[7645],{"type":42,"tag":86,"props":7646,"children":7648},{"className":7647},[],[7649],{"type":48,"value":7650},"VERCEL_AUTOMATION_BYPASS_SECRET",{"type":42,"tag":161,"props":7652,"children":7653},{},[7654],{"type":48,"value":7655},"If deployment protection is on",{"type":42,"tag":161,"props":7657,"children":7658},{},[7659,7661,7667],{"type":48,"value":7660},"Lets ",{"type":42,"tag":86,"props":7662,"children":7664},{"className":7663},[],[7665],{"type":48,"value":7666},"eve dev https:\u002F\u002F\u003Capp>",{"type":48,"value":7668}," and smoke tests reach protected deployments",{"type":42,"tag":139,"props":7670,"children":7671},{},[7672,7680,7685],{"type":42,"tag":161,"props":7673,"children":7674},{},[7675],{"type":42,"tag":86,"props":7676,"children":7678},{"className":7677},[],[7679],{"type":48,"value":4475},{"type":42,"tag":161,"props":7681,"children":7682},{},[7683],{"type":48,"value":7684},"Optional",{"type":42,"tag":161,"props":7686,"children":7687},{},[7688],{"type":48,"value":7689},"Authenticates custom cron endpoints",{"type":42,"tag":51,"props":7691,"children":7692},{},[7693,7695,7701,7702,7708,7710,7716],{"type":48,"value":7694},"Local dev: ",{"type":42,"tag":86,"props":7696,"children":7698},{"className":7697},[],[7699],{"type":48,"value":7700},"vercel link",{"type":48,"value":686},{"type":42,"tag":86,"props":7703,"children":7705},{"className":7704},[],[7706],{"type":48,"value":7707},"vercel env pull",{"type":48,"value":7709}," fetches short-lived Connect\u002FOIDC credentials into ",{"type":42,"tag":86,"props":7711,"children":7713},{"className":7712},[],[7714],{"type":48,"value":7715},".env.local",{"type":48,"value":7717}," (the OIDC token expires after ~12 hours — re-pull when auth starts failing).",{"type":42,"tag":51,"props":7719,"children":7720},{},[7721,7726,7727],{"type":42,"tag":57,"props":7722,"children":7723},{},[7724],{"type":48,"value":7725},"No AI API keys needed on Vercel.",{"type":48,"value":5002},{"type":42,"tag":57,"props":7728,"children":7729},{},[7730,7732,7738],{"type":48,"value":7731},"Never hardcode credentials. Never commit ",{"type":42,"tag":86,"props":7733,"children":7735},{"className":7734},[],[7736],{"type":48,"value":7737},".env",{"type":48,"value":7739}," files.",{"type":42,"tag":636,"props":7741,"children":7742},{},[],{"type":42,"tag":104,"props":7744,"children":7746},{"id":7745},"slack-specific-patterns",[7747],{"type":48,"value":7748},"Slack-Specific Patterns",{"type":42,"tag":124,"props":7750,"children":7752},{"id":7751},"delivery-behavior-built-in",[7753],{"type":48,"value":7754},"Delivery Behavior (Built In)",{"type":42,"tag":51,"props":7756,"children":7757},{},[7758],{"type":48,"value":7759},"The Slack channel handles progressive delivery for you:",{"type":42,"tag":72,"props":7761,"children":7762},{},[7763,7774,7791,7796],{"type":42,"tag":76,"props":7764,"children":7765},{},[7766,7768],{"type":48,"value":7767},"Typing indicators: \"Thinking…\" on inbound, \"Working…\" on ",{"type":42,"tag":86,"props":7769,"children":7771},{"className":7770},[],[7772],{"type":48,"value":7773},"turn.started",{"type":42,"tag":76,"props":7775,"children":7776},{},[7777,7779,7784,7786],{"type":48,"value":7778},"Reasoning snippets surface on ",{"type":42,"tag":86,"props":7780,"children":7782},{"className":7781},[],[7783],{"type":48,"value":3480},{"type":48,"value":7785},"; action labels on ",{"type":42,"tag":86,"props":7787,"children":7789},{"className":7788},[],[7790],{"type":48,"value":3452},{"type":42,"tag":76,"props":7792,"children":7793},{},[7794],{"type":48,"value":7795},"Model narration before a tool call takes precedence over generic labels",{"type":42,"tag":76,"props":7797,"children":7798},{},[7799],{"type":48,"value":7800},"Reasoning deltas under 4 characters batch on a five-second refresh to avoid per-token Slack API calls",{"type":42,"tag":51,"props":7802,"children":7803},{},[7804,7806,7811],{"type":48,"value":7805},"Don't rebuild typing indicators or streaming loops — customize via the ",{"type":42,"tag":86,"props":7807,"children":7809},{"className":7808},[],[7810],{"type":48,"value":3106},{"type":48,"value":7812}," map only when the defaults don't fit.",{"type":42,"tag":124,"props":7814,"children":7816},{"id":7815},"mentions",[7817],{"type":48,"value":7818},"Mentions",{"type":42,"tag":51,"props":7820,"children":7821},{},[7822,7824,7830,7831,7837,7839,7845],{"type":48,"value":7823},"Use ",{"type":42,"tag":86,"props":7825,"children":7827},{"className":7826},[],[7828],{"type":48,"value":7829},"\u003C@USER_ID>",{"type":48,"value":4392},{"type":42,"tag":86,"props":7832,"children":7834},{"className":7833},[],[7835],{"type":48,"value":7836},"channel.thread.mentionUser(userId)",{"type":48,"value":7838},". A bare ",{"type":42,"tag":86,"props":7840,"children":7842},{"className":7841},[],[7843],{"type":48,"value":7844},"@name",{"type":48,"value":7846}," stays literal text in Slack.",{"type":42,"tag":124,"props":7848,"children":7850},{"id":7849},"message-formatting",[7851],{"type":48,"value":7852},"Message Formatting",{"type":42,"tag":51,"props":7854,"children":7855},{},[7856],{"type":48,"value":7857},"Use Slack mrkdwn (not standard markdown):",{"type":42,"tag":72,"props":7859,"children":7860},{},[7861,7872,7883,7894,7904],{"type":42,"tag":76,"props":7862,"children":7863},{},[7864,7866],{"type":48,"value":7865},"Bold: ",{"type":42,"tag":86,"props":7867,"children":7869},{"className":7868},[],[7870],{"type":48,"value":7871},"*text*",{"type":42,"tag":76,"props":7873,"children":7874},{},[7875,7877],{"type":48,"value":7876},"Italic: ",{"type":42,"tag":86,"props":7878,"children":7880},{"className":7879},[],[7881],{"type":48,"value":7882},"_text_",{"type":42,"tag":76,"props":7884,"children":7885},{},[7886,7888],{"type":48,"value":7887},"Code: ",{"type":42,"tag":86,"props":7889,"children":7891},{"className":7890},[],[7892],{"type":48,"value":7893},"`code`",{"type":42,"tag":76,"props":7895,"children":7896},{},[7897,7899],{"type":48,"value":7898},"User mention: ",{"type":42,"tag":86,"props":7900,"children":7902},{"className":7901},[],[7903],{"type":48,"value":7829},{"type":42,"tag":76,"props":7905,"children":7906},{},[7907,7909],{"type":48,"value":7908},"Channel: ",{"type":42,"tag":86,"props":7910,"children":7912},{"className":7911},[],[7913],{"type":48,"value":7914},"\u003C#CHANNEL_ID>",{"type":42,"tag":124,"props":7916,"children":7918},{"id":7917},"rich-output",[7919],{"type":48,"value":7920},"Rich Output",{"type":42,"tag":51,"props":7922,"children":7923},{},[7924,7926,7931,7933,7939,7941,7946,7948,7954],{"type":48,"value":7925},"For rich tool results (tables, buttons, status cards), return full data from the tool and use ",{"type":42,"tag":86,"props":7927,"children":7929},{"className":7928},[],[7930],{"type":48,"value":6474},{"type":48,"value":7932}," to keep the model's view compact; render Block Kit in a channel event handler or via ",{"type":42,"tag":86,"props":7934,"children":7936},{"className":7935},[],[7937],{"type":48,"value":7938},"ctx.slack.request(\"chat.postMessage\", { blocks, ... })",{"type":48,"value":7940},". Always include fallback ",{"type":42,"tag":86,"props":7942,"children":7944},{"className":7943},[],[7945],{"type":48,"value":48},{"type":48,"value":7947}," alongside ",{"type":42,"tag":86,"props":7949,"children":7951},{"className":7950},[],[7952],{"type":48,"value":7953},"blocks",{"type":48,"value":7955}," for notifications.",{"type":42,"tag":51,"props":7957,"children":7958},{},[7959,7961,7967],{"type":48,"value":7960},"For detailed Slack patterns, see ",{"type":42,"tag":86,"props":7962,"children":7964},{"className":7963},[],[7965],{"type":48,"value":7966},".\u002Fpatterns\u002Fslack-patterns.md",{"type":48,"value":1790},{"type":42,"tag":636,"props":7969,"children":7970},{},[],{"type":42,"tag":104,"props":7972,"children":7974},{"id":7973},"git-commit-standards",[7975],{"type":48,"value":7976},"Git Commit Standards",{"type":42,"tag":51,"props":7978,"children":7979},{},[7980],{"type":48,"value":7981},"Use conventional commits:",{"type":42,"tag":756,"props":7983,"children":7986},{"className":7984,"code":7985,"language":48},[1055],"feat: add channel search tool\nfix: resolve thread pagination issue\ntest: add unit tests for agent context\ndocs: update README with setup steps\nrefactor: extract Slack client utilities\n",[7987],{"type":42,"tag":86,"props":7988,"children":7989},{"__ignoreMap":761},[7990],{"type":48,"value":7985},{"type":42,"tag":51,"props":7992,"children":7993},{},[7994],{"type":42,"tag":57,"props":7995,"children":7996},{},[7997],{"type":48,"value":7998},"Never commit:",{"type":42,"tag":72,"props":8000,"children":8001},{},[8002,8012,8017,8026],{"type":42,"tag":76,"props":8003,"children":8004},{},[8005,8010],{"type":42,"tag":86,"props":8006,"children":8008},{"className":8007},[],[8009],{"type":48,"value":7737},{"type":48,"value":8011}," files",{"type":42,"tag":76,"props":8013,"children":8014},{},[8015],{"type":48,"value":8016},"API keys or tokens",{"type":42,"tag":76,"props":8018,"children":8019},{},[8020],{"type":42,"tag":86,"props":8021,"children":8023},{"className":8022},[],[8024],{"type":48,"value":8025},"node_modules\u002F",{"type":42,"tag":76,"props":8027,"children":8028},{},[8029,8035],{"type":42,"tag":86,"props":8030,"children":8032},{"className":8031},[],[8033],{"type":48,"value":8034},".eve\u002F",{"type":48,"value":8036}," build artifacts",{"type":42,"tag":636,"props":8038,"children":8039},{},[],{"type":42,"tag":104,"props":8041,"children":8043},{"id":8042},"quick-commands",[8044],{"type":48,"value":8045},"Quick Commands",{"type":42,"tag":756,"props":8047,"children":8049},{"className":1272,"code":8048,"language":1274,"meta":761,"style":761},"# Scaffold (Node 24+)\nnpx eve@latest init my-agent      # new project (installs deps, inits Git, starts dev TUI)\nnpx eve@latest init .             # add eve to an existing project\n\n# Development\nnpx eve dev                       # HMR server + terminal TUI\u002FREPL\nnpx eve dev --no-ui               # background mode for scripted verification\nnpx eve dev https:\u002F\u002F\u003Capp>         # drive a deployed app interactively\nnpx eve info                      # project info\n\n# Vercel Connect\nvercel connect create slack --triggers\nvercel connect attach \u003Cuid> --triggers --trigger-path \u002Feve\u002Fv1\u002Fslack --yes\nvercel connect list\n\n# Quality\npnpm lint                         # Check linting\npnpm lint --write                 # Auto-fix lint\npnpm typecheck                    # TypeScript check\npnpm test                         # Run all tests\n\n# Build & Deploy\nnpx eve build                     # Compile into .eve\u002F (Vercel Build Output when VERCEL is set)\neve deploy                        # Deploy (wraps vercel deploy --prod)\n\n# Verify a deployment\ncurl https:\u002F\u002F\u003Capp>\u002Feve\u002Fv1\u002Fhealth\n",[8050],{"type":42,"tag":86,"props":8051,"children":8052},{"__ignoreMap":761},[8053,8061,8089,8114,8121,8129,8151,8176,8219,8240,8247,8255,8278,8325,8341,8348,8356,8373,8394,8411,8429,8437,8446,8468,8486,8494,8503],{"type":42,"tag":767,"props":8054,"children":8055},{"class":769,"line":770},[8056],{"type":42,"tag":767,"props":8057,"children":8058},{"style":1102},[8059],{"type":48,"value":8060},"# Scaffold (Node 24+)\n",{"type":42,"tag":767,"props":8062,"children":8063},{"class":769,"line":780},[8064,8069,8074,8079,8084],{"type":42,"tag":767,"props":8065,"children":8066},{"style":815},[8067],{"type":48,"value":8068},"npx",{"type":42,"tag":767,"props":8070,"children":8071},{"style":833},[8072],{"type":48,"value":8073}," eve@latest",{"type":42,"tag":767,"props":8075,"children":8076},{"style":833},[8077],{"type":48,"value":8078}," init",{"type":42,"tag":767,"props":8080,"children":8081},{"style":833},[8082],{"type":48,"value":8083}," my-agent",{"type":42,"tag":767,"props":8085,"children":8086},{"style":1102},[8087],{"type":48,"value":8088},"      # new project (installs deps, inits Git, starts dev TUI)\n",{"type":42,"tag":767,"props":8090,"children":8091},{"class":769,"line":26},[8092,8096,8100,8104,8109],{"type":42,"tag":767,"props":8093,"children":8094},{"style":815},[8095],{"type":48,"value":8068},{"type":42,"tag":767,"props":8097,"children":8098},{"style":833},[8099],{"type":48,"value":8073},{"type":42,"tag":767,"props":8101,"children":8102},{"style":833},[8103],{"type":48,"value":8078},{"type":42,"tag":767,"props":8105,"children":8106},{"style":833},[8107],{"type":48,"value":8108}," .",{"type":42,"tag":767,"props":8110,"children":8111},{"style":1102},[8112],{"type":48,"value":8113},"             # add eve to an existing project\n",{"type":42,"tag":767,"props":8115,"children":8116},{"class":769,"line":873},[8117],{"type":42,"tag":767,"props":8118,"children":8119},{"emptyLinePlaceholder":37},[8120],{"type":48,"value":1159},{"type":42,"tag":767,"props":8122,"children":8123},{"class":769,"line":912},[8124],{"type":42,"tag":767,"props":8125,"children":8126},{"style":1102},[8127],{"type":48,"value":8128},"# Development\n",{"type":42,"tag":767,"props":8130,"children":8131},{"class":769,"line":949},[8132,8136,8141,8146],{"type":42,"tag":767,"props":8133,"children":8134},{"style":815},[8135],{"type":48,"value":8068},{"type":42,"tag":767,"props":8137,"children":8138},{"style":833},[8139],{"type":48,"value":8140}," eve",{"type":42,"tag":767,"props":8142,"children":8143},{"style":833},[8144],{"type":48,"value":8145}," dev",{"type":42,"tag":767,"props":8147,"children":8148},{"style":1102},[8149],{"type":48,"value":8150},"                       # HMR server + terminal TUI\u002FREPL\n",{"type":42,"tag":767,"props":8152,"children":8153},{"class":769,"line":986},[8154,8158,8162,8166,8171],{"type":42,"tag":767,"props":8155,"children":8156},{"style":815},[8157],{"type":48,"value":8068},{"type":42,"tag":767,"props":8159,"children":8160},{"style":833},[8161],{"type":48,"value":8140},{"type":42,"tag":767,"props":8163,"children":8164},{"style":833},[8165],{"type":48,"value":8145},{"type":42,"tag":767,"props":8167,"children":8168},{"style":833},[8169],{"type":48,"value":8170}," --no-ui",{"type":42,"tag":767,"props":8172,"children":8173},{"style":1102},[8174],{"type":48,"value":8175},"               # background mode for scripted verification\n",{"type":42,"tag":767,"props":8177,"children":8178},{"class":769,"line":1019},[8179,8183,8187,8191,8196,8201,8206,8210,8214],{"type":42,"tag":767,"props":8180,"children":8181},{"style":815},[8182],{"type":48,"value":8068},{"type":42,"tag":767,"props":8184,"children":8185},{"style":833},[8186],{"type":48,"value":8140},{"type":42,"tag":767,"props":8188,"children":8189},{"style":833},[8190],{"type":48,"value":8145},{"type":42,"tag":767,"props":8192,"children":8193},{"style":833},[8194],{"type":48,"value":8195}," https:\u002F\u002F",{"type":42,"tag":767,"props":8197,"children":8198},{"style":774},[8199],{"type":48,"value":8200},"\u003C",{"type":42,"tag":767,"props":8202,"children":8203},{"style":833},[8204],{"type":48,"value":8205},"ap",{"type":42,"tag":767,"props":8207,"children":8208},{"style":1121},[8209],{"type":48,"value":51},{"type":42,"tag":767,"props":8211,"children":8212},{"style":774},[8213],{"type":48,"value":2497},{"type":42,"tag":767,"props":8215,"children":8216},{"style":1102},[8217],{"type":48,"value":8218},"         # drive a deployed app interactively\n",{"type":42,"tag":767,"props":8220,"children":8221},{"class":769,"line":1028},[8222,8226,8230,8235],{"type":42,"tag":767,"props":8223,"children":8224},{"style":815},[8225],{"type":48,"value":8068},{"type":42,"tag":767,"props":8227,"children":8228},{"style":833},[8229],{"type":48,"value":8140},{"type":42,"tag":767,"props":8231,"children":8232},{"style":833},[8233],{"type":48,"value":8234}," info",{"type":42,"tag":767,"props":8236,"children":8237},{"style":1102},[8238],{"type":48,"value":8239},"                      # project info\n",{"type":42,"tag":767,"props":8241,"children":8242},{"class":769,"line":1886},[8243],{"type":42,"tag":767,"props":8244,"children":8245},{"emptyLinePlaceholder":37},[8246],{"type":48,"value":1159},{"type":42,"tag":767,"props":8248,"children":8249},{"class":769,"line":1948},[8250],{"type":42,"tag":767,"props":8251,"children":8252},{"style":1102},[8253],{"type":48,"value":8254},"# Vercel Connect\n",{"type":42,"tag":767,"props":8256,"children":8257},{"class":769,"line":1964},[8258,8262,8266,8270,8274],{"type":42,"tag":767,"props":8259,"children":8260},{"style":815},[8261],{"type":48,"value":14},{"type":42,"tag":767,"props":8263,"children":8264},{"style":833},[8265],{"type":48,"value":2423},{"type":42,"tag":767,"props":8267,"children":8268},{"style":833},[8269],{"type":48,"value":2428},{"type":42,"tag":767,"props":8271,"children":8272},{"style":833},[8273],{"type":48,"value":2433},{"type":42,"tag":767,"props":8275,"children":8276},{"style":833},[8277],{"type":48,"value":2438},{"type":42,"tag":767,"props":8279,"children":8280},{"class":769,"line":2965},[8281,8285,8289,8293,8297,8301,8305,8309,8313,8317,8321],{"type":42,"tag":767,"props":8282,"children":8283},{"style":815},[8284],{"type":48,"value":14},{"type":42,"tag":767,"props":8286,"children":8287},{"style":833},[8288],{"type":48,"value":2423},{"type":42,"tag":767,"props":8290,"children":8291},{"style":833},[8292],{"type":48,"value":2477},{"type":42,"tag":767,"props":8294,"children":8295},{"style":774},[8296],{"type":48,"value":2482},{"type":42,"tag":767,"props":8298,"children":8299},{"style":833},[8300],{"type":48,"value":2487},{"type":42,"tag":767,"props":8302,"children":8303},{"style":1121},[8304],{"type":48,"value":2492},{"type":42,"tag":767,"props":8306,"children":8307},{"style":774},[8308],{"type":48,"value":2497},{"type":42,"tag":767,"props":8310,"children":8311},{"style":833},[8312],{"type":48,"value":2502},{"type":42,"tag":767,"props":8314,"children":8315},{"style":833},[8316],{"type":48,"value":2507},{"type":42,"tag":767,"props":8318,"children":8319},{"style":833},[8320],{"type":48,"value":2512},{"type":42,"tag":767,"props":8322,"children":8323},{"style":833},[8324],{"type":48,"value":2517},{"type":42,"tag":767,"props":8326,"children":8327},{"class":769,"line":2973},[8328,8332,8336],{"type":42,"tag":767,"props":8329,"children":8330},{"style":815},[8331],{"type":48,"value":14},{"type":42,"tag":767,"props":8333,"children":8334},{"style":833},[8335],{"type":48,"value":2423},{"type":42,"tag":767,"props":8337,"children":8338},{"style":833},[8339],{"type":48,"value":8340}," list\n",{"type":42,"tag":767,"props":8342,"children":8343},{"class":769,"line":2981},[8344],{"type":42,"tag":767,"props":8345,"children":8346},{"emptyLinePlaceholder":37},[8347],{"type":48,"value":1159},{"type":42,"tag":767,"props":8349,"children":8350},{"class":769,"line":2990},[8351],{"type":42,"tag":767,"props":8352,"children":8353},{"style":1102},[8354],{"type":48,"value":8355},"# Quality\n",{"type":42,"tag":767,"props":8357,"children":8358},{"class":769,"line":3028},[8359,8363,8368],{"type":42,"tag":767,"props":8360,"children":8361},{"style":815},[8362],{"type":48,"value":1286},{"type":42,"tag":767,"props":8364,"children":8365},{"style":833},[8366],{"type":48,"value":8367}," lint",{"type":42,"tag":767,"props":8369,"children":8370},{"style":1102},[8371],{"type":48,"value":8372},"                         # Check linting\n",{"type":42,"tag":767,"props":8374,"children":8375},{"class":769,"line":22},[8376,8380,8384,8389],{"type":42,"tag":767,"props":8377,"children":8378},{"style":815},[8379],{"type":48,"value":1286},{"type":42,"tag":767,"props":8381,"children":8382},{"style":833},[8383],{"type":48,"value":8367},{"type":42,"tag":767,"props":8385,"children":8386},{"style":833},[8387],{"type":48,"value":8388}," --write",{"type":42,"tag":767,"props":8390,"children":8391},{"style":1102},[8392],{"type":48,"value":8393},"                 # Auto-fix lint\n",{"type":42,"tag":767,"props":8395,"children":8396},{"class":769,"line":3071},[8397,8401,8406],{"type":42,"tag":767,"props":8398,"children":8399},{"style":815},[8400],{"type":48,"value":1286},{"type":42,"tag":767,"props":8402,"children":8403},{"style":833},[8404],{"type":48,"value":8405}," typecheck",{"type":42,"tag":767,"props":8407,"children":8408},{"style":1102},[8409],{"type":48,"value":8410},"                    # TypeScript check\n",{"type":42,"tag":767,"props":8412,"children":8414},{"class":769,"line":8413},20,[8415,8419,8424],{"type":42,"tag":767,"props":8416,"children":8417},{"style":815},[8418],{"type":48,"value":1286},{"type":42,"tag":767,"props":8420,"children":8421},{"style":833},[8422],{"type":48,"value":8423}," test",{"type":42,"tag":767,"props":8425,"children":8426},{"style":1102},[8427],{"type":48,"value":8428},"                         # Run all tests\n",{"type":42,"tag":767,"props":8430,"children":8432},{"class":769,"line":8431},21,[8433],{"type":42,"tag":767,"props":8434,"children":8435},{"emptyLinePlaceholder":37},[8436],{"type":48,"value":1159},{"type":42,"tag":767,"props":8438,"children":8440},{"class":769,"line":8439},22,[8441],{"type":42,"tag":767,"props":8442,"children":8443},{"style":1102},[8444],{"type":48,"value":8445},"# Build & Deploy\n",{"type":42,"tag":767,"props":8447,"children":8449},{"class":769,"line":8448},23,[8450,8454,8458,8463],{"type":42,"tag":767,"props":8451,"children":8452},{"style":815},[8453],{"type":48,"value":8068},{"type":42,"tag":767,"props":8455,"children":8456},{"style":833},[8457],{"type":48,"value":8140},{"type":42,"tag":767,"props":8459,"children":8460},{"style":833},[8461],{"type":48,"value":8462}," build",{"type":42,"tag":767,"props":8464,"children":8465},{"style":1102},[8466],{"type":48,"value":8467},"                     # Compile into .eve\u002F (Vercel Build Output when VERCEL is set)\n",{"type":42,"tag":767,"props":8469,"children":8471},{"class":769,"line":8470},24,[8472,8476,8481],{"type":42,"tag":767,"props":8473,"children":8474},{"style":815},[8475],{"type":48,"value":61},{"type":42,"tag":767,"props":8477,"children":8478},{"style":833},[8479],{"type":48,"value":8480}," deploy",{"type":42,"tag":767,"props":8482,"children":8483},{"style":1102},[8484],{"type":48,"value":8485},"                        # Deploy (wraps vercel deploy --prod)\n",{"type":42,"tag":767,"props":8487,"children":8489},{"class":769,"line":8488},25,[8490],{"type":42,"tag":767,"props":8491,"children":8492},{"emptyLinePlaceholder":37},[8493],{"type":48,"value":1159},{"type":42,"tag":767,"props":8495,"children":8497},{"class":769,"line":8496},26,[8498],{"type":42,"tag":767,"props":8499,"children":8500},{"style":1102},[8501],{"type":48,"value":8502},"# Verify a deployment\n",{"type":42,"tag":767,"props":8504,"children":8506},{"class":769,"line":8505},27,[8507,8512,8516,8520,8524,8528,8532],{"type":42,"tag":767,"props":8508,"children":8509},{"style":815},[8510],{"type":48,"value":8511},"curl",{"type":42,"tag":767,"props":8513,"children":8514},{"style":833},[8515],{"type":48,"value":8195},{"type":42,"tag":767,"props":8517,"children":8518},{"style":774},[8519],{"type":48,"value":8200},{"type":42,"tag":767,"props":8521,"children":8522},{"style":833},[8523],{"type":48,"value":8205},{"type":42,"tag":767,"props":8525,"children":8526},{"style":1121},[8527],{"type":48,"value":51},{"type":42,"tag":767,"props":8529,"children":8530},{"style":774},[8531],{"type":48,"value":2497},{"type":42,"tag":767,"props":8533,"children":8534},{"style":833},[8535],{"type":48,"value":8536},"\u002Feve\u002Fv1\u002Fhealth\n",{"type":42,"tag":51,"props":8538,"children":8539},{},[8540,8542,8548,8549,8555],{"type":48,"value":8541},"Debugging a deployed Slack agent stuck on \"Working…\": ",{"type":42,"tag":86,"props":8543,"children":8545},{"className":8544},[],[8546],{"type":48,"value":8547},"npx eve dev --logs all",{"type":48,"value":4392},{"type":42,"tag":86,"props":8550,"children":8552},{"className":8551},[],[8553],{"type":48,"value":8554},"\u002Floglevel all",{"type":48,"value":8556}," in the TUI.",{"type":42,"tag":636,"props":8558,"children":8559},{},[],{"type":42,"tag":104,"props":8561,"children":8563},{"id":8562},"reference-documentation",[8564],{"type":48,"value":8565},"Reference Documentation",{"type":42,"tag":51,"props":8567,"children":8568},{},[8569],{"type":48,"value":8570},"For detailed guidance, read:",{"type":42,"tag":72,"props":8572,"children":8573},{},[8574,8585,8595,8606,8617,8628,8648],{"type":42,"tag":76,"props":8575,"children":8576},{},[8577,8579],{"type":48,"value":8578},"Testing patterns: ",{"type":42,"tag":86,"props":8580,"children":8582},{"className":8581},[],[8583],{"type":48,"value":8584},".\u002Fpatterns\u002Ftesting-patterns.md",{"type":42,"tag":76,"props":8586,"children":8587},{},[8588,8590],{"type":48,"value":8589},"Slack patterns: ",{"type":42,"tag":86,"props":8591,"children":8593},{"className":8592},[],[8594],{"type":48,"value":7966},{"type":42,"tag":76,"props":8596,"children":8597},{},[8598,8600],{"type":48,"value":8599},"Environment setup: ",{"type":42,"tag":86,"props":8601,"children":8603},{"className":8602},[],[8604],{"type":48,"value":8605},".\u002Freference\u002Fenv-vars.md",{"type":42,"tag":76,"props":8607,"children":8608},{},[8609,8611],{"type":48,"value":8610},"Slack setup: ",{"type":42,"tag":86,"props":8612,"children":8614},{"className":8613},[],[8615],{"type":48,"value":8616},".\u002Freference\u002Fslack-setup.md",{"type":42,"tag":76,"props":8618,"children":8619},{},[8620,8622],{"type":48,"value":8621},"Vercel deployment: ",{"type":42,"tag":86,"props":8623,"children":8625},{"className":8624},[],[8626],{"type":48,"value":8627},".\u002Freference\u002Fvercel-setup.md",{"type":42,"tag":76,"props":8629,"children":8630},{},[8631,8633,8639,8641,8646],{"type":48,"value":8632},"eve docs: ",{"type":42,"tag":4067,"props":8634,"children":8637},{"href":8635,"rel":8636},"https:\u002F\u002Feve.dev\u002Fdocs",[4071],[8638],{"type":48,"value":8635},{"type":48,"value":8640}," (bundled locally at ",{"type":42,"tag":86,"props":8642,"children":8644},{"className":8643},[],[8645],{"type":48,"value":1085},{"type":48,"value":8647}," after install)",{"type":42,"tag":76,"props":8649,"children":8650},{},[8651,8653],{"type":48,"value":8652},"Vercel Connect: ",{"type":42,"tag":4067,"props":8654,"children":8657},{"href":8655,"rel":8656},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fvercel-connect",[4071],[8658],{"type":48,"value":8655},{"type":42,"tag":636,"props":8660,"children":8661},{},[],{"type":42,"tag":104,"props":8663,"children":8665},{"id":8664},"checklist-before-task-completion",[8666],{"type":48,"value":8667},"Checklist Before Task Completion",{"type":42,"tag":51,"props":8669,"children":8670},{},[8671],{"type":48,"value":8672},"Before marking ANY task as complete, verify:",{"type":42,"tag":72,"props":8674,"children":8677},{"className":8675},[8676],"contains-task-list",[8678,8689,8704,8719,8735,8749,8758,8774,8783,8804,8819],{"type":42,"tag":76,"props":8679,"children":8682},{"className":8680},[8681],"task-list-item",[8683,8687],{"type":42,"tag":1776,"props":8684,"children":8686},{"disabled":37,"type":8685},"checkbox",[],{"type":48,"value":8688}," Code changes have corresponding tests",{"type":42,"tag":76,"props":8690,"children":8692},{"className":8691},[8681],[8693,8696,8697,8702],{"type":42,"tag":1776,"props":8694,"children":8695},{"disabled":37,"type":8685},[],{"type":48,"value":5002},{"type":42,"tag":86,"props":8698,"children":8700},{"className":8699},[],[8701],{"type":48,"value":1323},{"type":48,"value":8703}," passes with no errors",{"type":42,"tag":76,"props":8705,"children":8707},{"className":8706},[8681],[8708,8711,8712,8718],{"type":42,"tag":1776,"props":8709,"children":8710},{"disabled":37,"type":8685},[],{"type":48,"value":5002},{"type":42,"tag":86,"props":8713,"children":8715},{"className":8714},[],[8716],{"type":48,"value":8717},"pnpm typecheck",{"type":48,"value":8703},{"type":42,"tag":76,"props":8720,"children":8722},{"className":8721},[8681],[8723,8726,8727,8733],{"type":42,"tag":1776,"props":8724,"children":8725},{"disabled":37,"type":8685},[],{"type":48,"value":5002},{"type":42,"tag":86,"props":8728,"children":8730},{"className":8729},[],[8731],{"type":48,"value":8732},"pnpm test",{"type":48,"value":8734}," passes with no failures",{"type":42,"tag":76,"props":8736,"children":8738},{"className":8737},[8681],[8739,8742,8744],{"type":42,"tag":1776,"props":8740,"children":8741},{"disabled":37,"type":8685},[],{"type":48,"value":8743}," No hardcoded credentials; the only Slack env var is ",{"type":42,"tag":86,"props":8745,"children":8747},{"className":8746},[],[8748],{"type":48,"value":336},{"type":42,"tag":76,"props":8750,"children":8752},{"className":8751},[8681],[8753,8756],{"type":42,"tag":1776,"props":8754,"children":8755},{"disabled":37,"type":8685},[],{"type":48,"value":8757}," Follows eve filesystem conventions (tool filename = tool name, one tool per file)",{"type":42,"tag":76,"props":8759,"children":8761},{"className":8760},[8681],[8762,8765,8767,8772],{"type":42,"tag":1776,"props":8763,"children":8764},{"disabled":37,"type":8685},[],{"type":48,"value":8766}," Every tool has an ",{"type":42,"tag":86,"props":8768,"children":8770},{"className":8769},[],[8771],{"type":48,"value":5995},{"type":48,"value":8773},"; outputs are JSON-serializable with secrets redacted",{"type":42,"tag":76,"props":8775,"children":8777},{"className":8776},[8681],[8778,8781],{"type":42,"tag":1776,"props":8779,"children":8780},{"disabled":37,"type":8685},[],{"type":48,"value":8782}," Non-idempotent side effects are idempotent or approval-gated (replay + at-least-once delivery)",{"type":42,"tag":76,"props":8784,"children":8786},{"className":8785},[8681],[8787,8790,8792,8797,8799],{"type":42,"tag":1776,"props":8788,"children":8789},{"disabled":37,"type":8685},[],{"type":48,"value":8791}," Connector trigger path is ",{"type":42,"tag":86,"props":8793,"children":8795},{"className":8794},[],[8796],{"type":48,"value":2080},{"type":48,"value":8798}," and was attached with ",{"type":42,"tag":86,"props":8800,"children":8802},{"className":8801},[],[8803],{"type":48,"value":2529},{"type":42,"tag":76,"props":8805,"children":8807},{"className":8806},[8681],[8808,8811,8812,8817],{"type":42,"tag":1776,"props":8809,"children":8810},{"disabled":37,"type":8685},[],{"type":48,"value":5002},{"type":42,"tag":86,"props":8813,"children":8815},{"className":8814},[],[8816],{"type":48,"value":4301},{"type":48,"value":8818}," replaced before production deploy",{"type":42,"tag":76,"props":8820,"children":8822},{"className":8821},[8681],[8823,8826,8828,8833],{"type":42,"tag":1776,"props":8824,"children":8825},{"disabled":37,"type":8685},[],{"type":48,"value":8827}," Model config uses a Gateway string ID (",{"type":42,"tag":86,"props":8829,"children":8831},{"className":8830},[],[8832],{"type":48,"value":709},{"type":48,"value":8834}," default)",{"type":42,"tag":636,"props":8836,"children":8837},{},[],{"type":42,"tag":104,"props":8839,"children":8841},{"id":8840},"vercel-kb-guides",[8842],{"type":48,"value":8843},"Vercel KB Guides",{"type":42,"tag":51,"props":8845,"children":8846},{},[8847],{"type":48,"value":8848},"Verified guides on the Vercel Knowledge Base for deeper walkthroughs:",{"type":42,"tag":72,"props":8850,"children":8851},{},[8852,8864,8876,8886,8898,8918,8930,8942,8954],{"type":42,"tag":76,"props":8853,"children":8854},{},[8855,8862],{"type":42,"tag":4067,"props":8856,"children":8859},{"href":8857,"rel":8858},"https:\u002F\u002Fvercel.com\u002Fkb\u002Feve",[4071],[8860],{"type":48,"value":8861},"eve hub on the Vercel KB",{"type":48,"value":8863}," - all eve guides and templates in one place",{"type":42,"tag":76,"props":8865,"children":8866},{},[8867,8874],{"type":42,"tag":4067,"props":8868,"children":8871},{"href":8869,"rel":8870},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Feve-slack-agent-starter",[4071],[8872],{"type":48,"value":8873},"Build your first Slack agent with eve",{"type":48,"value":8875}," - the end-to-end starter this skill's wizard mirrors",{"type":42,"tag":76,"props":8877,"children":8878},{},[8879,8884],{"type":42,"tag":4067,"props":8880,"children":8882},{"href":8655,"rel":8881},[4071],[8883],{"type":48,"value":68},{"type":48,"value":8885}," - credential brokering concepts, connectors, tokens, and trigger forwarding",{"type":42,"tag":76,"props":8887,"children":8888},{},[8889,8896],{"type":42,"tag":4067,"props":8890,"children":8893},{"href":8891,"rel":8892},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fbuild-a-slack-bot-with-vercel-connect",[4071],[8894],{"type":48,"value":8895},"Build a Slack bot with Vercel Connect",{"type":48,"value":8897}," - Connect + Slack fundamentals (scopes, trigger events, webhook verification)",{"type":42,"tag":76,"props":8899,"children":8900},{},[8901,8908,8910,8916],{"type":42,"tag":4067,"props":8902,"children":8905},{"href":8903,"rel":8904},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fhow-to-add-eve-tools",[4071],[8906],{"type":48,"value":8907},"How to add eve tools",{"type":48,"value":8909}," - ",{"type":42,"tag":86,"props":8911,"children":8913},{"className":8912},[],[8914],{"type":48,"value":8915},"defineTool",{"type":48,"value":8917}," patterns",{"type":42,"tag":76,"props":8919,"children":8920},{},[8921,8928],{"type":42,"tag":4067,"props":8922,"children":8925},{"href":8923,"rel":8924},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fhow-to-add-eve-skills",[4071],[8926],{"type":48,"value":8927},"How to add eve skills",{"type":48,"value":8929}," - load-on-demand instructions",{"type":42,"tag":76,"props":8931,"children":8932},{},[8933,8940],{"type":42,"tag":4067,"props":8934,"children":8937},{"href":8935,"rel":8936},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Fgithub-agent-vercel-connect",[4071],[8938],{"type":48,"value":8939},"Build a GitHub agent with Vercel Connect",{"type":48,"value":8941}," - app-scoped Connect tokens in authored tools",{"type":42,"tag":76,"props":8943,"children":8944},{},[8945,8952],{"type":42,"tag":4067,"props":8946,"children":8949},{"href":8947,"rel":8948},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Flinear-agent-vercel-connect",[4071],[8950],{"type":48,"value":8951},"Build a Linear agent with Vercel Connect",{"type":48,"value":8953}," - MCP connections with user-scoped auth",{"type":42,"tag":76,"props":8955,"children":8956},{},[8957,8964],{"type":42,"tag":4067,"props":8958,"children":8961},{"href":8959,"rel":8960},"https:\u002F\u002Fvercel.com\u002Fkb\u002Fguide\u002Feve-agent-with-resend",[4071],[8962],{"type":48,"value":8963},"Build an email agent with eve and Resend",{"type":48,"value":8965}," - a second channel example beyond Slack",{"type":42,"tag":8967,"props":8968,"children":8969},"style",{},[8970],{"type":48,"value":8971},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":8973,"total":770},[8974],{"slug":4,"name":4,"fn":5,"description":6,"org":8975,"tags":8976,"stars":22,"repoUrl":23,"updatedAt":24},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[8977,8978,8979],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":13,"slug":14,"type":15},{"items":8981,"total":9147},[8982,8998,9010,9022,9037,9054,9066,9077,9088,9101,9113,9132],{"slug":8983,"name":8983,"fn":8984,"description":8985,"org":8986,"tags":8987,"stars":8995,"repoUrl":8996,"updatedAt":8997},"agent-browser","automate browser interactions for AI agents","Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to \"open a website\", \"fill out a form\", \"click a button\", \"take a screenshot\", \"scrape data from a page\", \"test this web app\", \"login to a site\", \"automate browser actions\", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[8988,8989,8992],{"name":17,"slug":18,"type":15},{"name":8990,"slug":8991,"type":15},"Automation","automation",{"name":8993,"slug":8994,"type":15},"Browser Automation","browser-automation",38346,"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fagent-browser","2026-07-20T05:55:17.314329",{"slug":8999,"name":8999,"fn":9000,"description":9001,"org":9002,"tags":9003,"stars":8995,"repoUrl":8996,"updatedAt":9009},"agentcore","run browser automation on AWS Bedrock","Run agent-browser on AWS Bedrock AgentCore cloud browsers. Use when the user wants to use AgentCore, run browser automation on AWS, use a cloud browser with AWS credentials, or needs a managed browser session backed by AWS infrastructure. Triggers include \"use agentcore\", \"run on AWS\", \"cloud browser with AWS\", \"bedrock browser\", \"agentcore session\", or any task requiring AWS-hosted browser automation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9004,9005,9008],{"name":8990,"slug":8991,"type":15},{"name":9006,"slug":9007,"type":15},"AWS","aws",{"name":8993,"slug":8994,"type":15},"2026-07-17T06:08:33.665276",{"slug":9011,"name":9011,"fn":9012,"description":9013,"org":9014,"tags":9015,"stars":8995,"repoUrl":8996,"updatedAt":9021},"core","navigate and interact with web pages","Core agent-browser usage guide. Read this before running any agent-browser commands. Covers the snapshot-and-ref workflow, navigating pages, interacting with elements (click, fill, type, select), extracting text and data, taking screenshots, managing tabs, handling forms and auth, waiting for content, running multiple browser sessions in parallel, and troubleshooting common failures. Use when the user asks to interact with a website, fill a form, click something, extract data, take a screenshot, log into a site, test a web app, or automate any browser task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9016,9017,9018],{"name":17,"slug":18,"type":15},{"name":8993,"slug":8994,"type":15},{"name":9019,"slug":9020,"type":15},"Navigation","navigation","2026-07-26T05:47:42.378419",{"slug":9023,"name":9023,"fn":9024,"description":9025,"org":9026,"tags":9027,"stars":8995,"repoUrl":8996,"updatedAt":9036},"derive-client","reverse engineer internal APIs from browser traffic","Reverse-engineer a website's internal API by recording browser traffic into a HAR file, then generate a standalone client or CLI that calls the endpoints directly, with no browser needed after the first recording. Use when asked to \"derive a client\", \"build a CLI for \u003Csite>\", \"reverse engineer this site's API\", \"record network requests\", \"turn this site into an API\", or when the same site will be automated repeatedly and direct HTTP calls would beat driving the browser every time.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9028,9031,9032,9033],{"name":9029,"slug":9030,"type":15},"API Development","api-development",{"name":8990,"slug":8991,"type":15},{"name":8993,"slug":8994,"type":15},{"name":9034,"slug":9035,"type":15},"Web Scraping","web-scraping","2026-07-20T06:24:11.928835",{"slug":9038,"name":9038,"fn":9039,"description":9040,"org":9041,"tags":9042,"stars":8995,"repoUrl":8996,"updatedAt":9053},"dogfood","perform exploratory testing on web applications","Systematically explore and test a web application to find bugs, UX issues, and other problems. Use when asked to \"dogfood\", \"QA\", \"exploratory test\", \"find issues\", \"bug hunt\", \"test this app\u002Fsite\u002Fplatform\", or review the quality of a web application. Produces a structured report with full reproduction evidence -- step-by-step screenshots, repro videos, and detailed repro steps for every issue -- so findings can be handed directly to the responsible teams.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9043,9044,9047,9050],{"name":8993,"slug":8994,"type":15},{"name":9045,"slug":9046,"type":15},"Debugging","debugging",{"name":9048,"slug":9049,"type":15},"QA","qa",{"name":9051,"slug":9052,"type":15},"Testing","testing","2026-07-17T06:07:41.421482",{"slug":9055,"name":9055,"fn":9056,"description":9057,"org":9058,"tags":9059,"stars":8995,"repoUrl":8996,"updatedAt":9065},"electron","automate Electron desktop applications","Automate Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify, etc.) using agent-browser via Chrome DevTools Protocol. Use when the user needs to interact with an Electron app, automate a desktop app, connect to a running app, control a native app, or test an Electron application. Triggers include \"automate Slack app\", \"control VS Code\", \"interact with Discord app\", \"test this Electron app\", \"connect to desktop app\", or any task requiring automation of a native Electron application.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9060,9061,9062],{"name":17,"slug":18,"type":15},{"name":8993,"slug":8994,"type":15},{"name":9063,"slug":9064,"type":15},"Desktop","desktop","2026-07-17T06:08:28.007783",{"slug":21,"name":21,"fn":9067,"description":9068,"org":9069,"tags":9070,"stars":8995,"repoUrl":8996,"updatedAt":9076},"interact with Slack workspaces","Interact with Slack workspaces using browser automation. Use when the user needs to check unread channels, navigate Slack, send messages, extract data, find information, search conversations, or automate any Slack task. Triggers include \"check my Slack\", \"what channels have unreads\", \"send a message to\", \"search Slack for\", \"extract from Slack\", \"find who said\", or any task requiring programmatic Slack interaction.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9071,9072,9075],{"name":8993,"slug":8994,"type":15},{"name":9073,"slug":9074,"type":15},"Messaging","messaging",{"name":20,"slug":21,"type":15},"2026-07-17T06:08:27.679015",{"slug":9078,"name":9078,"fn":9079,"description":9080,"org":9081,"tags":9082,"stars":8995,"repoUrl":8996,"updatedAt":9087},"vercel-sandbox","run browser automation in Vercel Sandbox","Run agent-browser + Chrome inside Vercel Sandbox microVMs for browser automation from any Vercel-deployed app. Use when the user needs browser automation in a Vercel app (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.), wants to run headless Chrome without binary size limits, needs persistent browser sessions across commands, or wants ephemeral isolated browser environments. Triggers include \"Vercel Sandbox browser\", \"microVM Chrome\", \"agent-browser in sandbox\", \"browser automation on Vercel\", or any task requiring Chrome in a Vercel Sandbox.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9083,9084,9085,9086],{"name":8990,"slug":8991,"type":15},{"name":8993,"slug":8994,"type":15},{"name":9051,"slug":9052,"type":15},{"name":13,"slug":14,"type":15},"2026-07-17T06:08:28.349899",{"slug":9089,"name":9089,"fn":9090,"description":9091,"org":9092,"tags":9093,"stars":9098,"repoUrl":9099,"updatedAt":9100},"deploy-to-vercel","deploy applications to Vercel","Deploy applications and websites to Vercel. Use when the user requests deployment actions like \"deploy my app\", \"deploy and give me the link\", \"push this live\", or \"create a preview deployment\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9094,9097],{"name":9095,"slug":9096,"type":15},"Deployment","deployment",{"name":13,"slug":14,"type":15},28993,"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fagent-skills","2026-07-17T06:08:41.18374",{"slug":9102,"name":9102,"fn":9103,"description":9104,"org":9105,"tags":9106,"stars":9098,"repoUrl":9099,"updatedAt":9112},"vercel-cli-with-tokens","manage Vercel projects via CLI","Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. \"deploy to vercel\", \"set up vercel\", \"add environment variables to vercel\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9107,9110,9111],{"name":9108,"slug":9109,"type":15},"CLI","cli",{"name":9095,"slug":9096,"type":15},{"name":13,"slug":14,"type":15},"2026-07-17T06:08:41.84179",{"slug":9114,"name":9114,"fn":9115,"description":9116,"org":9117,"tags":9118,"stars":9098,"repoUrl":9099,"updatedAt":9131},"vercel-composition-patterns","implement scalable React composition patterns","React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9119,9122,9125,9128],{"name":9120,"slug":9121,"type":15},"Best Practices","best-practices",{"name":9123,"slug":9124,"type":15},"Frontend","frontend",{"name":9126,"slug":9127,"type":15},"React","react",{"name":9129,"slug":9130,"type":15},"UI Components","ui-components","2026-07-17T06:05:40.576913",{"slug":9133,"name":9133,"fn":9134,"description":9135,"org":9136,"tags":9137,"stars":9098,"repoUrl":9099,"updatedAt":9146},"vercel-optimize","optimize Vercel project performance and costs","Use for Vercel cost and performance optimization on deployed projects, especially Next.js, SvelteKit, Nuxt, and limited Astro apps. Collect Vercel metrics, usage, project config, and code scan results first; investigate only metric-backed candidates; produce ranked recommendations grounded in verified files and version-aware Vercel\u002Fframework docs. Trigger for Vercel bill reduction, slow or expensive routes, caching opportunities, Function Invocations, Build Minutes, Fast Data Transfer, Core Web Vitals, Bot Management, Fluid compute, or cost breakdown requests.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[9138,9141,9142,9145],{"name":9139,"slug":9140,"type":15},"Cost Optimization","cost-optimization",{"name":9095,"slug":9096,"type":15},{"name":9143,"slug":9144,"type":15},"Performance","performance",{"name":13,"slug":14,"type":15},"2026-07-17T06:04:08.327515",100]