A gremlin is a folder you can talk to. Drop .gremlin/ into any directory and that directory becomes an agent โ persistent, scheduleable, and addressable from the TUI, Telegram, or a shell pipe.
No daemon. No database. No framework. No language runtime. Just bash, markdown, and the filesystem. A gremlin is a folder you can cp -r, git diff, and mv.
Install into the current directory:
curl -fsSL https://raw.githubusercontent.com/zealtv/gremlin/main/install.sh | bash -sThat lays down .gremlin/ and, because a gremlin with no nest cannot be
tended, installs any of the five primitives you are missing by running each
project's own installer โ once, at install time. After that gremlin never
touches them: /update overlays .gremlin/ alone, and doctor reports a
missing primitive rather than reaching for a private copy. Add
GREMLIN_SKIP_PRIMITIVES=1 to install the tender by itself.
Point it at a model. .gremlin/models/default.sh is just an executable that reads a prompt on stdin and writes a reply on stdout โ edit it for whichever CLI you use (Claude Code, Codex, Open Code, a local model, anything):
#!/usr/bin/env bash
exec claude -p --model claude-sonnet-4-6 --allowedTools "Bash"Wake it and open the TUI:
.gremlin/gremlin wake
.gremlin/gremlin tuiThe verbs are wake, sleep, tend, and prompt โ plus status, restart,
and tui. prompt submits one conversational turn and waits for its response;
prompt --read-only asks the model to inspect and answer without changing
files or external state.
Run /help for commands.
- Create a bot with
@BotFatherand copy the token. - Get your numeric chat id from
@myidbot. - Copy
.gremlin/bridges/telegram/config.exampletoconfig, fill inTELEGRAM_BOT_TOKENandTELEGRAM_CHAT_ID, then.gremlin/gremlin telegram start.
- It has a name. Rolled at first start from a pinned list of mythic
creatures and kept for good โ the gremlin's own name, not its folder's, so
"the gremlin" and "the repo it tends" stop being the same word.
/nameto change it. - The agent is a folder. Copy it, fork it, version it, delete it. There is no hidden state.
- Almost no dependencies. Bash, coreutils, and whatever CLI talks to your model. Updating is
/updateโ an overlay that preserves your identity, model presets, transcripts, memory, and queues. - Bring your own model. A model preset is just
stdin โ stdout. Swap models with/model <alias>. Non-LLM scripts work too. - One inbox, many sources. TUI, Telegram, scheduled ticks, peer gremlins, and
gremlin promptall funnel through.nest/in/. One tender loop, one dispatch rule. An item's shape picks the route: amessage.mdlands in the transcript with no model call, arun.shruns, anything else is a turn. - One prompt verb. Questions and instructions use the same one-shot exchange. Read-only intent is an explicit option, not a guess based on conversational wording.
- Composition is adjacency. Multiple gremlins = multiple folders. Delegation is
mv item ../other/.nest/in/. - Scheduled and persistent. Background tend + tick loops give you reminders, nightly summaries, and self-initiated work without a separate scheduler.
- Append-only transcript.
transcript.mdis the source of truth. Bridges tail it. Debugging iscat. - Memory you control. Glean stores findings as flat markdown; the catalog is broadcast by default, bodies are fetched on demand, and selected findings can be promoted into full context with a symlink.
- A library, not just memory. Lore keeps complete, dated records โ specs, decisions, transcripts โ whole and findable, durable and dark by default: the append-and-keep sibling to Glean's revisable memory.
- Everything is a file. Skills, tools, commands, model presets, bridges โ every extension point is a directory of small scripts or markdown.
your-repo/
โโโ AGENTS.md the map: generated primitives block + your preamble
โโโ CLAUDE.md symlink to AGENTS.md, for runtimes that look for it
โโโ .nest/ inbox / claimed / completed items
โโโ .loom/ finite work: threads and stitches
โโโ .lore/ durable, dated records
โโโ .glean/ memory workbench
โโโ .groundhog/ scheduled work
โโโ .gremlin/ the optional tender
โโโ gremlin.md identity, personality, voice
โโโ context/ always-loaded context, including managed system/ links
โโโ skills/ markdown procedures with triggers
โโโ tools/ bash tools the gremlin can run
โโโ models/ stdin โ stdout model presets
โโโ commands/ slash commands
โโโ bridges/ TUI, Telegram, web
โโโ transcript.md append-only conversation log โ private
โโโ gremlin the executable
The five primitives live at the host root, not inside .gremlin/. A gremlin
is the optional tender of a folder: it sits beside them and acts on them, the
same files a human acts on. A primitive dotdir still inside .gremlin/ is
legacy placement โ gremlin doctor says so.
.gremlin/bin/index-primitives.sh writes the primitives section of the host's
AGENTS.md between markers, from what is installed on disk โ a reading order,
what each dotdir owns, and one line per primitive taken from its own README.
Prose outside the markers is yours and is never touched. gremlin doctor runs
the generator, so the map cannot rot; it also works on a repository with no
gremlin at all:
.gremlin/bin/index-primitives.sh [host-dir]User-facing docs live inside the installed gremlin:
.gremlin/README.mdโ full usage guide.gremlin/docs/protocol.mdโ loops, transcript, dispatch, models.gremlin/docs/composition.mdโ multiple gremlins, delegation, sandboxing
The underlying file-based protocols are separate installs, siblings of
.gremlin/ rather than parts of it, and documented on their own:
- ๐ชบ nestlings โ queueing and actioning work
- ๐ฆซ groundhog โ scheduling recurring tasks
- ๐ฎ glean โ memory distillation and retrieval
- ๐ lore โ durable, dated reference and record
- ๐ชก loom โ planning structured work
The protocol does not enforce a sandbox. Host a gremlin where broad shell and file access is acceptable. For real isolation, wrap .gremlin/bin/llm.sh with a separate UNIX user, container, VM, sandbox-exec, bwrap, or equivalent.