Skip to content
Merged
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
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<a href="https://x.com/rfgarcia"><img src="https://img.shields.io/twitter/follow/rfgarcia" alt="Follow @rfgarcia"></a>
</p>

A CLI tool to create the scaffolding for a new Kernel applications. This tool helps you get started with building browser automation applications using Kernel's platform.
A CLI tool to create the scaffolding for a new Kernel applications. This tool helps you get started with building browser automation applications using Kernel's platform.

## Features

Expand Down Expand Up @@ -52,30 +52,36 @@ create-kernel-app [app-name] [options]
### Examples

Create a TypeScript application with a sample app:

```bash
npx @onkernel/create-kernel-app my-app --language typescript --template sample-app
```

Create a Typescript application with Stagehand template:

```bash
npx @onkernel/create-kernel-app my-app --language typescript --template stagehand
```

Create a Typescript application with Computer Use template:

```bash
npx @onkernel/create-kernel-app my-app --language typescript --template computer-use
```

Create a Python application with a sample app:

```bash
npx @onkernel/create-kernel-app my-app --language python --template sample-app
```

Create a Python application with Browser Use template:

```bash
npx @onkernel/create-kernel-app my-app --language python --template browser-use
```
```

````

## Next Steps

Expand All @@ -84,18 +90,21 @@ After creating your application:
1. Navigate to your project directory:
```bash
cd my-app
```
````

2. Set up your environment:

- For TypeScript: `npm install`
- For Python: `uv venv && source .venv/bin/activate && uv sync`

3. Set your Kernel API key:

```bash
export KERNEL_API_KEY=<YOUR_API_KEY>
kernel login # or: export KERNEL_API_KEY=<YOUR_API_KEY>
```

4. Deploy your application:

```bash
# Typscript
kernel deploy index.ts # --env OPENAI_API_KEY=XXX if Stagehand; --env ANTHROPIC_API_KEY=XXX if Computer Use
Expand All @@ -107,6 +116,7 @@ kernel deploy main.py # --env OPENAI_API_KEY=XXX if Browser Use
If deploying an app that requires environment variables, make sure to [set them](https://docs.onkernel.com/launch/deploy#environment-variables) when you `deploy`.

5. Invoke your application:

```bash
# Typescript + Sample App
kernel invoke ts-basic get-page-title --payload '{"url": "https://www.google.com"}'
Expand Down Expand Up @@ -134,18 +144,19 @@ kernel invoke python-cua cua-task --payload '{"task": "Get current market price

These are the sample apps currently available when you run `npx @onkernel/create-kernel-app`:

| Template | Description | Framework | Query Parameters |
|----------|-------------|-----------|------------------|
| **sample-app** | Returns the page title of a specified URL | Playwright | `{ url }` |
| **browser-use** | Completes a specified task | Browser Use | `{ task }` |
| **stagehand** | Returns the first result of a specified Google search | Stagehand | `{ query }` |
| **advanced-sample** | Implements sample apps using advanced Kernel configs | n/a |
| **computer-use** | Implements a prompt loop | Anthropic Computer Use API | `{ query }` |
| **cua** | Implements the OpenAI Computer Using Agent (CUA) | OpenAI CUA | `{ task }` |
| Template | Description | Framework | Query Parameters |
| ------------------- | ----------------------------------------------------- | -------------------------- | ---------------- |
| **sample-app** | Returns the page title of a specified URL | Playwright | `{ url }` |
| **browser-use** | Completes a specified task | Browser Use | `{ task }` |
| **stagehand** | Returns the first result of a specified Google search | Stagehand | `{ query }` |
| **advanced-sample** | Implements sample apps using advanced Kernel configs | n/a |
| **computer-use** | Implements a prompt loop | Anthropic Computer Use API | `{ query }` |
| **cua** | Implements the OpenAI Computer Using Agent (CUA) | OpenAI CUA | `{ task }` |

## Documentation

For more information about Kernel and its features, visit:

- [Kernel Documentation](https://docs.onkernel.com/quickstart)
- [Kernel Homepage](https://onkernel.com)

Expand All @@ -156,4 +167,3 @@ Contributions are welcome! Please feel free to submit a pull request. See [Contr
## License

MIT © [Kernel](https://onkernel.com)

55 changes: 23 additions & 32 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ const TEMPLATES: Record<TemplateKey, TemplateInfo> = {
},
[TEMPLATE_ADVANCED_SAMPLE]: {
name: "Advanced Samples",
description:
"Implements sample actions with advanced Kernel configs",
description: "Implements sample actions with advanced Kernel configs",
languages: [LANGUAGE_TYPESCRIPT, LANGUAGE_PYTHON],
},
[TEMPLATE_COMPUTER_USE]: {
Expand All @@ -91,8 +90,7 @@ const INVOKE_SAMPLES: Record<
'kernel invoke ts-basic get-page-title --payload \'{"url": "https://www.google.com"}\'',
[TEMPLATE_STAGEHAND]:
'kernel invoke ts-stagehand stagehand-task --payload \'{"query": "Best wired earbuds"}\'',
[TEMPLATE_ADVANCED_SAMPLE]:
'kernel invoke ts-advanced test-captcha-solver',
[TEMPLATE_ADVANCED_SAMPLE]: "kernel invoke ts-advanced test-captcha-solver",
[TEMPLATE_COMPUTER_USE]:
'kernel invoke ts-cu cu-task --payload \'{"query": "Return the first url of a search result for NYC restaurant reviews Pete Wells"}\'',
[TEMPLATE_CUA]:
Expand All @@ -104,7 +102,7 @@ const INVOKE_SAMPLES: Record<
[TEMPLATE_BROWSER_USE]:
'kernel invoke python-bu bu-task --payload \'{"task": "Compare the price of gpt-4o and DeepSeek-V3"}\'',
[TEMPLATE_ADVANCED_SAMPLE]:
'kernel invoke python-advanced test-captcha-solver',
"kernel invoke python-advanced test-captcha-solver",
[TEMPLATE_COMPUTER_USE]:
'kernel invoke python-cu cu-task --payload \'{"query": "Return the first url of a search result for NYC restaurant reviews Pete Wells"}\'',
[TEMPLATE_CUA]:
Expand All @@ -117,28 +115,18 @@ const REGISTERED_APP_NAMES: Record<
Partial<Record<TemplateKey, string>>
> = {
[LANGUAGE_TYPESCRIPT]: {
[TEMPLATE_SAMPLE_APP]:
'ts-basic',
[TEMPLATE_STAGEHAND]:
'ts-stagehand',
[TEMPLATE_ADVANCED_SAMPLE]:
'ts-advanced',
[TEMPLATE_COMPUTER_USE]:
'ts-cu',
[TEMPLATE_CUA]:
'ts-cua',
[TEMPLATE_SAMPLE_APP]: "ts-basic",
[TEMPLATE_STAGEHAND]: "ts-stagehand",
[TEMPLATE_ADVANCED_SAMPLE]: "ts-advanced",
[TEMPLATE_COMPUTER_USE]: "ts-cu",
[TEMPLATE_CUA]: "ts-cua",
},
[LANGUAGE_PYTHON]: {
[TEMPLATE_SAMPLE_APP]:
'python-basic',
[TEMPLATE_BROWSER_USE]:
'python-bu',
[TEMPLATE_ADVANCED_SAMPLE]:
'python-advanced',
[TEMPLATE_COMPUTER_USE]:
'python-cu',
[TEMPLATE_CUA]:
'python-cua',
[TEMPLATE_SAMPLE_APP]: "python-basic",
[TEMPLATE_BROWSER_USE]: "python-bu",
[TEMPLATE_ADVANCED_SAMPLE]: "python-advanced",
[TEMPLATE_COMPUTER_USE]: "python-cu",
[TEMPLATE_CUA]: "python-cua",
},
};

Expand Down Expand Up @@ -311,14 +299,14 @@ function copyTemplateFiles(
fs.copySync(templatePath, appPath, {
filter: (src, dest) => {
const filename = path.basename(src);
if (filename === '_gitignore') {
if (filename === "_gitignore") {
fs.copyFileSync(src, dest);
// Rename it to .gitignore
fs.renameSync(dest, path.join(path.dirname(dest), '.gitignore'));
fs.renameSync(dest, path.join(path.dirname(dest), ".gitignore"));
return false; // Skip the original copy since we handled it
}
return true; // Copy all other files normally
}
},
});
}

Expand Down Expand Up @@ -363,15 +351,18 @@ function printNextSteps(
): void {
// Determine which sample command to show based on language and template
const deployCommand =
language === LANGUAGE_TYPESCRIPT && (template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_ADVANCED_SAMPLE)
language === LANGUAGE_TYPESCRIPT &&
(template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_ADVANCED_SAMPLE)
? "kernel deploy index.ts"
: language === LANGUAGE_TYPESCRIPT && template === TEMPLATE_STAGEHAND
? "kernel deploy index.ts --env OPENAI_API_KEY=XXX"
: language === LANGUAGE_TYPESCRIPT && template === TEMPLATE_COMPUTER_USE
? "kernel deploy index.ts --env ANTHROPIC_API_KEY=XXX"
: language === LANGUAGE_TYPESCRIPT && template === TEMPLATE_CUA
? "kernel deploy index.ts --env OPENAI_API_KEY=XXX"
: language === LANGUAGE_PYTHON && (template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_ADVANCED_SAMPLE)
: language === LANGUAGE_PYTHON &&
(template === TEMPLATE_SAMPLE_APP ||
template === TEMPLATE_ADVANCED_SAMPLE)
? "kernel deploy main.py"
: language === LANGUAGE_PYTHON && template === TEMPLATE_BROWSER_USE
? "kernel deploy main.py --env OPENAI_API_KEY=XXX"
Expand All @@ -388,11 +379,11 @@ function printNextSteps(
Next steps:
brew install onkernel/tap/kernel
cd ${appName}
export KERNEL_API_KEY=<YOUR_API_KEY>
kernel login # or: export KERNEL_API_KEY=<YOUR_API_KEY>
${deployCommand}
${INVOKE_SAMPLES[language][template]}
# Do this in a separate tab
export KERNEL_API_KEY=<YOUR_API_KEY>
kernel login # or: export KERNEL_API_KEY=<YOUR_API_KEY>
kernel logs ${REGISTERED_APP_NAMES[language][template]} --follow
`)
);
Expand Down
4 changes: 2 additions & 2 deletions templates/python/advanced-sample/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
None

Invoke this via CLI:
export KERNEL_API_KEY=<your_api_key>
kernel login # or: export KERNEL_API_KEY=<your_api_key>
kernel deploy main.py # If you haven't already deployed this app
kernel invoke py-advanced test_captcha_solver
kernel logs py-advanced -f # Open in separate tab
Expand All @@ -36,7 +36,7 @@ async def test_captcha_solver(ctx: kernel.KernelContext) -> None:
page = context.pages[0] if context.pages else await context.new_page()

# Access the live view. Retrieve this live_view_url from the Kernel logs in your CLI:
# export KERNEL_API_KEY=<Your API key>
# kernel login # or: export KERNEL_API_KEY=<Your API key>
# kernel logs py-advanced --follow
print("Kernel browser live view url: ", kernel_browser.browser_live_view_url)

Expand Down
2 changes: 1 addition & 1 deletion templates/python/cua/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Returns:
An answer to the task, elapsed time and optionally the messages stack
Invoke this via CLI:
export KERNEL_API_KEY=<your_api_key>
kernel login # or: export KERNEL_API_KEY=<your_api_key>
kernel deploy main.py -e OPENAI_API_KEY=XXXXX --force
kernel invoke python-cua cua-task -p '{"task":"go to https://news.ycombinator.com and list top 5 articles"}'
kernel logs python-cua -f # Open in separate tab
Expand Down
4 changes: 2 additions & 2 deletions templates/python/sample-app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Returns:
A dictionary containing the page title
Invoke this via CLI:
export KERNEL_API_KEY=<your_api_key>
kernel login # or: export KERNEL_API_KEY=<your_api_key>
kernel deploy main.py # If you haven't already deployed this app
kernel invoke python-basic get-page-title -p '{"url": "https://www.google.com"}'
kernel logs python-basic -f # Open in separate tab
Expand Down Expand Up @@ -74,7 +74,7 @@ async def get_page_title(ctx: kernel.KernelContext, input_data: PageTitleInput)
Returns:
A dictionary containing the browser live view url
Invoke this via CLI:
export KERNEL_API_KEY=<your_api_key>
kernel login # or: export KERNEL_API_KEY=<your_api_key>
kernel deploy main.py # If you haven't already deployed this app
kernel invoke python-basic create-persisted-browser
kernel logs python-basic -f # Open in separate tab
Expand Down
22 changes: 12 additions & 10 deletions templates/typescript/advanced-sample/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@ const app = kernel.app("ts-advanced");
/**
* Example showing Kernel's auto-CAPTCHA solver
* Visit the live view url to see the Kernel browser auto-solve the CAPTCHA on the site
*
*
* Args:
* ctx: Kernel context containing invocation information
* Returns:
* None
*
*
* Invoke this via CLI:
* export KERNEL_API_KEY=<your_api_key>
* kernel login # or: export KERNEL_API_KEY=<your_api_key>
* kernel deploy index.ts # If you haven't already deployed this app
* kernel invoke ts-advanced test-captcha-solver
* kernel logs ts-advanced -f # Open in separate tab
*/
app.action("test-captcha-solver", async(ctx: KernelContext): Promise<void> => {

app.action("test-captcha-solver", async (ctx: KernelContext): Promise<void> => {
const kernelBrowser = await kernel.browsers.create({
invocation_id: ctx.invocation_id,
stealth: true,
Expand All @@ -32,15 +31,18 @@ app.action("test-captcha-solver", async(ctx: KernelContext): Promise<void> => {
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);

// Access the live view. Retrieve this live_view_url from the Kernel logs in your CLI:
// export KERNEL_API_KEY=<Your API key>
// kernel login # or: export KERNEL_API_KEY=<Your API key>
// kernel logs ts-advanced --follow
console.log("Kernel browser live view url: ", kernelBrowser.browser_live_view_url);
console.log(
"Kernel browser live view url: ",
kernelBrowser.browser_live_view_url
);

// Navigate to a site with a CAPTCHA
const context = await browser.contexts()[0] || (await browser.newContext());
const page = await context.pages()[0] || (await context.newPage());
const context = browser.contexts()[0] || (await browser.newContext());
const page = context.pages()[0] || (await context.newPage());
await page.waitForTimeout(10000); // Add a delay to give you time to visit the live view url
await page.goto("https://www.google.com/recaptcha/api2/demo");
// Watch Kernel auto-solve the CAPTCHA!
await browser.close();
});
});
2 changes: 1 addition & 1 deletion templates/typescript/cua/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if (!process.env.OPENAI_API_KEY) {
* Returns:
* An answer to the task, elapsed time and optionally the messages stack
* Invoke this via CLI:
* export KERNEL_API_KEY=<your_api_key>
* kernel login # or: export KERNEL_API_KEY=<your_api_key>
* kernel deploy index.ts -e OPENAI_API_KEY=XXXXX --force
* kernel invoke ts-cua cua-task -p "{\"task\":\"current market price range for a used dreamcast\"}"
* kernel logs ts-cua -f # Open in separate tab
Expand Down
Loading