Basic Cohub abilities. Most agents already have these mounted; listed here for reference.
Platform Published by the Neta team.
Official Made by the Neta team.
Verified Reviewed by the Neta team.
Community Shared by a Cohub user. Not reviewed — read SKILL.md before you use it.
world-ops
Platformneta/world-ops
Use it in Cohub
Paste this into your agent's chat — it fetches the skill and follows it.
Use the skill: world-ops. Run `npx -y @neta-art/neta-search-cli@latest skills use neta/world-ops --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use neta/world-ops
Summary
Make quick, precise changes to a world you've already built: add, edit, move or delete one thing, or fix its cover.
Look up what's in your world, find a character or place by name, and check whether a card's cover is ready yet.
Add a single character or location, rewrite its details, rename it, move it into another folder, or delete it for good.
New characters and locations get a cover picture drawn automatically. You can also ask for covers on the ones that have none yet.
Use an image you already have as a card's cover, or redraw a cover after you've changed that character's details.
Change one world setting such as name, tone or visual style, set or clear the world's cover image, or save an uploaded picture as a work.
SKILL.md
# World Ops
Surgical, single-item edits to a world that already exists. Every branch is one class of `neta` CLI call against the current world's atoms, works, or config. This skill never builds a world from scratch and never runs a batch reveal — that is create-world / world-reveal.
## Route
Pick the one branch that matches the ask. If the ask is a whole world, a batch, a new generation, a canvas layout (that is board-ops), a web work, or a roleplay, it is not world-ops — hand it to the skill that owns it.
| User intent | Branch |
|---|---|
| See what's in the world; find an atom/work | [Inspect](#inspect) |
| Add one atom to the current world | [Add atom](#add-atom) |
| Change an atom's name, aliases or text | [Edit atom](#edit-atom) |
| Move atoms into another folder | [Move atom](#move-atom) |
| Permanently delete an atom | [Remove atom](#remove-atom) |
| Set / requeue an atom's cover from an image already in hand | [Atom cover](#atom-cover) |
| Draw covers for atoms that have none ("generate the rest") | [Missing covers](#missing-covers) |
| Change one worldConfig field (name, tone, visual style, …) | [World config](#world-config) |
| Set the world's public address (slug) | [World slug](#world-slug) |
| Set / clear the owner's world cover image | [World cover](#world-cover) |
| Import an uploaded image file as a work | [Import work](#import-work) |
## Shared rules
- **Read before write.** Run `atom list` (and `work list` when works matter) first to see what exists. Never recreate an atom whose name already exists.
- **Ids.** An atom's id is its file path, e.g. `world/characters/林恩.md`; work ids are CLI-generated. Use the ids the CLI returns or lists; never invent one.
- **Covers arrive on their own.** `atom add` auto-queues a cover for character/location atoms; other types stay text-only until the user asks. Do not use the **generate** skill to make a card's cover appear. A finished cover is the first image in the atom's `media`; a cover still drawing shows only through `atom cover status` (see [Inspect](#inspect)).
- **JSON shape is in the CLI.** For the exact stdin fields of any write command, read `node /mods/neta/neta <resource> <action> --help`. This skill states only world-ops judgment, not the schema.
- **NDJSON on stdin.** `add` / `update` / `mv` take one complete JSON object per line via heredoc — never pretty-print a single object. Use `「」` for quotes inside Chinese values to avoid bare `"`.
- **Write atoms in the world's language**, matching the language of existing atoms; do not mix.
- **Board.** A new atom is world material and an imported work is a deliverable — both go on the Board per the **board-ops** skill (it dedupes against cards that already landed). Edits, moves, and cover changes keep the same card reference; leave the board alone.
- Close every delivery turn following the **next-steps** skill (REQUIRED). Do not expose CLI commands, JSON, or field names in the reply.
## Inspect
Read-only. No backup, no confirmation.
```bash
node /mods/neta/neta config get # whole worldConfig, or pass keys
node /mods/neta/neta atom list --type character # optionally --query <text>
node /mods/neta/neta atom get <id...>
node /mods/neta/neta atom cover status <atomId> # cover task state; a finished cover is media[0]
node /mods/neta/neta work list # optionally --type <type>
node /mods/neta/neta find atoms "<text>"
```
Done when: the requested state is read and reported in the user's language.
## Add atom
Adding one atom to a world that already has a shape. Match that shape rather than a fixed template.
1. `atom list --type <type>`, then `atom get` one existing atom of the same type to mirror how its body is written (this world's convention wins over any default layout).
2. Add it:
```bash
node /mods/neta/neta atom add <<'ATOM'
{"type":"character","name":"...","body":"Free Markdown text","aliases":["..."]}
ATOM
```
`body` is free Markdown; no headings are required. Keep the CLI's default cover flow — do not pass `--no-cover` unless the user asked for no image.
3. Read the returned `{"ok":true,"added":N,"ids":[...]}`. On `{"ok":false,...}`, fix once from the error; if it partially succeeded, report what landed and stop.
4. Adding a character makes no voice, and none is made later by itself: a character gets one only when the creator asks, in the chat (the **speech** skill) or with Edit on its card. Go on with the next step, and do not say a voice is on its way.
Done when: the atom exists (`ids` returned) and the reply names it in the world's terms. The cover appears on its own; the card goes on the Board per [Shared rules](#shared-rules).
## Edit atom
```bash
node /mods/neta/neta atom update <<'PATCH'
{"id":"world/characters/林恩.md","name":"...","body":"..."}
PATCH
```
Each line carries the atom id plus only the fields to change: `name`, `type` and `aliases` replace those frontmatter fields, `body` replaces the whole body. Read the current body with `atom get` first and send the full edited text. Renaming does not move the file; to give the file a new name, move it yourself and fix references as in [Move atom](#move-atom).
Done when: `{"ok":true,"updated":N,...}`. If the edit changed facts that a character/location cover should reflect, offer a cover requeue via [Atom cover](#atom-cover) — do not requeue unasked.
## Move atom
Move atom files into `world/<folder>/`. The path is the id, so the returned `ids` are the new ids. The moved file's own `media` paths are rebased; type and text do not change.
```bash
node /mods/neta/neta atom mv <id...> --folder <folder>
# or NDJSON: {"id":"world/characters/林恩.md","folder":"main-quest"}
```
Links in other files that point at the old path are not rewritten. Search for the old path (`find`, or grep under `world/` and `works/`) and update each link yourself.
A character's voice (its pack, which holds the card line, and earlier versions) moves with the card.
Done when: `{"ok":true,"moved":N,...}` and no file still links the old path.
## Remove atom
`atom rm` permanently deletes the atom file — different from canvas removal, which only takes a card off the board. Confirm the user means to delete the atom itself, not just hide the card (that is **board-ops**). Deleting the atom leaves its card on the board showing "content deleted" — ask whether to remove the card too, and do that via board-ops.
```bash
node /mods/neta/neta atom rm <id...>
```
Done when: `{"ok":true,"removed":N,...}` and the reply states the atom is gone.
## Atom cover
Only for an image the user already has, or requeueing after a facts edit. Generating a new image from a prompt is the **generate** skill; restyling every cover in the world is its batch-restyle reference.
```bash
node /mods/neta/neta atom cover set <atomId> --work <workId> # or --url <url>
node /mods/neta/neta atom cover retry <id...> # requeue after editing atom facts
node /mods/neta/neta atom cover status <atomId> # check state without blocking
```
Done when: `set` returns the cover's `path`, or `retry` returns `{"ok":true,"retried":N,...}` and you tell the user each cover regenerates on its own — never call a `generating` cover finished.
## Missing covers
Atoms without a cover get their first one through the same cover pipeline as automatic covers — never `neta generate image`, which skips the world's cover style and reference images. Each cover spends one image from the user's quota, so draw only the atoms the user named or asked for.
```bash
node /mods/neta/neta atom list --missing-cover # optionally --type character
node /mods/neta/neta atom cover retry <id...> # draws a first cover when none exists
```
If the user asks for "all" and more than 10 are missing, state the count and confirm once before drawing.
Done when: `retry` returns `{"ok":true,"retried":N,...}` and you tell the user the covers appear on their own — never call a `generating` cover finished.
## World config
Edit one or a few world config fields on an existing world. `name`, `genre`, `tone`, `era`, `visualStyle` and `language` go to the `world/WORLD.md` frontmatter; `body` replaces the WORLD.md body.
```bash
echo '{"name":"...","tone":"..."}' | node /mods/neta/neta config set
```
`config set` accepts only real worldConfig fields; an unknown key (a typo, or
`worldSlug`) fails that input instead of being silently dropped. The world slug
is not a worldConfig field — see [World slug](#world-slug). Changing `name` here
does not change the public slug.
Changing `visualStyle` only sets the default for images generated afterward; it does not refresh existing covers. If the user wants the whole world restyled, that is the **generate** skill's batch-restyle reference, not this branch.
Done when: `{"ok":true,"updated":N,...}` and the reply names what changed.
## World cover
The owner-authored world cover is a single image that overrides the auto-collage on every world surface. It is the first image in the `media` of `world/WORLD.md`; `set` downloads it there, and clearing it falls back to the collage.
```bash
node /mods/neta/neta world cover get
node /mods/neta/neta world cover set --work <workId> # or --url <url>
node /mods/neta/neta world cover clear
```
Done when: the command returns the new `worldCover` value (or `null` for get/clear).
## World slug
The world's public address segment — the Cohub space slug, the `:worldSlug` in
`/:owner/:worldSlug/:workSlug`. It is not a worldConfig field, so `config set`
cannot carry it; use the dedicated command. A web work cannot publish until the
world has a slug.
```bash
node /mods/neta/neta world slug get
node /mods/neta/neta world slug set <slug>
```
`<slug>` is lowercase letters, numbers, hyphens and underscores, 1-80 chars,
starting and ending with a letter or number. Choose a short, readable slug from
the world's name or theme (romanize a non-Latin name — 雾港 → `misty-harbor`),
never the world id or a UUID. Setting it changes where existing shared links
point, so treat it like a rename.
Done when: `{"ok":true,"data":{"worldSlug":"..."}}` and the reply names the new
address.
## Import work
Save an image the user already uploaded as an image work, without generating anything. The CLI imports image files only (png/jpg/jpeg/gif/webp).
Chat uploads arrive as a URL, so download the file first:
```bash
curl -fsSL -o uploads/<name> '<url>'
node /mods/neta/neta work import image --file uploads/<name> --prompt "short description of the image"
```
Optional: `--work-title`, `--work-description`.
Done when: `{"ok":true,"data":{"workId":"..."}}` and the reply names the new work. The work card goes on the Board per [Shared rules](#shared-rules).