Skip to content

Commit 87010be

Browse files
authored
Add Foreman integration guide to Vercel section (#510)
Add Foreman integration guide to Vercel section
1 parent 96a6369 commit 87010be

3 files changed

Lines changed: 85 additions & 6 deletions

File tree

docs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,9 @@
240240
"pages": [
241241
"integrations/vercel/overview",
242242
"integrations/vercel/ai-sdk",
243+
"integrations/vercel/marketplace",
243244
"integrations/vercel/eve-extension",
244-
"integrations/vercel/marketplace"
245+
"integrations/vercel/foreman"
245246
]
246247
},
247248
{

integrations/vercel/foreman.mdx

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: "Foreman"
3+
description: "Give your Foreman agent a Kernel cloud browser"
4+
---
5+
6+
## Overview
7+
8+
[Foreman](https://ask-foreman.dev) is a free, open-source software factory: specialized AI agents classify, plan, implement, and review work pulled from GitHub issues, Linear, CI failures, and more, then push draft PRs for a human to approve. Nothing ships without you — Foreman stops at the draft PR.
9+
10+
Foreman is built on [Vercel Eve](https://vercel.com/eve), so it mounts extensions the same way any Eve agent does.
11+
12+
### Foreman + Kernel
13+
14+
Mounting Kernel's [Eve extension](/integrations/vercel/eve-extension) gives Foreman's implementation agent a real cloud browser, so it can go beyond reading code to reproduce bugs and verify fixes in flows that only break behind authentication:
15+
16+
- **Sign-in, not just code review** — the agent drives an authenticated browser session to reproduce the bug the way a signed-in user would hit it.
17+
- **Per-user identity** — each teammate authenticates through their own Vercel Connect consent, so the browser acts as them rather than a shared credential.
18+
- **An approval gate** — Foreman parks its first browser action per session for the person driving it, before it acts inside a logged-in session.
19+
20+
Follow [Foreman's guide for adding the Kernel browser](https://ask-foreman.dev/recipes/add-the-kernel-browser) for the full recipe, including the shadowed connection and tool allowlist.
21+
22+
## Quickstart prompt
23+
24+
import { CopyPromptButton } from '/snippets/copy-prompt-button.jsx';
25+
26+
Paste this into your coding agent to add the Kernel browser to your Foreman repo. It registers the `@onkernel/eve-extension` mount, wires it to Vercel Connect instead of an API key, shadows the browser connection with an approval gate, and holds the tool allowlist to the seven tools it ships with.
27+
28+
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
29+
<CopyPromptButton
30+
prompt={`Help me customize the eve Software Factory template. I want to add KERNEL so the agent can drive a cloud browser, including signing in to sites through KERNEL's managed auth.
31+
32+
Ground truth first: read AGENTS.md in the repository root, read agent/extensions/github.ts as the in-repo example of an extension mount, and read https://www.kernel.sh/docs/integrations/vercel/eve-extension plus node_modules/eve/docs/extensions.md before writing code. Do not hand-write the mount if the registry provides it.
33+
34+
1. Run: eve add extension/kernel
35+
This installs @onkernel/eve-extension and writes a mount under agent/extensions/. The extension needs eve 0.25 or later and Node 24; the template ships both, but confirm in package.json rather than assuming. Show me the generated file before changing it.
36+
2. Configure the mount with Vercel Connect, not an API key: kernel({ connect: "kernel/kernel-mcp" }). Leave KERNEL_API_KEY unset everywhere, and tell me if you find it already set, because the extension falls back to it. If the generated file points at the older domain-based connector (mcp.onkernel.com/eve-extension), prefer the current registry form and say so.
37+
3. Convert the mount into a directory so the browser connection can carry an approval gate: agent/extensions/kernel/extension.ts holds the mount, and agent/extensions/kernel/connections/browser.ts shadows the extension's built-in browser connection. Use defineMcpClientConnection from eve/connections with url https://mcp.onkernel.com/mcp, auth connect("kernel/kernel-mcp") from @vercel/connect/eve, approval once() from eve/tools/approval, and tools.allow set to exactly the seven tools the extension mounts by default: manage_browsers, execute_playwright_code, computer_action, manage_auth_connections, manage_profiles, manage_proxies, manage_replays. Use allow, not block, so tools the server adds later stay undiscovered too.
38+
4. Do not add browser_curl, manage_credentials, exec_command, or manage_browser_pools to the allowlist. The extension ships them off to limit an autonomous agent's blast radius, and nothing in this factory needs them.
39+
5. Tell me the setup commands I need to run myself, and do not run them:
40+
vercel link, vercel connect create kernel --name kernel-mcp --connection-method mcp, vercel connect attach kernel/kernel-mcp.
41+
Tell me the --connection-method flag needs Vercel CLI 58.8.0 or later.
42+
6. Important: connect("kernel/kernel-mcp") is per-user consent, so each person authorizes in their own browser before their first tool call. Unattended factory runs (the factory label and the red-CI fix loop) have nobody to complete that flow. Confirm this in the eve connections docs, then tell me plainly which of Foreman's surfaces can and cannot use the browser.
43+
7. Do not mount this extension under agent/subagents/. Stations run in task mode and cannot park for a consent prompt, an approval card, or a sign-in hand-off. If I ask for it later, explain the failure mode before doing it.
44+
8. Explain the approval choice back to me instead of copying by reflex. once() parks the first browser action of a session for the person driving it, and agent/connections/linear.ts shows the predicate alternative. Say why a connection whose tools act inside logged-in sessions warrants a gate that this repo's read-oriented connections do not carry.
45+
46+
Finish by running pnpm validate and confirming 0 errors and 0 warnings, then run npx eve info and show me the kernel mount in the discovered surface with only the seven allowed tools. Do not deploy.
47+
48+
Full recipe, with the reasoning behind each step: https://ask-foreman.dev/recipes/add-the-kernel-browser`}
49+
/>
50+
<a
51+
href="https://ask-foreman.dev/recipes/add-the-kernel-browser"
52+
target="_blank"
53+
rel="noopener noreferrer"
54+
style={{
55+
display: 'inline-flex',
56+
alignItems: 'center',
57+
gap: '0.5rem',
58+
height: '56px',
59+
padding: '0 24px',
60+
fontSize: '0.9375rem',
61+
fontWeight: 500,
62+
letterSpacing: '0.01em',
63+
color: 'inherit',
64+
border: '1px solid currentColor',
65+
opacity: 0.7,
66+
textDecoration: 'none',
67+
fontFamily: 'inherit',
68+
}}
69+
>
70+
view the recipe ↗
71+
</a>
72+
</div>
73+
74+
## Related
75+
76+
- [Eve Extension](/integrations/vercel/eve-extension)
77+
- [Vercel Marketplace Integration](/integrations/vercel/marketplace)
78+
- [Managed Auth](/auth/overview)

snippets/copy-prompt-button.jsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
const { useState, useCallback } = React;
22

3-
export const CopyPromptButton = () => {
4-
const [copied, setCopied] = useState(false);
5-
6-
const prompt = `# Setup Kernel
3+
const DEFAULT_PROMPT = `# Setup Kernel
74
85
## Prerequisites
96
- Read the kernel-cli skill at https://github.com/kernel/skills/blob/main/plugins/kernel-cli/skills/kernel-cli/SKILL.md for reference on commands and capabilities.
@@ -30,6 +27,9 @@ export const CopyPromptButton = () => {
3027
- Tell the user they can use the live view immediately.
3128
- If browser creation fails, stop and ask the user for help.`;
3229

30+
export const CopyPromptButton = ({ prompt = DEFAULT_PROMPT, label = 'copy prompt' } = {}) => {
31+
const [copied, setCopied] = useState(false);
32+
3333
const handleCopy = useCallback(async () => {
3434
try {
3535
await navigator.clipboard.writeText(prompt);
@@ -92,7 +92,7 @@ export const CopyPromptButton = () => {
9292
<rect x="5.5" y="5.5" width="8" height="8" rx="1.5" />
9393
<path d="M10.5 5.5V3.5C10.5 2.67 9.83 2 9 2H3.5C2.67 2 2 2.67 2 3.5V9C2 9.83 2.67 10.5 3.5 10.5H5.5" />
9494
</svg>
95-
copy prompt
95+
{label}
9696
</>
9797
)}
9898
</button>

0 commit comments

Comments
 (0)