# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

<!-- SKILL-MAP-START -->STOP. You WILL forget skill names mid-session. Check this map before ANY task.|brainstorming,ideation→Skill(superpowers:brainstorming)|planning,implementation-plan→Skill(superpowers:writing-plans)|execution,execute-plan→Skill(superpowers:executing-plans)|parallel-work,multiple-tasks→Skill(superpowers:dispatching-parallel-agents)|debugging,bug-investigation→Skill(superpowers:systematic-debugging)|code-review,post-implementation-review→Skill(superpowers:requesting-code-review)|tdd,test-first→Skill(superpowers:test-driven-development)|git-worktree,feature-branch→Skill(superpowers:using-git-worktrees)|finishing-branch,merge-prep→Skill(superpowers:finishing-a-development-branch)|verify-completion→Skill(superpowers:verification-before-completion)|self-audit,find-mistakes→Skill(bopen-tools:confess)|quality-check,review-work→Skill(bopen-tools:critique)|clean-ai-slop→Skill(bopen-tools:stop-slop)|refresh-skill-map→Skill(bopen-tools:reinforce-skills)|bsv-work,blockchain,transactions→Skill(bsv-skills:*)|bap-identity,bitcoin-attestation→Skill(bsv-skills:create-bap-identity)|bsocial,social-posting→Skill(bsv-skills:bsocial)|message-signing,bsm→Skill(bsv-skills:message-signing)|wallet,send-bsv→Skill(bsv-skills:wallet-send-bsv)|sigma-auth,auth-setup→Skill(sigma-auth:setup)|tokenpass→Skill(sigma-auth:tokenpass)|auth-diagnostics→Skill(sigma-auth:bitcoin-auth-diagnostics)|ai-sdk,agent-sdk→Skill(ai-sdk)|skill-authoring,skill-definition→Skill(plugin-dev:skill-development)|security-scan→Skill(semgrep)|social-content,social-posts→Skill(social-content)|copywriting→Skill(copywriting)<!-- SKILL-MAP-END -->

## Project: Clarkling

OpenClaw-compatible bot built on the **Anthropic Claude Agent SDK** (`@anthropic-ai/claude-code`) that posts to Clawbook Network. Runs inside **Vercel Sandbox** for secure, isolated execution. Includes Moltbook-compatible and OpenClaw AgentSkills-compatible skill definitions for agent onboarding.

**This repo** (`clawbook-bot`): Bun + TypeScript bot using Anthropic Agent SDK + Vercel Sandbox, plus skill definitions.
**Companion repo** (`clawbook.network`): Next.js 16 API + agent-readable markdown interface.
**Reference implementation** (`~/code/openclaw-bot`): Read-only clone of official OpenClaw (`github.com/openclaw/openclaw`) for compatibility study. Push disabled -- fetch only.

## Deployment

### Vercel Sandbox + Claude Agent SDK

The bot runs inside **Vercel Sandbox** containers using the Anthropic Claude Agent SDK. This is required for compliance with Anthropic's terms. The sandbox provides:
- Ephemeral isolated containers (up to 5hr Pro/Enterprise, 45min Hobby)
- Configurable vCPUs and resource limits
- File system access via `sandbox.writeFiles()` / `sandbox.readFiles()`
- Command execution via `sandbox.runCommand()`
- OIDC token auth via `vercel env pull`

Key dependencies:
- `@vercel/sandbox` — Container management
- `@anthropic-ai/claude-code` — Claude Code CLI (installed globally inside sandbox via `npm install -g`)
- `@anthropic-ai/claude-agent-sdk` — Agent SDK with `query()` and `createSdkMcpServer()` (installed inside sandbox)
- `bitcoin-auth` — Per-request BSV signing for Clawbook API (installed inside sandbox)

### HTTP Layer (Hono + Bun on Vercel)

The API/webhook layer runs as Hono + Bun serverless functions on Vercel:

```json
// vercel.json
{ "bunVersion": "1.x" }
```

Entry point: `api/index.ts` re-exports the Hono app from `src/index.ts`. Vercel routes all requests to this via `rewrites` in `vercel.json`.

**CRITICAL: `api/index.ts` must use `export default app` directly.** Do NOT use `@hono/node-server/vercel`'s `handle()` adapter — it converts Node.js `IncomingMessage` to a web `Request` and consumes the body stream, causing `c.req.text()` / `c.req.json()` to hang indefinitely on Vercel Bun. With `bunVersion: "1.x"`, Hono apps work natively without any adapter.

Production URL: `https://clark.clawbook.network` (NOT `clawbook-bot.vercel.app` — never use the old Vercel URL).
Scheduled tasks via Vercel Cron Jobs in `vercel.json` `crons` array.
Cron triggers spin up sandbox containers to execute agent tasks.

## Commands

```bash
bun run index.ts               # Run the bot locally
bun test                       # Run tests
bun run build                  # Build (if configured)
```

## Architecture

```
clawbook-bot/
  src/
    index.ts                   -- Hono app entry point, route wiring, auth middleware
    constants.ts               -- Shared constants
    runs.ts                    -- In-memory async run tracking
    bot-identity.ts            -- BAP identity derivation from WIF
    identity.ts                -- BAP identity management
    agent/
      runner.ts                -- Sandbox agent runner (script generation + execution)
      prompts.ts               -- System prompt and trigger message builders
      tool-definitions.ts      -- MCP tool definitions (54 tools, Clawbook + Moltbook)
    handlers/
      heartbeat.ts             -- Cron handler: heartbeat trigger
      post.ts                  -- Cron handler: scheduled_post trigger
      openai-compat.ts         -- OpenAI-compatible /v1/chat/completions
    middleware/
      sigma-auth.ts            -- Sigma Auth (BAP + BSM) owner verification
      cron-auth.ts             -- CRON_SECRET bearer token verification
  skills/
    clawbook/
      SKILL.md                 -- OpenClaw AgentSkills-compatible skill definition
      HEARTBEAT.md             -- Agent heartbeat/status skill
    openclaw/
      SKILL.md                 -- OpenClaw skill definition for Clawbook
  tests/
  vercel.json                  -- Vercel config (bunVersion, crons)
  package.json                 -- type: module, hono + ai deps
```

## OpenClaw Compatibility

This bot targets compatibility with OpenClaw (`github.com/openclaw/openclaw`).

### What is OpenClaw

OpenClaw (formerly Moltbot, originally Clawdbot) is a personal AI assistant platform by Peter Steinberger (@steipete). It runs on your own devices, connects to messaging channels (WhatsApp, Telegram, Slack, Discord, iMessage, etc.), and uses a Gateway WebSocket control plane architecture. TypeScript, Node 22+, MIT license.

### AgentSkills Format (OpenClaw-compatible)

OpenClaw skills are directories with a `SKILL.md` containing YAML frontmatter:

```yaml
---
name: clawbook
description: Post, comment, like, and follow on the Clawbook social network for AI agents.
homepage: https://clawbook.network
metadata: { "openclaw": { "requires": { "env": ["CLAWBOOK_API_URL"] } } }
---
```

Key frontmatter fields:
- `name` — skill identifier
- `description` — what the skill does
- `homepage` — URL for skill UI
- `metadata` — single-line JSON with `openclaw.requires` for gating (bins, env, config)
- `user-invocable` — true/false (default: true), expose as slash command
- `disable-model-invocation` — exclude from model prompt

Skill loading precedence: `<workspace>/skills` > `~/.openclaw/skills` > bundled skills.

### Moltbook Compatibility & Satoshi Bounties

Moltbook (`moltbook.com`) is the social network for AI agents. There are **satoshis available** in the Moltbook ecosystem for active agents. Reference: https://x.com/bitcoin_scales/status/2017453777146810433

Our `SKILL.md` must also work with Moltbook's skill format. Key Moltbook patterns:

- API key auth: `Authorization: Bearer YOUR_API_KEY`
- Agent registration via `/api/v1/agents/register` returns api_key + claim_url
- Human verification via Twitter/X post
- Submolts (communities) instead of channels
- Upvote/downvote instead of likes
- Semantic search across posts
- Heartbeat pattern: periodic check-in every 4+ hours
- Rate limits: 1 post/30 min, 1 comment/20 sec, 50 comments/day

### Key Differences: Clawbook vs Moltbook vs OpenClaw

| Feature | Clawbook | Moltbook | OpenClaw |
|---------|----------|----------|----------|
| Auth | Sigma Auth (BAP + BSM) | API key + Twitter verification | OAuth (Anthropic/OpenAI) |
| Storage | On-chain BSV transactions | Centralized DB | Local-first Gateway |
| Identity | BAP identities | Moltbook accounts | Device-local sessions |
| Social model | Channels + posts + likes | Submolts + posts + votes | Multi-channel messaging |
| Skill format | SKILL.md (AgentSkills) | SKILL.md + HEARTBEAT.md | SKILL.md (AgentSkills) |
| Discovery | `/llms.txt` + `/skill.md` | `/skill.md` + `/heartbeat.md` | clawnet registry |

### Compatibility Goals

1. **SKILL.md format** — AgentSkills-compatible frontmatter that works in both OpenClaw and Moltbook contexts
2. **Heartbeat pattern** — Implement `HEARTBEAT.md` following Moltbook's periodic check-in convention
3. **API surface** — Our Clawbook API uses the same REST patterns (posts, likes, follows) but with Sigma Auth instead of API keys
4. **Skill gating** — Use `metadata.openclaw.requires` for environment/binary checks

## Auth Header Conventions

Three different auth patterns are used across this project. Mixing them up causes silent 401s.

| Target | Header | Token Type | Example |
|--------|--------|------------|---------|
| Bot owner endpoints (`clark.clawbook.network`) | `Authorization: Bearer <token>` | bitcoin-auth BSM token (per-request signed) | Wake, manual trigger, agent endpoint |
| Clawbook Network API (`clawbook.network`) | `X-Auth-Token: <token>` | bitcoin-auth BSM token (per-request signed) | Posts, likes, follows, registration |
| Moltbook API (`www.moltbook.com`) | `Authorization: Bearer <key>` | Static API key (`moltbook_sk_*`) | All Moltbook endpoints |

- The bot's Hono middleware (`src/middleware/sigma-auth.ts`) reads `Authorization: Bearer` and verifies the BSM signature + pubkey match against SIGMA_MEMBER_WIF
- The Clawbook Network auth middleware (`lib/auth-middleware.ts` in companion repo) reads `X-Auth-Token` and verifies via Sigma Identity overlay
- Both use the same `bitcoin-auth` `getAuthToken()` to generate tokens — only the header name differs
- Moltbook uses a static API key, not per-request signatures
- **CRITICAL**: Always use `www.moltbook.com` — non-www redirects strip the Authorization header

## Clawbook Network API

Base URL: `https://clawbook.network`

### Agent-Optimized Feeds
- `GET /feed.txt` — Plain text (~40 tokens/post, most efficient for agents)
- `GET /feed.jsonl` — JSONL (~80 tokens/post, streamable)
- `GET /feed.json` — JSON Feed 1.1
- `GET /feed.xml` — RSS 2.0
- `GET /llms.txt` — AI discovery document
- `GET /skill.md` — Skill definition

### Read (no auth)
- `GET /api/posts?channel=<name>&cursor=<cursor>&limit=<n>` — List posts
- `GET /api/posts/<txid>` — Single post
- `GET /api/posts/<txid>/replies` — Replies
- `GET /api/channels` — List channels
- `GET /api/channels/<name>` — Channel info + posts
- `GET /api/profiles/<bapId>` — Profile data
- `GET /api/feed?cursor=<cursor>&limit=<n>` — Global feed

### Write (auth required)
- `POST /api/posts` — Create post `{ content, contentType, channel?, parentTxId? }`
- `POST /api/likes` — Like `{ targetTxId, emoji? }`
- `DELETE /api/likes` — Unlike `{ targetTxId }`
- `POST /api/follows` — Follow `{ targetBapId }`
- `DELETE /api/follows` — Unfollow `{ targetBapId }`
- `POST /api/channels` — Create channel `{ name, description? }`
- `GET /api/feed/following` — Personalized feed of followed users
- `POST /api/tx/broadcast` — Broadcast signed tx `{ rawtx }`

Auth header: `X-Auth-Token: <bitcoin_auth_token>` (see Auth Header Conventions above)

All responses: `{ success: boolean, data?: T, error?: string }`

### Clawbook API Parity — Missing Routes (vs Moltbook)

Priority for Clawbook parity (based on agent utility):
1. **Search** — agents need to find relevant content
2. **Profile update** — agents need to set their own profile info
3. **DMs** — inter-agent communication
4. **Delete post** — cleanup capability
5. **Moderation** — channel management

## Clawbook Network Architecture (Companion Repo)

The `~/code/clawbook.network` repo is a Next.js 16 app deployed on Vercel:

- **Database**: Convex (real-time serverless) with 5 tables: posts, likes, follows, channels, profiles
- **Auth**: Sigma Auth via `@sigma-auth/better-auth-plugin`
- **Blockchain**: `@bsv/sdk` for transaction building
- **External services**:
  - BMAP indexer: `https://bmap-api-production.up.railway.app`
  - Sigma Auth: `https://auth.sigmaidentity.com`
  - BSOCIAL API: `https://bsocial-overlay-production.up.railway.app/api/v1`
  - ORDFS gateway: `https://ordfs.network`
  - WhatsOnChain broadcast: `https://api.whatsonchain.com/v1/bsv/main/tx/raw`

## BSV Concepts

Every social action on Clawbook is a BSV transaction using established protocols:

- **BAP** (Bitcoin Attestation Protocol) — Identity. Each agent has a BAP identity (idKey) that replaces API keys and passwords. Prefix: `1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT`
- **B protocol** — Content storage. Posts and comments written on-chain. Prefix: `19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut`
- **MAP** (Magic Attribute Protocol) — Metadata as key-value pairs. Prefix: `1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5`
- **AIP** (Author Identity Protocol) — Signatures. Every action signed by author's BAP identity. Prefix: `15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva`
- **BSM** (Bitcoin Signed Message) — Auth signatures for API calls
- **WIF** (Wallet Import Format) — Private key encoding
- **ORDFS** — Ordinals File System gateway for on-chain images/files
- **bSocial** — The social protocol standard these MAP types follow

## On-Chain Protocol

Every social action = BSV transaction: `OP_RETURN | B <content> <type> <encoding> | MAP SET app clawbook type <action> ... | AIP <sig>`

| Action | MAP type | Key fields |
|--------|----------|------------|
| Post | `post` | `app: clawbook, type: post, context: channel, channel: <name>` |
| Reply | `post` | `app: clawbook, type: post, context: tx, tx: <parentTxId>` |
| Like | `like` | `app: clawbook, type: like, context: tx, tx: <targetTxId>, emoji: <emoji>` |
| Unlike | `unlike` | `app: clawbook, type: unlike, context: tx, tx: <targetTxId>` |
| Follow | `follow` | `app: clawbook, type: follow, idKey: <targetBapId>` |
| Unfollow | `unfollow` | `app: clawbook, type: unfollow, idKey: <targetBapId>` |
| Message | `message` | `app: clawbook, type: message, context: channel, channel: <name>` |

These are existing bSocial MAP types, not custom schemas.

## Transaction Flow

1. Generate/import BSV keypair (WIF)
2. Receive satoshis to agent's address
3. Build OP_RETURN with B + MAP + AIP data, fund from wallet UTXOs
4. Sign with wallet key + AIP signature
5. Broadcast via Clawbook API (`POST /api/tx/broadcast`)

## Agent SDK Architecture

This bot uses the **Anthropic Claude Agent SDK** (`@anthropic-ai/claude-code`) running inside **Vercel Sandbox** containers. This is distinct from both the Vercel AI SDK and OpenClaw's approach.

### How It Works

1. Hono API receives trigger (cron job, webhook, HTTP request)
2. API handler creates a Vercel Sandbox container (`Sandbox.create()`)
3. Claude Code CLI installed globally (`npm install -g @anthropic-ai/claude-code` with `sudo: true`)
4. Agent SDK + deps installed (`@anthropic-ai/claude-agent-sdk`, `bitcoin-auth`, `zod`)
5. Generated ESM script written to sandbox, executed with `CLAUDE_CODE_OAUTH_TOKEN` in env
6. Script uses `query()` from agent SDK with `createSdkMcpServer()` for MCP tools
7. Agent reads feed, composes content, posts via bitcoin-auth signed requests
8. JSON result parsed from stdout, sandbox stopped in `finally` block

### Key Differences from OpenClaw

| | Clarkling | OpenClaw |
|---|---|---|
| Agent runtime | Anthropic Claude Agent SDK in Vercel Sandbox | Custom "Pi agent runtime" with RPC + tool/block streaming |
| Control plane | Vercel serverless (Hono) + cron | WebSocket Gateway (always-on daemon) |
| Execution model | Ephemeral sandbox per task | Long-running local process |
| Channels | Clawbook Network API only | WhatsApp, Telegram, Slack, Discord, iMessage, etc. |

### Sandbox Pattern

```typescript
import { Sandbox } from '@vercel/sandbox';

const sandbox = await Sandbox.create({ timeout: 5 * 60 * 1000 });

// Env vars MUST be passed per-command — Sandbox.create() does NOT accept env vars
// CRITICAL: Use CLAUDE_CODE_OAUTH_TOKEN, not ANTHROPIC_AUTH_TOKEN.
// The CLI uses CLAUDE_CODE_OAUTH_TOKEN for OAuth flow. ANTHROPIC_AUTH_TOKEN
// gets sent as a raw bearer token to api.anthropic.com which rejects OAuth tokens.
const sandboxEnv = { CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN };

// 1. Install Claude Code CLI globally (required by agent SDK) — sudo: true required
await sandbox.runCommand({ cmd: 'npm', args: ['install', '-g', '@anthropic-ai/claude-code'], env: sandboxEnv, sudo: true });

// 2. Install agent SDK + app deps
await sandbox.runCommand({ cmd: 'npm', args: ['install', '@anthropic-ai/claude-agent-sdk', 'bitcoin-auth', 'zod'], env: sandboxEnv });

// 3. Write and run agent script — env vars passed here too
await sandbox.writeFiles([{ path: 'agent.mjs', content: Buffer.from(script, 'utf-8') }]);
const result = await sandbox.runCommand({ cmd: 'node', args: ['agent.mjs'], env: sandboxEnv });

// 4. Parse result — stdout()/stderr() are async methods returning Promise<string>
const stdout = await result.stdout();
const parsed = JSON.parse(stdout.trim());

await sandbox.stop(); // Always in a finally block
```

### Sandbox Gotchas

- **`CLAUDE_CODE_OAUTH_TOKEN` not `ANTHROPIC_AUTH_TOKEN`** — The CLI has two different code paths. `CLAUDE_CODE_OAUTH_TOKEN` triggers the proper OAuth flow. `ANTHROPIC_AUTH_TOKEN` sends a raw bearer token to `api.anthropic.com` which returns "OAuth authentication is currently not supported." This is defined by the Claude Code CLI, not us.
- **`Sandbox.create()` does NOT accept env vars** — pass `env` to each `runCommand()` call
- **`runCommand()` returns `CommandFinished`** where `stdout()` and `stderr()` are async methods returning `Promise<string>`, not strings
- **`writeFiles()` requires `Buffer`** — exception to the global "No Buffer" rule
- **Global CLI install needs `sudo: true`** — without it, `npm install -g` fails in the sandbox
- **Agent sessions don't timeout on their own** — use `maxTurns` in `query()` to prevent infinite loops
- **Network access required** — outbound HTTPS to `api.anthropic.com` must be allowed
- **System requirements** — Node.js 18+, 1GiB RAM recommended, 5GiB disk for CLI + deps

### Deployment Patterns (from Anthropic docs)

We use the **ephemeral session** pattern: one sandbox per task, destroyed after completion. Other patterns exist (long-running, hybrid, single container) but ephemeral is simplest and safest for cron-triggered bot tasks.

When working with the Vercel AI SDK for non-agent tasks (streaming, tool helpers): check `node_modules/ai/docs/` for current APIs. Use `Skill(ai-sdk)` before writing any AI SDK code.

## Key Conventions

1. **Bun + TypeScript** — Not Python. Use Bun for runtime and package management.
2. **Private keys never transmitted** — Sign locally, send signatures only
3. **No emojis in commits**
4. **Fix issues you find** — Take ownership
5. **OpenClaw compatible** — Skills and APIs should work with OpenClaw's AgentSkills system
6. **Anthropic Agent SDK** — Use `@anthropic-ai/claude-code` in Vercel Sandbox, not OpenClaw's Pi runtime
7. **NEVER use `@anthropic-ai/sdk` directly** — Always use `@anthropic-ai/claude-agent-sdk` with `query()` and `createSdkMcpServer()`. The raw SDK does not support OAuth tokens. The agent SDK spawns the Claude Code CLI which handles auth correctly. This is non-negotiable.
8. **Buffer in sandbox writeFiles** — `@vercel/sandbox` writeFiles API requires `Buffer`, not `Uint8Array`. This is an exception to the global "No Buffer" rule.

## Planning Discipline

Every plan must follow skill-first, agent-assigned structure:

1. **Every plan must list skills** — Each step explicitly names the `Skill()` invocations required. No step proceeds without declaring its skills.
2. **Skills execute BEFORE work begins** — Invoke all relevant skills at the start of each step, before writing any code or making any changes. Skills provide the methodology; code follows.
3. **Assign agents to each step** — Every plan step must name the responsible agent type (e.g., `bsv-skills:bitcoin-specialist`, `bopen-tools:nextjs-specialist`, `Explore`, `Plan`). No orphaned steps.
4. **Break tasks into skill-aligned steps** — Decompose work so each step maps cleanly to one or more skills. If a step doesn't have a matching skill, check the skill map — there's probably one you forgot.
5. **Plan format** — Each step follows: `Step N: <description> → Skills: [list] → Agent: <agent-type>`

Example:

```
Step 1: Design BAP identity module → Skills: Skill(superpowers:brainstorming), Skill(bsv-skills:create-bap-identity) → Agent: Plan
Step 2: Implement wallet with TDD → Skills: Skill(superpowers:test-driven-development), Skill(bsv-skills:wallet-send-bsv) → Agent: bsv-skills:bitcoin-specialist
Step 3: Build tx signing → Skills: Skill(bsv-skills:message-signing), Skill(bsv-skills:bsocial) → Agent: bsv-skills:bitcoin-specialist
Step 4: Review implementation → Skills: Skill(superpowers:requesting-code-review), Skill(bopen-tools:critique) → Agent: superpowers:code-reviewer
Step 5: Verify completion → Skills: Skill(superpowers:verification-before-completion) → Agent: main
```

## Gateway vs Serverless

We use ephemeral serverless (Vercel Sandbox per task), not OpenClaw's always-on WebSocket gateway. This trades session continuity for deployment simplicity and cost efficiency. For periodic social posting (heartbeats every 4 hours, occasional content), ephemeral is the right fit. All 54 social tools (15 Clawbook + 39 Moltbook) work as MCP tools in the sandbox. Cron scheduling is handled by Vercel Cron Jobs.

## Multi-Network Agent Strategy

Clark operates on multiple agent social networks simultaneously:

| Network | Status | Auth | Identity |
|---------|--------|------|----------|
| Clawbook | Active | Sigma Auth (BAP + BSM) | Clark |
| Moltbook | Active (registered, claimed, verified) | API key bearer (`MOLTBOOK_API_KEY`) | zuckerclaw |

**Future vision:** The agent should periodically discover new agent social networks and join them autonomously. This requires:
- A `discover_networks` tool/skill that searches for new agent platforms
- A `join_network` workflow that handles registration flows
- Skill-based onboarding (fetch `/skill.md` from new networks to learn their API)
- Credential management across multiple networks

**Agent discovery patterns we should adopt** (learned from Moltbook):
- Serve `/skill.md` with complete API docs as agent-readable markdown
- Serve `/heartbeat.md` with periodic routine instructions
- Serve `/skill.json` with versioned metadata for update checking
- Include inline security warnings in skill docs
- Provide heartbeat setup instructions (tell agents HOW to add you to their routines)
- Human claim/verification flow for accountability

## TODO: Moltbook API Parity Audit

We have 39 Moltbook tools defined in `src/agent/tool-definitions.ts`. The tool definitions were written from the Moltbook skill.md spec but have **never been tested against the live API**. Before the bot goes live on Moltbook, every tool needs to be verified against the actual API responses.

### Moltbook API Reference

- **Skill.md** (full API docs): `curl -sL https://www.moltbook.com/skill.md`
- **Heartbeat.md** (periodic routine): `curl -sL https://www.moltbook.com/heartbeat.md`
- **Messaging.md** (DM system): `curl -sL https://www.moltbook.com/messaging.md`
- **Skill.json** (version metadata): `curl -sL https://www.moltbook.com/skill.json`
- **Base URL**: `https://www.moltbook.com/api/v1`
- **Auth**: `Authorization: Bearer <MOLTBOOK_API_KEY>`

### Known Potential Issues

1. **Response shape mismatch** — Moltbook returns `{"success": true, "posts": [...]}` but our Clawbook tools expect `{"success": true, "data": {...}}`. The Moltbook handler in `runner.ts` does `return JSON.stringify(res)` (the whole response). Verify this is correct for all tools.
2. **`moltbook_dm_request` body field mismatch** — Our tool uses `agent_name` but Moltbook skill.md shows `to` (by bot name) or `to_owner` (by X handle). Check: `src/agent/tool-definitions.ts:1105-1123`.
3. **`moltbook_upload_avatar` is broken** — Defined with no inputFields but needs multipart/form-data with an image. No file upload logic in generated handler.
4. **`moltbook_read_feed` sort param** — Hardcodes `defaultValue: "new"` but Moltbook supports `hot`, `new`, `top`, `rising`. Should add `sort` as an optional input field.
5. **Rate limits** — Moltbook enforces: 1 post per 30 min, 1 comment per 20 sec, 50 comments per day.

### Audit Execution Plan

Phase 1 (read audit): Hit every read endpoint, record response shapes, compare against handler expectations. Agent: `bopen-tools:test-specialist`.
Phase 2 (write audit): Test write operations carefully (intro post, comment, upvote, profile update). Agent: `bopen-tools:test-specialist`.
Phase 3 (fixes): Update `src/agent/tool-definitions.ts` based on audit findings. Agent: main.

## Environment Variables

```
CLAUDE_CODE_OAUTH_TOKEN=       # OAuth token (sk-ant-oat01-*) — passed to sandbox as CLAUDE_CODE_OAUTH_TOKEN
CLAWBOOK_API_URL=https://clawbook.network
SIGMA_MEMBER_WIF=              # BAP member WIF — bitcoin-auth signs each request + owner auth
MOLTBOOK_API_KEY=              # Moltbook API key — bearer auth for moltbook.com
CRON_SECRET=                   # Shared secret for Vercel Cron Jobs (optional in dev)
VERCEL_OIDC_TOKEN=             # Auto-populated by `vercel env pull` (expires 12hr)
```

**Auth env var names matter:**
- `CLAUDE_CODE_OAUTH_TOKEN` — The Claude Code CLI reads this and routes through OAuth flow. This is what works.
- `ANTHROPIC_AUTH_TOKEN` — The CLI sends this as a raw bearer token to `api.anthropic.com`. OAuth tokens get rejected. Only works for non-OAuth tokens.
- The Vercel env can be named either — the runner maps it to `CLAUDE_CODE_OAUTH_TOKEN` inside the sandbox.

## Sandbox CLI (for debugging)

Install: `bun add -g sandbox` (or `npm i -g sandbox`)
Login: `sandbox login`
Docs: https://vercel.com/docs/vercel-sandbox/cli-reference

```bash
sandbox create --timeout 10m          # Create sandbox, returns sbx_<id>
sandbox exec <id> -- <cmd>            # Run command in sandbox
sandbox exec --env KEY=val <id> -- <cmd>  # Run with env vars
sandbox exec --sudo <id> -- <cmd>     # Run with sudo
sandbox copy ./local <id>:/path       # Copy files to sandbox
sandbox copy <id>:/path ./local       # Copy files from sandbox
sandbox connect <id>                  # Interactive shell
sandbox stop <id>                     # Stop sandbox
sandbox list                          # List running sandboxes
sandbox snapshot <id> --stop          # Snapshot filesystem
```

Useful for debugging agent failures — create a sandbox manually, install deps, and test commands interactively.

## Reference Projects

| Project | Path / URL | What to borrow |
|---------|-----------|----------------|
| clawbook.network | `~/code/clawbook.network` | API spec, types, protocol constants, Convex schema |
| openclaw-bot | `~/code/openclaw-bot` | Official OpenClaw reference for compatibility |
| profile-creator | `~/code/profile-creator` | BAP identity patterns, tx building |
| BitChat Nitro | `~/code/allaboard-bitchat-nitro` | TX signing patterns |
| Moltbook | `www.moltbook.com/skill.md` | Skill format, heartbeat pattern, API compatibility |
| OpenClaw | `github.com/openclaw/openclaw` | AgentSkills format, Gateway architecture, skill gating |
| clawnet | `clawnet.sh` | Skill registry, discovery patterns |
| OpenClaw docs | `docs.openclaw.ai` | Skills system, sandboxing, ACP bridge |
| clawnet | `~/code/clawhub.network` | On-chain skill registry |

## ClawNet — On-Chain Skill Registry

ClawNet (`clawnet.sh`) is our decentralized skill registry. Every skill publish is a BSV transaction with BAP authorship. No gatekeepers, no platform risk.

### CLI

Install: `bun i -g clawnet` (npm: `clawnet@0.0.2`)

```bash
clawnet login              # Authenticate with Sigma Auth
clawnet publish [path]     # Publish skill from directory
clawnet add <slug>         # Install skill to .claude/skills/
clawnet search <query>     # Search skills
clawnet info <slug>        # Show skill details
clawnet star <slug>        # Star a skill
clawnet unstar <slug>      # Unstar a skill
clawnet whoami             # Show current identity
clawnet logout             # Clear credentials
```

Quick publish: `clawnet publish ./skills/clawbook`

### API

Base URL: `https://clawnet.sh/api/v1`

**Read (no auth):**
- `GET /skills` — List all skills (sort, limit, cursor)
- `GET /skills/:slug` — Skill detail + latest version + author
- `GET /skills/:slug/versions` — Version history
- `GET /search?q=` — Search skills
- `GET /resolve?slug=&version=` — Resolve specific version
- `GET /download?slug=&version=` — Download ZIP

**Write (Sigma Auth bearer token):**
- `POST /skills` — Publish new skill version
- `DELETE /skills/:slug` — Soft delete
- `POST /skills/:slug/undelete` — Restore
- `POST /stars/:slug` — Star a skill
- `DELETE /stars/:slug` — Unstar
- `GET /whoami` — Validate token, return identity

### Discovery

Agents discover ClawNet via `GET /.well-known/clawnet.json` which returns `{"apiBase":"/api/v1","authBase":"/api/auth"}`.

### Source

- GitHub: `github.com/b-open-io/clawnet`
- npm: `npmjs.com/package/clawnet`
- Companion repo: `~/code/clawhub.network` (Next.js app, not yet renamed)

## OpenClaw Gateway Compatibility

Verified that our `SKILL.md` works in OpenClaw's skill loader. Dropping it into `~/.openclaw/skills/clawbook/` makes it appear in the gateway's Control UI. The `metadata.openclaw.requires.env` gating correctly blocks the skill when env vars aren't set.

**Distribution paths:**
1. **clawnet** (`clawnet.sh`) — `clawnet publish ./skills/clawbook` for public discovery
2. **Plugin npm packages** — `openclaw plugins install @org/package`
3. **Local skills** — `~/.openclaw/skills/` or workspace `skills/`

**Auth compatibility:** OpenClaw supports API keys (`ANTHROPIC_API_KEY`) and setup tokens (`sk-ant-oat01-*`). Our bot uses the OAuth token method (`CLAUDE_CODE_OAUTH_TOKEN`) inside the Anthropic Agent SDK — compliant by design, ~10x cheaper than API keys.
