# Coding Agents

> Build inference shell apps with AI coding assistants like Claude Code, Cursor, or Windsurf.

**URL:** https://inference.sh/docs/extend/coding-agents
**Last updated:** 2026-10-11

---

Build inference shell apps with AI coding assistants like Claude Code, Cursor, or Windsurf.

---

## Setup

### 1. Install CLI

```bash
curl -fsSL https://cli.inference.sh | sh
belt login
```

### 2. Create App

```bash
# Python app
belt app init my-app
cd my-app

# Or Node.js app
belt app init my-app --lang node
cd my-app
```

This creates your app with all the files needed, including **skills** that teach your coding agent how to build inference shell apps.

---

## Skills Included

When you run `belt app init`, the CLI creates a `skills/` directory containing guidance for AI coding assistants:

| Skill | What it teaches |
|-------|-----------------|
| `building-inferencesh-apps` | Overview, CLI commands |
| `writing-app-logic` | How to write inference.py / inference.js |
| `configuring-resources` | How to set up inf.yml |
| `managing-secrets` | Handling API keys |
| `using-oauth-integrations` | Google Sheets, Drive |
| `tracking-usage` | Output metadata for billing |
| `handling-cancellation` | Graceful task cancellation |
| `optimizing-performance` | Best practices |
| `debugging-issues` | Troubleshooting |

---

## How It Works

1. **You describe what you want** — Tell your coding agent what app to build
2. **Agent reads skills** — The agent uses the skills to understand inference shell patterns
3. **Agent writes code** — Creates inference.py, updates inf.yml, adds dependencies
4. **Test locally** — Run `belt app test` to verify
5. **Deploy** — Run `belt app deploy` to publish

---

## Example Prompts

```
Create an image resizing app that takes an image and dimensions, 
and returns the resized image.
```

```
Build an LLM app that calls OpenAI's API. 
It should track token usage for billing.
```

```
Make a YouTube audio downloader that extracts audio from videos 
and returns MP3 files.
```

---

## Supported Agents

The skills work with any AI coding assistant that supports project-level context. `belt plugin install` wires belt into all of them in one step:

- **Claude Code** and **Codex** — plugin marketplace (see below)
- **Copilot CLI, Cursor, Droid, Gemini CLI, Goose, Grok, Hermes, Kilo, Kimi, Kiro, Oh My Pi, OpenCode, Pi, Qwen Code, Windsurf** — hooks, skills, and a belt section in the agent's instruction file

---

## Other agent runtimes (`belt plugin install`)

```bash
belt login
belt plugin install            # every agent installed on this machine
belt plugin install grok kiro  # or name them
belt plugin status             # which detected agents have belt hooks (user, project, or none)
```

Not every agent lets a hook hand text back to the model on each prompt. Goose hooks are observation-only, Cursor's headless `agent -p` runs the prompt hook only when Cursor's backend asks for it, Droid runs it only in its TUI and `droid exec -o stream-jsonrpc`, Grok reads a prompt hook's output only for a block decision, and Windsurf hooks return an exit code only. There, the instruction-file section, the skills, and `belt suggest` on demand carry belt instead.

Each install writes five core belt skills (`suggest`, `skill`, `apps`, `remember`, `belt`) into the agent's skills directory, a hooks config with event names that match that runtime, and a belt section in the agent's instruction file. Skills are downloaded from inference shell when you are logged in; embedded copies are used when you are not logged in, offline, or the download fails. Claude Code and Codex use their plugin marketplaces instead of a direct hooks install; see [Claude Code plugin](#claude-code-plugin) and [Codex plugin](#codex-plugin).

| Agent | Skills directory | Hooks config | Instruction file |
|-------|------------------|--------------|------------------|
| claude | `~/.claude/skills/` (plugin) | `~/.claude/settings.json` (plugin) | `~/.claude/CLAUDE.md` |
| codex | `~/.agents/skills/` | `~/.codex/hooks.json` (plugin when `codex` is on PATH) | `~/.codex/AGENTS.md` |
| copilot | `~/.copilot/skills/` | `~/.copilot/hooks/belt.json` | `~/.copilot/instructions/belt.instructions.md` |
| cursor | `~/.cursor/skills/` | `~/.cursor/hooks.json` | — (Cursor Settings → Rules) |
| droid | `~/.factory/skills/` | `~/.factory/hooks.json` | `~/.factory/AGENTS.md` |
| gemini | `~/.gemini/skills/` | `~/.gemini/settings.json` | `~/.gemini/GEMINI.md` |
| goose | `~/.config/goose/skills/` | `~/.agents/plugins/belt/hooks/hooks.json` | `~/.config/goose/.goosehints` |
| grok | `~/.grok/skills/` | `~/.grok/hooks/belt.json` | `~/.grok/AGENTS.md` |
| hermes | `~/.hermes/skills/` | `~/.hermes/config.yaml` | — (SOUL.md is identity only) |
| kilo | `~/.kilocode/skills/` | `~/.kilo/plugins/belt.ts` | `~/.kilocode/rules/belt.md` |
| kimi | `~/.kimi-code/skills/` | `~/.kimi-code/config.toml` | `~/.kimi-code/AGENTS.md` |
| kiro | `~/.kiro/skills/` | `~/.kiro/agents/belt.json`, selected with `chat.defaultAgent` | `~/.kiro/steering/belt.md` |
| omp | `~/.omp/agent/skills/` | `~/.omp/agent/extensions/belt.ts` | `~/.omp/agent/AGENTS.md` |
| opencode | `~/.config/opencode/skills/` | `~/.config/opencode/plugins/belt.ts` | `~/.config/opencode/AGENTS.md` |
| pi | `~/.pi/agent/skills/` | `~/.pi/agent/extensions/belt.ts` | `~/.pi/agent/AGENTS.md` |
| qwen | `~/.qwen/skills/` | `~/.qwen/settings.json` | `~/.qwen/QWEN.md` |
| windsurf | `~/.codeium/windsurf/skills/` | `~/.codeium/windsurf/hooks.json` | `~/.codeium/windsurf/memories/global_rules.md` |

**Goose:** Belt writes hooks under `~/.agents/plugins/belt/hooks/` and skills under `~/.config/goose/skills/`. It does not write `plugin.json` — Goose discovers the plugin by directory convention, and a malformed manifest (especially component paths that do not start with `./`) can make belt skills vanish from `goose skills list` with no error while hooks keep running. `belt plugin uninstall goose` removes hooks and skills but does not touch a hand-written `plugin.json`. Reinstalling migrates hooks from the legacy `~/.agents/plugins/belt-test/` path.

**Lifecycle hooks** installed by `belt plugin install`:

| Hook event | Belt command | Purpose |
|------------|--------------|---------|
| SessionStart (codex, cursor) | `belt plugin hook session-start` (plugin) or `belt me` (manual Cursor) | Show account email when logged in; start [device authorization](/docs/api/rest/device-auth) when not |
| Prompt submit | `belt suggest --json` | Inject relevant skills, knowledge, and apps into context |
| Stop (or agent-specific end event) | `belt review --agent <name> --trigger stop` | Evaluate the session for knowledge worth saving (every 10 user turns by default) |
| PreCompact (codex, cursor only) | `belt review --agent <name> --trigger precompact --force` | Capture knowledge before context compaction |

**SessionStart (plugin installs):** Claude Code and Codex (marketplace plugin) call `belt plugin hook session-start`. When you are logged in, the hook prints your account email. When you are not (including anonymous guest sessions with no API key), it opens a browser for [device authorization](/docs/api/rest/device-auth), prints the approval URL and user code into session context, and polls for up to 45 seconds. A 6-hour cooldown (`~/.inferencesh/hook-auth-cooldown`) prevents reopening the browser on every session. **Cursor (manual install)** uses a lighter check: `belt me` output or a login reminder.

For non-Claude agents, review reads the session transcript from hook stdin. Extraction prefers a local agent CLI on your PATH (`codex`, `gemini`, `grok`, or `claude`) so it can ride your existing subscription; when none is available, it falls back to the inference shell API (paid). Claude Code uses a richer pipeline (fork-based extraction and optional skill auto-publish) — see [Claude Code plugin](#claude-code-plugin) below.

If a hooks file already exists, manual init skips overwriting it (delete the file to reinstall). After init, follow the CLI message — restart Cursor, OpenCode, Pi, or Windsurf when prompted. OpenCode init runs `npm install` in the plugin directory and `opencode plugin --global` when the OpenCode CLI is on your PATH. Pi init runs `pi install` on the extension when the Pi CLI is on your PATH.

### Hook data and privacy

Before installing, `belt plugin install` prints what belt hooks send upstream:

| Sent | Purpose |
|------|---------|
| Prompt text as the suggest `query`, plus up to 1,000 characters of the assistant's previous reply as `context` | Semantic search for matching skills, knowledge, and apps. Keyword matching uses the prompt only; the API embeds query then context so the prompt drives the vector. The prompt is stored with the suggestion record. |
| Scope tags: git remote, module, languages, working directory, hostname | Scoping suggestions to the project |
| Session-end telemetry (`POST /session/end`, when logged in) | Aggregate counts only: user turns, conversation messages (not every JSONL line), files edited, and tool names. No working directory, file paths, prompts, replies, or summary text. See [Session end](/docs/api/rest/search#session-end-belt-plugin-telemetry). |
| Conversation turns, only when no local agent CLI is available | Knowledge extraction at session end (see above) |

**Never sent:** file contents or secrets. Hook input excerpts are logged locally to `~/.belt/hooks.log`.

Traffic is encrypted (TLS 1.2+). See [privacy](https://inference.sh/privacy) and [trust](https://inference.sh/trust). Run `belt plugin info` for the per-hook upstream data table (Claude Code plugin) and compliance details.

### Disabling hooks

Disable belt hooks for a project tree by adding `.beltsh/config.json` at the repo root (the CLI walks up from CWD like `.git`):

```json
{
  "hooks_disabled": true,
  "suggest_disabled": true,
  "knowledge_disabled": true
}
```

| Field | Effect |
|-------|--------|
| `hooks_disabled` | Disables all plugin hooks for this project |
| `suggest_disabled` | Disables prompt-time skill/knowledge/app suggestions only |
| `knowledge_disabled` | Disables session-end knowledge extraction only |

Quick disable everywhere: `BELT_NO_HOOKS=1` (or any truthy value except `0` / `false`).

→ [Using skills with other agents](/docs/skills/other-agents)

---

## Codex plugin

When the Codex CLI is on your PATH, `belt plugin install codex` uses the Codex plugin marketplace (same `belt-sh/skills` marketplace as Claude Code):

```bash
belt login
belt plugin install codex    # add marketplace + install plugin
```

`init` runs:

```bash
codex plugin marketplace add belt-sh/skills
codex plugin add belt@belt-sh-skills
```

This installs the full belt plugin — hooks, skills, bin scripts, agents, and rules — instead of the simplified manual install.

After install, run `/hooks` in Codex to review and trust belt hooks.

**Duplicate hook cleanup:** A successful plugin install removes belt hook entries from `~/.codex/hooks.json` if that file already exists (for example after an earlier fallback install when the Codex CLI was missing). The plugin's own `hooks.json` manages belt hooks, so leaving both would run each hook twice. Non-belt entries in the global file are preserved; if every entry was belt-related, the global file is deleted. The CLI prints which path was updated.

**Requires Codex CLI:** If the `codex` command is not on your PATH, `belt plugin install codex` prints an error with a link to install the Codex CLI. The install then falls back to writing skills and `~/.codex/hooks.json` directly.

---

## Claude Code plugin

The belt CLI installs a **belt** plugin for [Claude Code](https://claude.ai/code) and **Cowork** (same hooks when `CLAUDE_CODE_IS_COWORK` is set). Hooks run in the background to suggest skills and apps, capture reusable knowledge, and optionally auto-publish skills from your sessions.

Use the `belt plugin` command group:

```bash
belt login
belt plugin install claude    # add marketplace + install plugin
belt plugin install claude --inject-rules   # also append belt rules to ~/.claude/CLAUDE.md
belt plugin info           # verify install and hook configuration
belt plugin doctor         # check plugin health (use --fix to auto-repair)
```

**Hook shims:** Plugin hook scripts in `bin/` are thin shims that delegate to `belt plugin hook <event>`. The marketplace cache can serve older hook scripts with embedded logic, so `belt plugin install claude` and `belt plugin doctor --fix` (when reinstalling) both scan Claude and Codex plugin caches and rewrite any stale hook scripts to shims immediately after install.

**Troubleshooting:** If hooks stop firing or Claude Code reports a missing plugin directory, run `belt plugin doctor`. It checks authentication, the plugin cache in Claude's `installed_plugins.json`, `hooks.json` inside the install path, that hook scripts in `bin/` are thin shims across Claude and Codex caches, and recent activity in `~/.belt/hooks.log`. With `--fix`, it reinstalls the belt plugin when the cache path is stale or missing (`claude plugin uninstall belt@belt-sh-skills`, then `claude plugin install belt`, with marketplace add as fallback), removes other stale cache directories, and patches hook scripts that still contain embedded logic. When no fixes are needed, doctor reports **All checks passed**; when `--fix` applies repairs, it lists each change (for example `fixed: removed stale cache dir abc123` or `fixed: patched hook-stop.sh in <hash>`) and then prompts a context-aware restart — inside Claude Code, **Run /reload-plugins or restart this session to apply changes**; from a regular terminal, **Restart your agent session to apply changes**.

Use `--inject-rules` when you want belt guidance in your user-level `CLAUDE.md` (persists across sessions and survives context compaction). If a belt section already exists, init replaces it.

After install, restart Claude Code or run `/reload-plugins`. Plugin slash commands include `/skill`, `/knowledge`, `/apps`, and `/suggest`.

| Hook | Belt command | Purpose |
|------|--------------|---------|
| SessionStart | `belt plugin hook session-start` | Show account email when logged in; run [device authorization](/docs/api/rest/device-auth) when not (browser + approval code in context, 45s poll, 6h cooldown) |
| UserPromptSubmit | `belt suggest --json` | Inject relevant skills, knowledge, and apps into context |
| Stop | `belt plugin review` (or `belt review --agent claude-code --trigger stop`) | Evaluate the session for knowledge worth saving (every 10 user turns by default) |
| SessionEnd | `belt plugin session-end` | When logged in, `POST /session/end` with aggregate telemetry (message and user-turn counts, files edited, tool names) — no transcript, paths, or prompts. See [Search API — Session end](/docs/api/rest/search#session-end-belt-plugin-telemetry). |

Claude Code review also runs fork-based extraction and can auto-publish reusable workflows as skills. Other agents use transcript-based extraction, preferring local CLIs (`codex`, `gemini`, `grok`) when installed — see [Other agent runtimes](#other-agent-runtimes-belt-plugin-install) above.

**Knowledge import** from existing Claude Code projects:

```bash
belt plugin history --dry-run   # preview ~/.claude/projects memory + skill signals
belt plugin history             # import memory files + skill usage (requires belt login)
belt plugin history --extract   # also mine transcripts with Haiku (~$3; requires login)
```

| Flag | Purpose |
|------|---------|
| `--dry-run` | Show what would be imported without saving |
| `--extract` | Mine session transcripts for knowledge Claude's native memory missed (uses Haiku, ~$3) |
| `--narratives` | With `--extract`, also process large session narratives (Haiku, ~$5–8 extra) |
| `--max-sessions N` | With `--narratives`, cap how many large sessions to process (`0` = all) |

**Tips and notices:** Contextual stderr tips after commands can be disabled with `INFSH_NO_TIPS=1`, by passing `--json` / `--pjson` (or `--jq` on `belt mcp run` / `belt app run`), or when stderr is not a terminal. Hook `tip:` lines inside `belt suggest --json` output are separate (rate-limited in `~/.belt/notices/`) and are not suppressed by those flags or `INFSH_NO_TIPS`.

**Bounty and survey notices:** The CLI stderr notice block loads active programs from `GET /bounties` (cached for 6 hours) and shows the highest-priority due notice — for example app-builder incentives, unanswered discovery surveys, or **bounty forms** (`proof_type: form`). Form programs prompt `belt bounty claim <program>` and stay visible until claimed on that machine. Notice text, cooldowns, and priority come from the API and update without a CLI release. Neither bounty nor survey prompts are injected into `belt suggest --json` hook context. In an agent runtime, only operator-facing survey questions and bounty forms surface in notices; other programs wait for a human terminal. Claim app bounties with `belt bounty claim app-builder <namespace/app-name>` after deploy (`belt app promo submit` is an alias); answer single-question surveys with `belt feedback <question-id> "answer"` or `belt feedback "open message"`; complete bounty forms with `belt bounty claim <program>` (use `--no-input` / `--data` in automation). See [CLI setup — Bounties](/docs/extend/cli-setup#bounties-cli), [CLI setup — App bounties](/docs/extend/cli-setup#app-bounties-cli), and [CLI setup — Feedback](/docs/extend/cli-setup#feedback-cli).

→ [Using skills with other agents](/docs/skills/other-agents) · [CLI setup](/docs/extend/cli-setup)

---

## Next

→ [CLI Setup](/docs/extend/cli-setup) — Manual CLI installation

→ [Creating an App](/docs/extend/creating-app) — Manual app creation
