Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/bright-messages-connect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"eve": patch
"@vercel/eve-catalog": patch
---

Add guided Photon setup through `eve add channel/photon`, including project creation, phone registration, Vercel Connect or portable credentials, and channel scaffolding.
69 changes: 17 additions & 52 deletions apps/docs/lib/integrations/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ const channelPresentations: Record<string, ChannelPresentation> = {
logo: "slack",
docsHref: "/docs/channels/slack",
keywords: ["chat", "messaging", "bot", "webhook"],
install: `The eve CLI scaffolds the channel for you. \`eve channels add slack\` writes \`agent/channels/slack.ts\`, adds \`@vercel/connect\`, and runs the Connect setup flow:
install: `The eve CLI scaffolds the channel for you. \`eve add channel/slack\` writes \`agent/channels/slack.ts\`, adds \`@vercel/connect\`, and runs the Connect setup flow:

\`\`\`bash
eve channels add slack
eve add channel/slack
\`\`\`

To wire it up by hand instead, install the framework and the Connect SDK. Slack channels use [Vercel Connect](https://vercel.com/docs/connect) for both the outbound bot token and inbound webhook verification:
Expand Down Expand Up @@ -314,7 +314,7 @@ export default linearChannel({
install: `The eve CLI scaffolds the full Next.js web chat app alongside \`agent/channels/eve.ts\`:

\`\`\`bash
eve channels add web
eve add channel/web
\`\`\`

To wire it up by hand instead, install the framework:
Expand Down Expand Up @@ -842,64 +842,29 @@ export default channel;
See the [Kapso adapter documentation](https://chat-sdk.dev/adapters/vendor-official/kapso) for supported events, capabilities, and credentials.`,
configure: `Connect a WhatsApp number in Kapso, set \`KAPSO_API_KEY\`, \`KAPSO_PHONE_NUMBER_ID\`, and \`KAPSO_WEBHOOK_SECRET\`, then point the Kapso webhook at \`/eve/v1/kapso\`. Use this provider-managed option when you do not want to integrate directly with the WhatsApp Cloud API. See the [Chat SDK channel docs](/docs/channels/chat-sdk) for eve session dispatch, state, streaming, and human-in-the-loop behavior.`,
},
"chat-sdk-photon": {
photon: {
logo: "photon",
docsHref: "/docs/channels/chat-sdk",
badge: "Provider official",
keywords: [
"chat sdk",
"imessage",
"apple messages",
"sms",
"mms",
"rcs",
"photon",
"sendblue",
"linq",
"agentphone",
"dial",
],
install: `Add this Chat SDK channel from eve's registry. This writes \`agent/channels/imessage.ts\` and installs Chat SDK and its adapter dependencies:
docsHref: "/docs/channels/photon",
badge: "First-party",
keywords: ["imessage", "apple messages", "photon", "sms", "phone"],
install: `Add Photon from eve's registry, then follow the guided project, phone, and deployment setup:

\`\`\`bash
eve add channel/chat-sdk-photon
eve add channel/photon
\`\`\``,
quickStart: `Create \`agent/channels/imessage.ts\`:
quickStart: `Create \`agent/channels/photon.ts\`:

\`\`\`ts
// agent/channels/imessage.ts
import { createiMessageAdapter } from "@photon-ai/chat-adapter-imessage";
import { createMemoryState } from "@chat-adapter/state-memory";
import type { Message, Thread } from "chat";
import { chatSdkChannel } from "eve/channels/chat-sdk";
import { connectPhotonCredentials } from "@vercel/connect/eve";
import { photonChannel } from "eve/channels/photon";

export const { bot, channel, send } = chatSdkChannel({
userName: "My Agent",
adapters: {
imessage: createiMessageAdapter({
local: false,
projectId: process.env.IMESSAGE_PROJECT_ID,
projectSecret: process.env.IMESSAGE_PROJECT_SECRET,
}),
},
state: createMemoryState(),
export default photonChannel({
credentials: connectPhotonCredentials(process.env.PHOTON_CONNECTOR_ID!),
});

bot.onNewMention(async (thread: Thread, message: Message) => {
await thread.subscribe();
await send(message.text, { thread });
});

bot.onSubscribedMessage(async (thread: Thread, message: Message) => {
await send(message.text, { thread });
});

export default channel;
\`\`\`

See the [Photon adapter documentation](https://chat-sdk.dev/adapters/vendor-official/photon) for all supported events and credentials.`,
configure: `Set \`IMESSAGE_PROJECT_ID\` and \`IMESSAGE_PROJECT_SECRET\`, then point Photon’s signed webhook at \`/eve/v1/imessage\`. Photon supports cloud, self-hosted, and local macOS deployments. See the [Chat SDK channel docs](/docs/channels/chat-sdk) for eve session dispatch, state, streaming, and human-in-the-loop behavior.`,
\`\`\``,
configure: `The guided setup can create a dedicated Photon project or use existing credentials, register your phone, and choose Vercel Connect or portable environment credentials. Connect-backed setup creates a native Photon connector and routes verified triggers to \`/eve/v1/photon\`; portable setup registers a signed Photon webhook directly.`,
},

"chat-sdk-dial": {
logo: "dial",
docsHref: "/docs/channels/chat-sdk",
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/lib/integrations/discovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("integration discovery", () => {
const markdown = integrationMarkdown(slack!);
expect(markdown).toContain("## Install");
expect(markdown).toContain("## Quick start");
expect(markdown).toContain("eve channels add slack");
expect(markdown).toContain("eve add channel/slack");
});

it("renders the Browserbase extension setup", () => {
Expand Down
17 changes: 17 additions & 0 deletions apps/docs/public/r/channel/photon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "channel/photon",
"type": "registry:item",
"title": "Photon",
"description": "Connect an eve agent to iMessage through Photon with guided project and phone setup.",
"dependencies": ["@vercel/connect@0.4.3"],
"meta": {
"eve": {
"setup": {
"command": "eve",
"args": ["integration", "setup", "photon"]
},
"requires": ">=0.27.11"
}
}
}
24 changes: 11 additions & 13 deletions apps/docs/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -1205,22 +1205,20 @@
]
},
{
"name": "channel/chat-sdk-photon",
"name": "channel/photon",
"type": "registry:item",
"title": "Photon",
"description": "Cloud, self-hosted, and local iMessage messaging through Photon.",
"dependencies": ["chat", "@photon-ai/chat-adapter-imessage", "@chat-adapter/state-memory"],
"envVars": {
"IMESSAGE_PROJECT_ID": "",
"IMESSAGE_PROJECT_SECRET": ""
},
"files": [
{
"path": "registry/channels/chat-sdk-photon.ts",
"type": "registry:file",
"target": "agent/channels/imessage.ts"
"description": "Connect an eve agent to iMessage through Photon with guided project and phone setup.",
"dependencies": ["@vercel/connect@0.4.3"],
"meta": {
"eve": {
"setup": {
"command": "eve",
"args": ["integration", "setup", "photon"]
},
"requires": ">=0.27.11"
}
]
}
},
{
"name": "channel/chat-sdk-dial",
Expand Down
27 changes: 0 additions & 27 deletions apps/docs/registry/channels/chat-sdk-photon.ts

This file was deleted.

14 changes: 8 additions & 6 deletions apps/docs/scripts/validate-channel-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const adapterDependenciesByCatalogSlug: Readonly<Record<string, string>> = {
"chat-sdk-liveblocks": "@liveblocks/chat-sdk-adapter",
"chat-sdk-linq": "@linqapp/chat-sdk-adapter",
"chat-sdk-kapso": "@kapso/chat-adapter",
"chat-sdk-photon": "@photon-ai/chat-adapter-imessage",
"chat-sdk-dial": "@getdial/chat-sdk-adapter",
"chat-sdk-agentphone": "@agentphone/chat-sdk-adapter",
"chat-sdk-lark": "@larksuite/vercel-chat-adapter",
Expand All @@ -63,7 +62,6 @@ const targetSlugsByCatalogSlug: Readonly<Record<string, string>> = {
"chat-sdk-liveblocks": "liveblocks",
"chat-sdk-linq": "linq",
"chat-sdk-kapso": "kapso",
"chat-sdk-photon": "imessage",
"chat-sdk-dial": "dial",
"chat-sdk-agentphone": "agentphone",
"chat-sdk-lark": "lark",
Expand Down Expand Up @@ -91,12 +89,16 @@ for (const [index, item] of items.entries()) {
if (entry === undefined) throw new Error(`Unexpected channel registry item "${item.name}".`);
const registrySlug = expectedSlugs[index];

if (entry.slug === "slack" || entry.slug === "eve") {
if (entry.slug === "slack" || entry.slug === "eve" || entry.slug === "photon") {
const setupKind = registrySlug;
const setup = item.meta?.eve?.setup;
const expectedArgs = ["integration", "setup", registrySlug];
if (setup?.command !== "eve" || JSON.stringify(setup.args) !== JSON.stringify(expectedArgs)) {
if (
(entry.slug !== "eve" && item.files !== undefined) ||
setup?.command !== "eve" ||
JSON.stringify(setup.args) !== JSON.stringify(["integration", "setup", setupKind])
) {
throw new Error(
`Registry item "${item.name}" must delegate setup to eve integration setup ${registrySlug}.`,
`Registry item "${item.name}" must delegate to eve integration setup ${setupKind}.`,
);
}
continue;
Expand Down
2 changes: 1 addition & 1 deletion docs/channels/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ agent/
intake.ts
```

Scaffold a channel file with `eve channels add` (interactive), or pass a kind: `eve channels add slack` or `eve channels add web`. You can also author the file by hand.
Install a channel from the registry with `eve add channel/photon`, `eve add channel/slack`, or `eve add channel/web`. You can also author the file by hand.

## The eve HTTP channel (default)

Expand Down
4 changes: 2 additions & 2 deletions docs/channels/slack.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The `create` step provisions a destination at the default Connect path. `detach`

## Add the channel

Scaffold the channel and its dependency with `eve channels add slack`, or set it up by hand:
Scaffold the channel and its dependency with `eve add channel/slack`, or set it up by hand:

```bash
npm install @vercel/connect
Expand All @@ -38,7 +38,7 @@ export default slackChannel({

`connectSlackCredentials` returns `{ botToken, webhookVerifier }`, keeping token rotation, multi-workspace tenancy, and request verification inside Connect rather than your code.

If eve cannot find an authenticated Vercel session, `eve channels add slack` asks whether to set up Vercel Connect or use portable environment credentials. The portable option adds the required names to `.env.example`. Before deploying, appropriate values must be supplied to your runtime environment.
If eve cannot find an authenticated Vercel session, `eve add channel/slack` asks whether to set up Vercel Connect or use portable environment credentials. The portable option adds the required names to `.env.example`. Before deploying, appropriate values must be supplied to your runtime environment.

### Deploy

Expand Down
8 changes: 1 addition & 7 deletions docs/guides/dev-tui.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ On startup the TUI prints a brand line with your agent's name, plus a rotating t

```text
eve weather-agent
Use /channels to add more ways to reach your agent.
```

If agent discovery reported problems, an error and warning count renders between the two lines. Instructions, tools, skills, and subagents are one `eve info` away, and `/help` lists every command. The TUI also runs a startup check. A fresh `eve init` starts local `eve dev` with `/model` prefilled. That input starts onboarding: the flow installs the Vercel CLI if needed, asks you to log in if needed, then opens `/model` before the first prompt. Other `eve dev` sessions show missing setup as an attention line, with each command's outcome hanging under it on a `⎿` connector.
Expand All @@ -35,7 +34,6 @@ Each command echoes as an invocation line, asks through a bordered panel that ta
| Command | Does |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/model` | Opens a configure menu that loops until Done (or Esc). See [Configure the model and provider](#configure-the-model-and-provider). |
| `/channels` | Shows the agent's channel list and adds the one you pick. See [Add a channel](#add-a-channel). |
| `/connect` | Shows the Vercel Connect MCP catalog and configures the server you pick. See [Add a connection](#add-a-connection). |
| `/deploy` | Ships the agent to Vercel production, linking the directory first when it is unlinked. |
| `/vc:install` | Installs the Vercel CLI. Available locally and on a remote session. |
Expand All @@ -45,7 +43,7 @@ Each command echoes as an invocation line, asks through a bordered panel that ta
| `/exit` | Quits the TUI. |
| `/help` | Lists the commands available for the current local or remote session. |

`/model`, `/channels`, `/connect`, and `/deploy` manage the local agent or its linked project. They are available only when `eve dev` runs the server locally, not when connected to a remote server with `--url`.
`/model`, `/connect`, and `/deploy` manage the local agent or its linked project. They are available only when `eve dev` runs the server locally, not when connected to a remote server with `--url`.

### Configure the model and provider

Expand All @@ -55,10 +53,6 @@ The provider row opens one menu: AI Gateway via a project, AI Gateway via `AI_GA

The provider row demands attention (a bold yellow "Configure model access" with a yellow "Not configured" hint that dims when unselected and uses the terminal foreground when selected) until a link or gateway credential is detected, then names the connection afterward (for example "AI Gateway (Linked to my-project in my-team)"). Setup menus mark the cursor row with a padded, filled-arrow inverse label that inherits the row's accent: blue normally and yellow for warning rows. In stacked menus, the selected row's description appears directly beneath that option. The completed command's outcome stays in the transcript after the panel closes. When a turn fails because AI Gateway authentication is missing or stale, the error points you at `/model` directly.

### Add a channel

`/channels` shows the agent's channel list. Already-registered channels render as checked, focusable rows with an "Already installed" hint. Picking one adds it (including the Slack Connect provisioning), then installs the dependencies the scaffold added so the dev server can load the new channels right away. After each addition the list repaints with the channel checked, until Done (or Esc) leaves the flow.

### Add a connection

`/connect` shows a searchable list of MCP servers available through Vercel Connect. Already-authored connections remain checked. Logged-out users are directed to `/vc:login`. When the directory is not linked, selecting a server opens the same team and project flow used by `/model`, including creating a project or linking an existing one.
Expand Down
20 changes: 3 additions & 17 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ The `eve` binary (`bin: eve`) runs from your app root, and every command first l
| `eve link` | Link the directory to a Vercel project and pull AI Gateway credentials |
| `eve deploy` | Deploy the agent to Vercel production (links first if needed) |
| `eve eval` | Run evals against the local app or a remote target |
| `eve channels add [kind]` | Scaffold a channel interactively, or by kind (`slack` \| `web`) |
| `eve channels list` | List user-authored channels |
| `eve extension init [target]` | Create a new extension package |
| `eve extension build` | Build the current package as an extension |
Expand All @@ -47,9 +46,9 @@ Creates a new agent app or adds an agent to an existing app. Always installs dep

After scaffolding, a human terminal usually continues into `eve dev` (or a coding-agent REPL if one is on `PATH` and you pick it). Coding-agent launches print the next steps instead of opening the TUI, so the session does not get stuck. Fresh projects use the parent workspace's package manager when there is one; otherwise they use the manager that launched `eve init`.

| Flag | Type | Default | Description |
| ---------------------- | ---- | ------- | ----------------------------------------------------------------------------------------------------- |
| `--channel-web-nextjs` | flag | off | Add the Web Chat app (Next.js). Not for existing projects — run `eve channels add web` there instead. |
| Flag | Type | Default | Description |
| ---------------------- | ---- | ------- | ---------------------------------------------------------------------------------------------------- |
| `--channel-web-nextjs` | flag | off | Add the Web Chat app (Next.js). Not for existing projects — run `eve add channel/web` there instead. |

## `eve extension`

Expand Down Expand Up @@ -291,19 +290,6 @@ Runs all discovered evals when no eval ids are given; ids match exactly or by di

See [Evals](../evals/overview) for authoring evals.

## `eve channels add`

```bash
eve channels add [kind] [-f] [-y]
```

Scaffolds a channel into `agent/channels/`. With no `kind` it prompts interactively; pass a `kind` (`slack` \| `web`) to scaffold one directly. When the Vercel CLI has an authenticated session, eve scaffolds the Vercel-integrated variant and asks whether to deploy after setup. Without one, Slack setup asks whether to set up Vercel Connect or use portable credentials. The portable variant reads `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` and adds both names to `.env.example`.

| Flag | Type | Default | Description |
| ------------- | ---- | ------- | --------------------------------------------------------- |
| `-f, --force` | flag | off | Overwrite existing channel files |
| `-y, --yes` | flag | off | Assume yes for confirmations; requires an explicit `kind` |

## `eve channels list`

```bash
Expand Down
Loading
Loading