DSH Hub

geml-spec/geml

geml

ToolWorkflow29 GitHub stars· updated 2026-10-27

One format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar.

Install

npx @deepseek-ai/dsh plugin --profile web add @geml/dsh-plugin

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

geml DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/geml.svg)](https://dshhub.dev/plugins/geml)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from geml-spec/geml, cleaned of badges and images.

GEML — General Expressive Markup Language

English | 中文

GEML is a lightweight markup language with uniform, addressable blocks and standard verbs.<br> Easy for humans to read, safe for agents to mutate. In agent-driven development and knowledge work, plain text and Markdown have no deterministic block boundaries: a program and a model trade the whole file in and the whole file back out — at best probing for it with line windows, and restating the original verbatim to rewrite it. Token cost grows with the length of the document, and the operation turns bloated. After a few rounds of rewriting, the copies excerpted elsewhere start to drift.

You can start without changing a thing. geml list, geml find and geml get address the Markdown you already have — nothing is converted, no new files, your .md stays .md:

geml list    README.md                          # every section, as an address
geml get     README.md '#key-features'          # read ONE section, not the file
geml set     README.md '#key-features' --body   # write one section back
geml replace README.md 'old text' 'new text'    # swap a string, told which block held it
geml history save README.md -m 'tighten intro'  # a revision into README.md.gemlhistory, beside the file

Only that section enters the agent’s context — a couple of KB, not the whole file, however long it grows. And every save is a revision you can read back or roll back, one block or the whole file.

▶ Try it in the Playground — no install, nothing to read first.

Need finer than a section — one block, one chart, one table? Let .geml stand in the middle ground: edit at that grain, and the --to md you ship never drifts from it.

A block has a name; the things inside it have a coordinate. A table's cell, a data block's leaf, a key in meta — each has a coordinate the structure already gives it, and get and set land on exactly that value.

geml get doc.geml '#fy[2]["Q1"]'                     # one cell
geml set doc.geml '#intake["fields"][1]["name"]'     # one leaf in the JSON

For people, it is plain text that reads clean; for agents, it is an addressable, verifiable, traceable, revertible "Doc-as-a-Base".


GEML is minimal. It is plain text — still clean with no renderer in sight; one block syntax for the whole language; addressable, verifiable, referenceable structure, natively.

Instead of a separate mini-syntax for each kind of content, GEML carries every kind in one container: the typed block. Code is a block. So are tables, diagrams, math, callouts, even metadata — and a run of prose can be one too (=== text), whenever you want it addressable. Extending it later is just as plain. The shape is the same every time, which makes the language easy enough to learn that it's hard to get wrong.

=== code {#hello lang=python}
print("hi")
===
geml get doc.geml '#hello'   # by name, just this block

Blocks have names so the verbs have somewhere to land — the full syntax is in the format in 1 minute.

…

Related plugins