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.
desktop-pet-companion
Community@rain/desktop-pet-companion
Community skill — not reviewed. It was shared by caramel pudding and has not been checked by Neta. Read SKILL.md below before letting an agent use it.
Use it in Cohub
Paste this into your agent's chat — it fetches the skill and follows it.
Use the skill: desktop-pet-companion. Run `npx -y @neta-art/neta-search-cli@latest skills use @rain/desktop-pet-companion --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 @rain/desktop-pet-companion
Summary
Turn your character into a little desktop companion that reacts to taps, greets you, and shares memories as you bond.
Your character sits on a small stage; tap it for a reaction, drag it around, or press and hold to open a menu.
It greets you differently in the morning, afternoon, evening and late at night, and speaks up by itself when you go quiet.
Talking and giving gifts raise an affection meter; five milestones each unlock a private inner thought, shown once.
Works without any chat service, using the character's own lines. You can optionally connect your own chat service for live replies.
Works best with a character who has a clear personality and at least one good picture; extra expressions are simulated by moving that picture.
SKILL.md
# Desktop pet companion
Small on purpose: a character, a mood, a line, and a reason to come back. The affection system is the spine — every
interaction moves one number, and that number unlocks memory. Everything else is timing and tone.
## What the user gets
A published web Work: the character on a small stage, tap/drag interaction, a greeting by time slot, idle lines,
affection with five memory unlocks, a small menu (talk, gift, memories, settings), and optional LLM chat.
## Inputs — and when to ask
| Item | Required | Counts as given when | Default |
|---|---|---|---|
| Character art (at least idle) | yes | Attached or a material | Ask once, stop |
| Voice / sound | no | Files given | Silent, with a text bubble |
| Personality lines | no | Given | Short, neutral, in the character's register |
| LLM endpoint + key | no | The user offers one | Local lines only; never request a key |
Only the art is a stop. Never ask for an API key as part of the build.
## State model
| Field | Range | Notes |
|---|---|---|
| `affection` | 0–100 | +1 per talk turn, +3 per gift, never negative |
| `turns` | counter | total interactions |
| `unlocked` | string[] | memory ids already shown |
| Memory thresholds | **15, 35, 55, 75, 95** | each unlocks one inner monologue, once |
| Idle timer | **55 s** | one idle line, then re-arm |
| Greeting slots | morning / afternoon / evening / late night | chosen from local time |
Persist all of it under one localStorage key with a schema version. A reload must not replay an unlock.
## Build order
1. **Stage.** A small floating character (roughly 40–60% of the viewport height) over a soft background, draggable
within bounds; a tap triggers a reaction, a long press opens the menu. Keep the page free of scrollbars.
2. **Expression set.** Idle, blink loop (random 3–7 s), talk, happy, shy, sleepy. If the user only has one image,
synthesise the rest with CSS transforms (scale, rotate, a 2 px bob) and say so — never fake extra art.
3. **Greeting.** On open, pick a slot from the hour and one line from that slot. Use the character's register, not
generic assistant tone.
4. **Talk loop.** Type the line at 45–90 ms per character, hold it, then hide. While typing, switch to the talk
expression; on end, back to idle. Queue lines instead of overlapping bubbles.
5. **Affection.** Every talk +1, every gift +3, clamp at 100. When a threshold is crossed, pause the normal line and
play the unlocked memory as a distinct beat (different bubble style, slower typing), then mark it unlocked.
6. **Idle.** After 55 s with no input, one idle line drawn without repetition (keep the last three used). Cancel the
timer on any pointer event and re-arm after the line.
7. **Optional LLM.** Only if the user supplies an endpoint. Read the config from a settings panel into memory, never
into the shipped files, never into a URL query. Show a clear "not connected" state, keep the local lines as the
fallback for every error (timeout 20 s, refusal, empty reply). Send at most the last 8 turns, and never send the
image unless the user explicitly asks for that.
8. **Gift.** A small set of items (emoji or the user's images); each gift has one reaction line and +3. Cap gifts per
session so the meter is not farmed in ten seconds.
9. **Publish** with `neta work init web`, then `neta work publish web`.
## Fallbacks
- No LLM: local lines, clearly presented as the character's own voice, not as an error.
- LLM returns a refusal or an empty string: one in-character deflection, then a local line; never show a raw error.
- No voice audio: text only; do not fake a lip-sync animation without a mouth layer.
- Hidden tab: pause the idle timer and the blink loop.
## Gotchas
- One number, one writer. Affection updates from talk, gift and memory must go through one function, or thresholds
double-fire.
- Do not unlock a memory on load just because the saved affection is already past the threshold; only unlock on the
transition.
- An idle line that repeats feels broken faster than silence does.
- The LLM key, if any, lives only in the viewer's browser. Never write it into the source, the Work, or a log.
## Verify
`node scripts/verify.mjs <work-dir>` checks: entry, no remote assets, the affection clamp, the five thresholds, the
55 s idle constant, the greeting slots, the persistence key, and that no key-shaped string exists in the files.
Then talk five times, cross one threshold, wait out the idle timer, reload, and try the LLM path with no config. Report
what you ran.
## Deliver
Publish the Work, put its card on the Board, and hand it over with an interaction-components card whose target is the
Work — the id comes from the publish output.
## Out of scope
No world-setting changes, no deleting files, no API keys in the skill or the Work, no pretending to be a real person,
no emotional dependency mechanics that punish leaving.
## Language
Reply in the user's language, whatever language this file is in — every message, the final handover included. All
lines, menu labels and memories follow the user's language and the character's register; keep them in a data file, not
in the markup.