{
  "markdown": "# curb.sale for agents\n\n**You do not need this repo.** curb.sale is a live HTTP API with no account, no\nAPI key and no signup on any path. One unauthenticated POST creates a public\nlisting and returns its URL, from anything that can make an HTTP request:\n\n```bash\ncurl -sX POST https://curb.sale/sell \\\n  -F 'photo=@sofa.jpg' \\\n  -F 'text=Grey IKEA Ektorp 3-seat sofa, small stain on left arm, $150 obo' \\\n  -F 'location=Austin, TX'\n```\n\nThat is the whole product. [`https://curb.sale/index.md`](https://curb.sale/index.md)\nholds the full contract in less than 4,500 characters. An agent can fetch that\npage in the middle of a conversation and complete the task with no second\nrequest.\n\nThis repo is a convenience, not a dependency. It packages the contract as a\nskill. The agent then knows these rules before the first call, not after a\nfailed one:\n\n- Prices are in cents.\n- A listing needs a city. Your IP address belongs to the agent, not to you.\n- `edit_token` is returned one time only. Save it.\n- A sandbox can block the request. This is the most common cause of a failed\n  first call, and the skill knows how to recover.\n\nIf you remove this repo, everything above still works. You lose only the head\nstart.\n\n## Install\n\n| Runtime | Command | What lands |\n|---|---|---|\n| **Claude Code** | `/plugin marketplace add curb-sale/curb-skill`<br>`/plugin install curb-sale@curb-sale` | skill + `/curb-sell` `/curb-search` `/curb-contact` `/curb-manage` |\n| **Codex** | `codex plugin marketplace add curb-sale/curb-skill`<br>`codex plugin add curb-sale@curb-sale` | skill. [Turn its network on first](#codex) — the default failure looks like DNS, not a firewall |\n| **Gemini CLI** | `gemini extensions install https://github.com/curb-sale/curb-skill` | skill + the same four commands, as `.toml` |\n| **Cursor** | `git clone https://github.com/curb-sale/curb-skill ~/.cursor/plugins/local/curb-sale` | skill, then **Developer: Reload Window** |\n| **VS Code / Copilot** | `cp -R skills/curb-sale ~/.agents/skills/` | skill. No manifest, no command |\n| **Amp** | `amp skill add curb-sale/curb-skill` | skill |\n| **~78 others**<br><sub>Zed, Cline, Roo, Warp, OpenCode, Windsurf, Kiro…</sub> | `npx skills add curb-sale/curb-skill` | skill, into whichever agents it finds installed |\n| **Only the domain**<br><sub>no repo, no org, nothing but the URL</sub> | `npx skills add https://curb.sale` | skill. The site serves `/.well-known/agent-skills/index.json`, so this needs nothing from GitHub |\n| **No plugin system**<br><sub>ChatGPT, the Claude and Gemini apps, any chat box</sub> | paste [`agents-snippet.md`](agents-snippet.md) into custom instructions | the contract, as text |\n\nThen just say what you want:\n\n> sell my old dresser, $80, I'm in Austin\n\n> find me a used desk near Austin under $150\n\nEvery row above reads the same `skills/curb-sale/` directory.\n\nIf your runtime is not in the table, copy that folder into its skills directory.\nThat is the full install. Use `.agents/skills/`, which more runtimes accept than\nany other path. Many runtimes also read `.claude/skills/`, so a global Claude\nCode install is often already visible to them.\n\n## Runtime notes\n\n### Codex\n\nCodex reads `.claude-plugin/marketplace.json` as a legacy-compatible marketplace.\nIt takes the name and version from one of the plugin manifests. All five\nmanifests come from one source and hold the same values, so the choice does not\nchange the result.\n\nTo confirm the install, run `codex debug prompt-input`. The skill shows in the\nmodel-visible list with its path. This makes no API call.\n\nCodex also reads a skill directory with no plugin. `$HOME/.agents/skills` is the\nuser location. `$REPO_ROOT/.agents/skills` is the project location.\n\n```bash\nmkdir -p ~/.agents/skills && cp -R skills/curb-sale ~/.agents/skills/\n```\n\n**Codex keeps networking off by default.** The `workspace-write` sandbox blocks\noutbound traffic until you enable it. The first POST then fails with a DNS\nerror, not an HTTP status:\n\n```\ncurl: (6) Could not resolve host: curb.sale\n```\n\nTo enable networking, edit `~/.codex/config.toml`:\n\n```toml\n[sandbox_workspace_write]\nnetwork_access = true\n```\n\nTo allow curb.sale only, enable the egress proxy and add one rule:\n\n```toml\n[features]\nnetwork_proxy = true\n\n[permissions.curb]\nextends = \":workspace\"\n\n[permissions.curb.network]\nenabled = true\n\n[permissions.curb.network.domains]\n\"curb.sale\" = \"allow\"\n```\n\nYou must use both parts. The proxy applies rules but grants no access on its own.\n\nThree more errors are possible, and none of them come from curb.sale:\n\n| Error | Cause | Action |\n|---|---|---|\n| `curl: (6) Could not resolve host` | Networking is off | Set `network_access = true` |\n| `curl: (56) CONNECT tunnel failed, response 403` | The local proxy blocks the host | Add the host to `domains` |\n| `curl: (7) Failed to connect to 127.0.0.1 port NNNNN` | The proxy is still starting | Send the request again |\n\nThe skill knows all three, and acts on them without your help.\n\n### Gemini CLI\n\n`gemini-extension.json` at the repo root is what makes this an extension. It\ncarries the skill plus a `.toml` copy of each command, which is the only command\nformat Gemini reads: `/curb-sell`, `/curb-search`, `/curb-contact` and\n`/curb-manage`. If a command name is already in use, Gemini adds the extension name as a prefix:\n`/curb-sale.curb-sell`.\n\nRun the install from a shell. It does not work in interactive mode. Restart the\nCLI when the install completes.\n\nFor the skill on its own, without the commands:\n\n```bash\ngemini skills install https://github.com/curb-sale/curb-skill.git \\\n  --path skills/curb-sale --consent\n```\n\nThat subcommand is available after version 0.16.0. Run `gemini --version` first.\n\nCopying the folder works on all versions and needs no CLI. Gemini reads\n`~/.gemini/skills/` and `~/.agents/skills/` for a user, and `.gemini/skills/`\nand `.agents/skills/` for a workspace. In each pair, `.agents` wins.\n\n### Cursor\n\nCursor loads two plugin formats and this repo carries a manifest for each: the\nportable `plugin.json` at the root, and `.cursor-plugin/plugin.json` in Cursor's\nown format. Either loads from `~/.cursor/plugins/local`, which needs no review\nand no paid plan. Symlink instead of cloning if you want to iterate:\n\n```bash\nln -s \"$PWD\" ~/.cursor/plugins/local/curb-sale\n```\n\nThe skill shows in **Customize → Skills**, under *Agent Decides*. Cursor puts a\nskill there when the agent can select it without a command. This repo keeps that\nbehaviour. The `disable-model-invocation` flag would turn the skill into a typed\n`/name`, and then only a user who already knows about curb.sale could reach it.\n\nCursor's choice between the two manifests is not documented, and this repo is\nunverified on Cursor. Both manifests hold the same name, version and\nno-account values, so the skill loads either way. The four commands load only if\nCursor reads its own manifest. Treat the commands as unconfirmed on Cursor.\n\nFor the skill alone: `cp -R skills/curb-sale ~/.cursor/skills/`. Cursor also\nloads `~/.claude/skills/` and `.claude/skills/` for compatibility.\n\n### Runtimes with no plugin system\n\n[`agents-snippet.md`](agents-snippet.md) holds the contract in a few lines. It\nis a bare markdown section. It has no title, no frontmatter and no wrapper, so\nyou can append it to any instructions file:\n\n```bash\ncurl -sL https://raw.githubusercontent.com/curb-sale/curb-skill/main/agents-snippet.md >> AGENTS.md\n```\n\nWhere to point that `>>`, checked against each runtime's own current docs:\n\n| Runtime | Personal, all projects | Per project |\n|---|---|---|\n| Codex | `~/.codex/AGENTS.md` | `AGENTS.md`, git root down to cwd |\n| Amp | `~/.config/AGENTS.md` or `~/.config/amp/AGENTS.md` | `AGENTS.md`, cwd and parents |\n| Zed | `~/.config/zed/AGENTS.md` (`%APPDATA%\\Zed\\AGENTS.md` on Windows) | `AGENTS.md` |\n| opencode | `~/.config/opencode/AGENTS.md` | `AGENTS.md`, cwd and parents |\n| Claude Code | `~/.claude/CLAUDE.md`. It reads `CLAUDE.md`, not `AGENTS.md` | `CLAUDE.md` |\n| Cursor | Settings → Rules, as a User Rule | `AGENTS.md`, root or any subdirectory |\n| VS Code / Copilot | `~/.copilot/instructions/curb-sale.instructions.md`. This is a **folder** of `*.instructions.md` files, not a file to append to | `AGENTS.md` at the workspace root |\n| Windsurf / Devin | `~/.codeium/windsurf/memories/global_rules.md` (6,000 char cap) | `AGENTS.md`, any workspace directory |\n| Warp | Global Rules, in settings | `AGENTS.md`. The name must be in caps. A `WARP.md` beside it wins |\n| Gemini CLI | `~/.gemini/GEMINI.md` | `GEMINI.md`, or `AGENTS.md` once `context.fileName` lists it |\n\nTwo runtimes merge nothing. opencode and Zed read the **first** file they match:\n\n- opencode does not read `~/.claude/CLAUDE.md` if its own global file exists.\n- Zed reads `AGENT.md` before `AGENTS.md`.\n\nThe snippet is 1,379 characters. You can paste it by hand into a settings box.\nIt fits every global-rules limit in the table above. The smallest is Windsurf's\n6,000 characters.\n\nFor a longer version that also covers buyer messages and the seller's reply\npath, use\n[`skills/curb-sale/references/paste-block.md`](skills/curb-sale/references/paste-block.md).\n\n## Allow the host\n\nAgent runtimes sandbox outbound traffic. The first POST can fail before it\nleaves your machine. curb.sale does not receive that request and cannot answer\nit.\n\nThere are two kinds of failure:\n\n- The runtime blocks a host that is not on an allowlist. You get\n  `403 host_not_allowed`.\n- The runtime turns networking off. You get a DNS failure and no HTTP status.\n\nCodex is the second kind. See [Codex](#codex) above.\n\nIn `~/.claude/settings.json`:\n\n```json\n{\n  \"sandbox\": {\n    \"network\": {\n      \"allowedDomains\": [\"curb.sale\"]\n    }\n  }\n}\n```\n\nIf you cannot change these settings, the skill still completes the task. It\ngives you a curl command to run yourself, or a prefilled\n`https://curb.sale/new?...` page that needs no terminal. For more, see\n[`references/blocked-egress.md`](skills/curb-sale/references/blocked-egress.md).\n\n## What is in here\n\n```\nskills/curb-sale/              every runtime above reads this one directory\n  SKILL.md                     the contract: sell, search, contact, inbox, edit\n  references/api.md            every endpoint, field, and error code\n  references/blocked-egress.md recovering when the sandbox blocks the request\n  references/paste-block.md    the whole loop, for a runtime with no skill system\n  scripts/curb.sh              the calls with the quoting already right\n\ncommands/curb-sell.md          /curb-sell   (written once, as markdown)\ncommands/curb-search.md        /curb-search\ncommands/curb-contact.md       /curb-contact\ncommands/curb-manage.md        /curb-manage\ncommands/*.toml                the same four, generated for Gemini CLI, which\n                               reads no other command format\n\nplugin.json                    Agent Plugins 1.0.0: Cursor, VS Code, Copilot,\n                               ChatGPT & Codex, Kiro, Hermes and three more\n.claude-plugin/plugin.json     Claude Code\n.claude-plugin/marketplace.json  the curb-sale marketplace; also what\n                               `codex plugin marketplace add` resolves\n.codex-plugin/plugin.json      Codex's own format, plus its install-surface copy\n.cursor-plugin/plugin.json     Cursor's own format\ngemini-extension.json          Gemini CLI\n\nagents-snippet.md              the paste-in block, for runtimes with none of the above\nAGENTS.md                      how to change this repo\nCLAUDE.md                      one line, importing AGENTS.md, because Claude Code\n                               reads CLAUDE.md and not AGENTS.md\nscripts/sync.py                regenerates every derived file; --check fails on drift\n```\n\n`curb.sh` needs `curl`. The `contact` and `edit` subcommands also need `python3`\nto build their JSON.\n\nEvery subcommand accepts `--dry-run`. This prints the curl command and sends\nnothing.\n\n## How the copies stay the same\n\nFive manifests hold the same name, version and description. Four command prompts\nexist twice, because Gemini CLI reads `.toml` and no other runtime does.\n\nThese files are generated. `plugin.json` and `commands/*.md` are the sources.\nEvery other manifest and every `.toml` is derived from them.\n\n```bash\nscripts/sync.py            # write every derived file\nscripts/sync.py --check    # exit 1 if a derived file differs\n```\n\n`sync.py` also rejects a description that contains `\": \"`. In an unquoted YAML\nscalar, a colon and a space start a nested mapping and make the file invalid.\nClaude Code, Codex, Gemini CLI and Cursor accept the file anyway. Strict parsers\nreject it, and the skill then does not load at all.\n\nCI runs `--check` and a strict parser on every push.\n\n## What this repo does not ship\n\n- **No `mcpServers` key in any manifest.** The MCP server is live at\n  `POST https://curb.sale/mcp`. It uses Streamable HTTP. It needs no\n  authentication, no OAuth and no session. This plugin does not declare it. A runtime that\n  installs this plugin already holds the contract in `SKILL.md`, and makes the\n  same calls over plain HTTP. To use the MCP server, point your runtime at the\n  URL:\n\n  ```bash\n  claude mcp add --transport http curb https://curb.sale/mcp\n  ```\n\n- **No Continue.dev file.** Continue publishes no skills format that could be\n  verified from its documentation. Cursor has since acquired Continue, so use\n  the Cursor manifest in this repo.\n- **No Aider file.** Aider has no skill or plugin system. Its extension point is\n  a read-only `CONVENTIONS.md`, which it reads through a project `AGENTS.md`.\n- **No second marketplace manifest** for Codex or Cursor. `codex plugin\n  marketplace add` resolves `.claude-plugin/marketplace.json`. Cursor documents\n  its marketplace format for repositories that hold more than one plugin, where\n  each `source` is a subdirectory. This repo holds one plugin at the root.\n\nEvery manifest, filename and config key in this repo is verified against that\nruntime's current documentation before it is written. A file in a shape the\nruntime does not read is worse than no file. It looks supported, and it does\nnothing.\n\nMore: [`/docs.md`](https://curb.sale/docs.md) ·\n[`/llms.txt`](https://curb.sale/llms.txt) ·\n[`/openapi.json`](https://curb.sale/openapi.json) ·\n[`/agents.md`](https://curb.sale/agents.md) ·\n[`/prohibited`](https://curb.sale/prohibited)\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n",
  "bytes": 14414,
  "sha": "2afcbd00e42a75a4b79885ba703f97c4545a976b7f56f1e9ce9559345fea0217",
  "repo_slug": "curb-sale/curb-skill",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_curb_sale_curb_skill_76a04dd9/readme"
}