swaylq/dsh-wildmon0

dsh-wildmon

A collect-em-all safari for DeepSeek Harness: your real work is the tall grass. Turns, tool calls and errors roll wild encounters; throw balls, fill a 28-slot dex, build a team of six. Zero tokens, zero tools, the model never knows.

AI 分析

核心用途是将 DSH 的日常使用转化为收集类冒险游戏。适合想要在枯燥的编码或调试工作中寻找随机惊喜的用户。零 Token 消耗,不影响 Agent 运行上下文。

パッケージ
dsh-wildmon
バージョン
0.1.0
ライセンス
MIT
最終更新
2026/08/15

インストール

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:swaylq/dsh-wildmon

ドキュメント

README 全文を読む ↗

dsh-wildmon

English | 中文

Your real work is the tall grass. Turns, tool calls and errors rustle it — wild critters pop out at random, you throw balls, fill a 28-slot dex, and walk with a team of six. The small hours wake nocturnal species, errors wake the glitch ones, and three legendaries each guard their own appearance condition.

Zero tokens, zero tools, zero context injection: the model never learns any of this exists.

野生的 绒电鼠 Volttuft 出现了!◈ 少见 · 常野原
(A wild Volttuft appeared! Uncommon · Field)

  ⟋⟍  ⟋⟍
  (⚡ᴥ⚡)
  c(   )ɔ
    ⌁⌁

球 ×9 —— /mon throw to throw · /mon run to retreat

The catch ceremony

Why this exists

The DSH pet lane is busy: twenty-plus desk pets are state mirrors (agent thinks, pet does a thinking animation), and dsh-digipet added raising (one pet eats your work and evolves).

Collecting was still an empty slot: no encounters, no catching, no "looking forward to the next error because the dex wants it." As of 2026-08, searching the dsh-plugin topic (2,800+ repos) and all four curated awesome lists for pokemon / pokedex / catching / gacha returns zero hits. dsh-wildmon fills that slot — the complete collect-em-all loop (encounter → catch → dex → team) mounted on your actual workflow.

It complements digipet rather than replacing it: digipet is depth with one creature, wildmon is breadth across many. Both install side by side (different command, different save file).

How to play

  1. /mon start — pick one of three starter-trio critters, get 8 balls.
  2. Work normally. Every turn, message, tool call and error has a chance to rustle the grass; the longer nothing shows, the higher the odds (a pity mechanic).
  3. /mon to check. A wild one waits 10 minutes, then wanders off.
  4. /mon throw. Rarer species are harder to catch; every miss improves your next throw — but it may also bolt.
  5. Fill the dex, build the team: your first six catches auto-join, and slot 1's aura raises its home habitat's encounter rate ×1.5. Rearrange with /mon swap.

Habitats: how you work decides who you meet

HabitatWhat rustles itResidents
Field (常野原)messages, turns, unclassifiable toolsFluffgrub, Dotfinch, Volttuft…
Forge (锻造窟)writing files, running commandsMalletclaw, Cogbadger, Coredrake…
Archive (墨书林)reading code, searching docsMarkmoth, Indexowl, Tomewyrm…
Glitch ridge (故障岭)failed tools, agent errorsShardtoad, Tracepede, Panicray…
Night bound (夜阈)anything between 00:00–05:59Lunasmudge, Dozetapir, Stardrift

Plus the starter trio (the two you didn't pick roam the field) and three legendaries: one surfaces every 250 turns; one only answers a deep-night error; the last only visits collectors who completed the first 25 slots. Shinies exist, at 1/64.

Ball economy: 8 to start, +1 per finished turn (cap 30), and catching a species you already own trades the catch back for 2 balls — duplicate encounters are never a loss.

A wild encounter The dex

Install

dsh plugin --profile web add github:swaylq/dsh-wildmon
# or a local checkout
dsh plugin --profile web add /path/to/dsh-wildmon

Restart dsh. Pure JavaScript, zero dependencies, no prepare script — installing from git needs no build approval.

Already running dsh-digipet? Just install this too; they don't interact. If /mon collides with another plugin, override config.command in your profile patch.

Commands

CommandDoes
/monCheck the grass: encounter card (art, rarity, time left) or quiet status
/mon startBegin the journey (bare form lists the three candidates)
/mon throwThrow one ball at the live encounter
/mon runBack out of the standoff
/mon dexCollection: caught ● / seen ◐ / unknown ○; legendaries show only rumors
/mon teamParty and box (its numbering feeds swap / name)
/mon swap Reorder the party or exchange with the box (slot 1 leads)
/mon name Nickname a caught partner (16 chars)
/mon storyThe journey log
/mon aboutMechanics and the trust stance

How it works

The whole plugin is four event taps and one slash command; the taps only roll dice:

TapBase encounter rate
agent/turn-stopping (also refills 1 ball)9%
agent/inbox/claimed (your messages)5%
tools/result (routed by tool name to forge/archive/field; failures → glitch)6% / 16% on failure
agent/error20%

On top: +0.8% per quiet event (capped at +25%), lead's home habitat ×1.5, and at night a 70% roll swaps in the night pool. Catch odds = rarity base (65% / 45% / 28% / 12%) + 12% per prior miss, capped at 95%; after a miss the wild one may flee at a rarity-scaled rate. Every number lives as a named constant at the top of core.js.

The save lives at $DSH_HOME/wildmon/state.json, written the way the official JSON storage backend writes: temp file + fsync + atomic rename, throttled to one write per 1.5 s no matter how busy the agent is.

The invariant that matters: model-visible means logged — and this plugin simply shows the model nothing. No tool registration (tool schemas are a per-request token tax), no agent.inject(), no session events. The whole game lives in command result cards and contributes zero bytes to every model request.

Trust stance

  • Reads: only its own save file. Never your code, never conversation content — the listeners use only what kind of thing happened; message and tool payloads never touch the save.
  • Writes: only $DSH_HOME/wildmon/state.json.
  • Network: none.
  • Model-visible surface: none. Zero token cost; KV cache untouched.
  • Randomness: affects the game only. The listeners never veto, rewrite or delay real work (all hooks are notification-mode events).
  • Blast radius: every listener is wrapped in try/catch and the command handler has its own catch — a collapsing grassland cannot land on your work.

Known limits

  • One dex per DSH home; all profiles, sessions and subagents on the machine share (and rustle) the same grass — feature and limit at once.
  • Concurrent dsh processes: last writer wins, same single-process stance as the official JSON backend.
  • Encounters don't notify you (the price of a zero model-visible surface) — you check with /mon; the wild ones wait 10 minutes and misses land in the story log.
  • Tool routing is a name-regex heuristic; oddly named third-party tools count as field.
  • The night window is machine-local 00:00–05:59; travel across time zones and the nocturnals jet-lag with you.
  • Rates and thresholds are not configurable: changed numbers would leave the dex and the save with no common language.

Verification record

Verified for real on dsh 0.1.0-rc.6 (macOS, web profile):

  1. Installed with dsh plugin --profile web add ; the wildmon layer shows in --dump-config;
  2. dsh web boots clean;
  3. In a real browser, /mon start picks a partner and the send-off card renders (monospace, newlines kept);
  4. Six plain messages without an API key — every model request fails, but inbox/claimed and agent/error are real events: the save recorded messages:6, mishaps:6, and with pity at 10 the 6th round really spawned a Shardtoad (error event → glitch ridge, matching the table);
  5. /mon throw missed once (the card showed the throw-bonus note), caught on the second — party 2/6, dex 2/28, balls ×6 = 8 − 2 throws; the save reconciles line by line with the observed events;
  6. Observed caveat: on rc.6, MISSING_CREDENTIAL failure rounds do not fire agent/turn-stopping, so the per-turn ball refill wasn't observable on a keyless machine (it needs turns that complete); that path is covered by unit tests;
  7. 61 unit/integration tests (node --test) covering pure logic, rendering, the store and a fake-ctx integration.

Homage and boundaries

The design pays homage to the collect-em-all genre's traditions (grass encounters, the three-shake catch, a dex, a starter trio, an electric rodent, shinies). Pokémon is a trademark of Nintendo / Creatures / Game Freak; this project is not affiliated with them in any way. All 28 species names, ASCII art and text are original; no official names, characters or assets appear. The ball is just a ball that wobbles — that belongs to everyone who loves collecting things.

License

MIT