Smoke logo

Smoke

Organization
nightly-labs
smoke

Start one or more local OpenBot dev instances and smoke test the features that the current changes or a pull request add. Use when asked to smoke test, QA, or check a change or PR in the real app, including two-client team flows, the browser client, and the iOS simulator.

Overview

Publishernightly-labs
Repositoryopenbot
Skill namesmoke
Stars
521
Forks
81
Bundled files
1
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by nightly-labs on GitHub. Read the source before you install it.

Installation

Install the Smoke AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/nightly-labs/openbot/tree/main/.agents/skills/smoke
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/nightly-labs/openbot.git /tmp/openbot
mkdir -p .claude/skills
cp -r /tmp/openbot/.agents/skills/smoke .claude/skills/smoke
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Smoke in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Smoke on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Smoke is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Smoke

Start the local dev stack for this worktree. Then drive the real app and prove that each feature in the change works. Report what passed, what failed, and what you did not check.

A smoke test does not replace tests or CI. Do not run broad checks here. AGENTS.md forbids them locally.

Before you start

  • Read AGENTS.md and the AGENTS.md of each directory in the change.
  • Run node --version. Node 24 is necessary.
  • Prefix each bun run dev* command with env -u ELECTRON_RUN_AS_NODE. An agent shell can leak this variable, and then Electron starts as Node.
  • In a fresh worktree, run bun run dev:bootstrap once. When it reports a missing .env.keys, copy the file from the main checkout. Do not create a new one.

Step 1 — Find what to test

Get the change set. Use the first source that applies:

  1. A PR number or URL: gh pr view <pr> --json title,body,headRefName,files and gh pr diff <pr> --name-only. Check out the PR branch in this worktree only when the user asks. Otherwise test the current branch.
  2. A branch: git diff --name-only $(git merge-base origin/main HEAD), plus git status --short for uncommitted work.

bun run dev:verify reads only uncommitted changes. Use it for setup and runtime state, not for the change set. Ignore the lint and typecheck entries in its commands.

Read the PR body and the diff. Write a short test plan before you start the app. Give each item a user action and an expected result:

#FeatureSurfaceActionExpected result
1Short namedesktop / test-client / web / mobileStepsVisible result

Include the reverse action for each state change: snooze/unsnooze, pause/resume, revoke/reconnect, mute/unmute. Include a restart when the change touches persisted state or migrations.

When a change has no user-visible behavior, such as a refactor, a test, or docs only, say so and stop. Do not start the app for it.

Step 2 — Choose the stack

Choose the smallest stack that covers the plan:

Plan needsCommand
Desktop renderer or main processbun run dev
Two clients: teams, invitations, sharing, Team APIbun run dev:test-client
Browser client at /app or public webbun run dev:api (add bun run dev when a desktop host is also necessary)
iOS appbun run dev:mobile

Rules:

  • Run bun run dev:status first. Reuse this worktree's stack when it is live. Do not start a second stack in the same worktree.
  • Never drive a stack or an app of a different worktree.
  • Start the stack with run_in_background. Wait for the ports that the supervisor prints, or poll bun run dev:status until the service is live. Use the ports that the stack reports, never a fixed port.
  • Do not pass --shared, so that the test does not change the shared OpenBot Dev profile. A new profile gets the showcase data of bun run dev:seed.
  • Do not run dev:reset, or dev:seed without --dry-run, on a profile that you did not create. Ask first.

Step 3 — Drive the app

Use bun run dev:automation for the desktop app and the test client:

bash
bun run dev:automation instances
bun run dev:automation pages
bun run dev:automation snapshot --wait-for=<role>,<name>
bun run dev:automation click --role=<role> --name=<name> --allow-mutations --instance=<id> --wait-for=<role>,<name>
bun run dev:automation type --role=<role> --name=<name> --text=<text> --allow-mutations --instance=<id>

Follow this loop for each plan item: snapshot → action with --wait-for → snapshot.

The accessibility snapshot is the evidence. Do not take screenshots by default: they cost more. Take one only when the user asks, when the result is visual (layout, color, animation, an image) and a snapshot cannot show it, or when the user asks for PR evidence. Then use bun run dev:automation screenshot --out=<name>.png.

  • Select elements by accessible role and name. When an element has no accessible name, record it as a finding. Do not add a test ID.
  • --page=<target-id|url-substring> selects a window or an embedded browser view. --service=test-client selects the second client.
  • Wait for a role, not for elapsed time.
  • dev:automation cannot close a window or run a script. For window lifecycle checks, use CDP on the instance's remoteDebuggingPort.
  • For the browser client, use the preview or Chrome DevTools tools on the URL that the stack reports.
  • For the iOS app, use the device tools to open the simulator. Take a simulator screenshot only when the result is visual.
  • For a restart check, stop only the stack you started with bun run dev:stop, then start it again with the same flags.

Also look for problems outside the plan: renderer console errors in the dev:automation stderr, errors in the stack log, and a UI that does not respond.

A provider turn uses the signed-in subscription. Send model turns only when the feature needs them, and keep the prompts short.

Step 4 — Clean up

  • Stop each stack you started with bun run dev:stop. Leave a stack that was live before you started.
  • Never kill by process pattern. Kill only a PID that you started.
  • Screenshots, if any, stay in .openbot-build/dev-automation/. Do not commit them.

Step 5 — Report

Give one table for the plan:

#FeatureResultEvidence
1Short namepass / fail / not checkedSnapshot text, log line, or screenshot path

Then give:

  • The stack and flags you used, and the surfaces you checked.
  • Each failure with the steps to reproduce it, the expected result, and the actual result.
  • Each item you did not check, and why. Examples: a real second computer, a paid provider, a production build, Windows or Linux.

Do not fix a failure unless the user asks. When the user asks for PR evidence, give the screenshot paths for before and after. Do not commit them.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Smoke AI skill do?

Start one or more local OpenBot dev instances and smoke test the features that the current changes or a pull request add. Use when asked to smoke test, QA, or check a change or PR in the real app, including two-client team flows, the browser client, and the iOS simulator.

Why use Smoke on TypingMind?

Because you install it once and use it with any model. Smoke is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Smoke in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/nightly-labs/openbot/tree/main/.agents/skills/smoke. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Smoke?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Smoke?

As many as you like. As long as a model supports skills, you can use Smoke with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Smoke AI skill free?

It is published on GitHub by nightly-labs. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇