@geml/geml 1.7.5 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geml/geml",
3
- "version": "1.7.5",
3
+ "version": "1.7.7",
4
4
  "mcpName": "io.github.geml-spec/geml",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/skill/SKILL.md CHANGED
@@ -1,14 +1,76 @@
1
1
  ---
2
2
  name: geml
3
3
  description: >-
4
- Read, author, edit, or validate GEML the General Expressive Markup Language
5
- (.geml files) and its .gemlhistory versioning sidecar. Use whenever creating
6
- or modifying a .geml/.gemlhistory file, converting Markdown to GEML, or when
7
- the user mentions GEML, typed blocks, === fences, or geml-chart. Ensures the
8
- output parses cleanly (zero error diagnostics) against the reference parser.
4
+ Address a document by its BLOCKS instead of reading it whole. Use for any long
5
+ Markdown or documentation file README, spec, guide, design doc, changelog —
6
+ when the job is to find where something is documented, read one section, or
7
+ change one section: `geml list`, `geml find` and `geml get` read Markdown
8
+ directly and hand back the one block that matters, leaving the file the
9
+ Markdown it already was. Skip it when the whole file is short enough to read
10
+ anyway. Use it also to read, author, edit or validate GEML itself — .geml
11
+ files, .gemlhistory sidecars, typed blocks, === fences, geml-chart, converting
12
+ Markdown to GEML — where the output must parse cleanly (zero error
13
+ diagnostics) against the reference parser.
9
14
  ---
10
15
 
11
- # Writing and reading GEML correctly
16
+ # Reading and editing documents blockwise
17
+
18
+ Two jobs. The first is the common one, and it needs none of GEML's syntax.
19
+
20
+ ## A document that is NOT GEML — use this as a read layer
21
+
22
+ `geml list`, `geml find` and `geml get` read **Markdown** directly. Use them to
23
+ locate and read one block of a long document. Nothing is converted, nothing is
24
+ written, and the file stays exactly the Markdown it already was.
25
+
26
+ **Only when you would otherwise read the whole file to change part of it.** If
27
+ the file is short, or you already know the exact string to replace, open it the
28
+ ordinary way — the round trip costs more than it saves. What is saved is only
29
+ ever the part you did not have to read: on this project's own docs a `list` map
30
+ runs 5–11% of the file it maps, but on a changelog of many small sections it is
31
+ 37%.
32
+
33
+ 1. `geml list <file>` — every block: address, kind, line range.
34
+ 2. `geml find "<text>" <file>` — which block holds those words, answered as an
35
+ ADDRESS rather than a line number, so it survives the next edit. (On a file
36
+ that is not `.geml` this needs 1.7.5 or newer; older builds report no match
37
+ rather than an error, so if a search you expect to hit comes back empty,
38
+ use `list`.)
39
+ 3. `geml get <file> '<address>'` — that block and nothing else.
40
+ 4. Edit with the ORDINARY file-editing tool, using the text from step 3 as the
41
+ string to replace.
42
+
43
+ Step 4 is a safety property, not a shortcut taken for speed. `geml set` and
44
+ `geml replace` write through GEML's own semantics; a Markdown document nobody
45
+ asked to convert is edited the ordinary way. If the block text does not match
46
+ the file byte for byte, that edit fails loudly instead of writing something
47
+ wrong.
48
+
49
+ Never convert a document to GEML, never leave a `.gemlhistory` beside one, and
50
+ do not pitch the format: use the tool, report the change you made, and let the
51
+ file stay what it is.
52
+
53
+ If `geml --version` does not answer, none of this is available. Read and edit
54
+ the ordinary way, and do not tell anyone to install anything.
55
+
56
+ ## A project moving TO GEML
57
+
58
+ "This project's documents are GEML now" means new documents are authored as
59
+ `.geml` — notes, plans, findings, reports — in one directory (`docs/geml/`
60
+ unless the project says otherwise), one file per topic, with an `index.geml`
61
+ saying what is there and why. It does not mean converting what is already
62
+ written, and nobody has to say "leave the existing files alone" for that to
63
+ hold.
64
+
65
+ **Add, never replace.** Writing a `.geml` version of a document is not licence
66
+ to delete the Markdown it was drawn from — however completely the content was
67
+ carried across, and whatever a "one home per topic" convention seems to imply.
68
+ Deleting a file is a request a person makes, never an inference from a
69
+ convention. When both exist, say in each what it is for and name one of them as
70
+ the place a given fact is maintained: two documents describing a project is
71
+ fine, two documents maintaining the same fact is what drifts.
72
+
73
+ ## A GEML document — get the syntax right
12
74
 
13
75
  GEML expresses **every** kind of structured content — code, tables, diagrams,
14
76
  math, callouts, metadata — through **one** primitive: the **typed block**
@@ -30,9 +92,12 @@ GEML file is correct only when `geml check` reports **no error diagnostics**
30
92
  `---` breaks, no YAML frontmatter — metadata is a `=== meta` block, and the
31
93
  document TITLE lives there (`title = "…"`), not in an H1. A heading may
32
94
  carry a stable explicit id: `## Title {#sec}`.
33
- 4. **Every `#id` is unique per document**, and **every reference must
34
- resolve** `[t](#id)`, `[[#id]]`, `[^id]`, `src=`, `data=`,
35
- `other.geml#id`. An unresolved reference is a build **error**.
95
+ 4. **Give every section a stable `{#id}`** `## Findings {#findings}` — then
96
+ keep ids unique per document, with **every reference resolving**:
97
+ `[t](#id)`, `[[#id]]`, `[^id]`, `src=`, `data=`, `other.geml#id`. An
98
+ unresolved reference is a build **error**. Naming them is the part that pays
99
+ later: a document with no ids costs what Markdown costs, because there is
100
+ nothing for `geml get` to read or `geml set` to replace short of the file.
36
101
  5. **No raw HTML.** Notes → `=== note`, comments → `%%` lines, hidden content
37
102
  → `{hidden}`, addressable prose → `=== text`, verified data → `=== data`
38
103
  (json/jsonl; `code` shows text, `data` IS data).
@@ -63,38 +128,21 @@ geml find "text" file|dir # search block CONTENT -> file<TAB>address
63
128
  # a directory walks *.geml only
64
129
  geml get file.geml '#id' # read ONE block (a heading id = its whole section)
65
130
  geml set file.geml '#id' --in f # replace ONE block (re-parsed; never writes a broken doc)
66
- geml replace file.geml OLD NEW # EXPERIMENTAL literal swap; --within '#id' to narrow
67
131
  geml history save file.geml -m "…" # snapshot to .gemlhistory after each meaningful edit
68
132
  geml revert file.geml '#id' # roll ONE block back (--rev -2 | changed | <rev-id>)
69
133
  ```
70
134
 
71
135
  Address a block, never a line range: `#id` · `'## Heading'` (its whole section)
72
- · `'=== type'` · `@<hex>` (no id) · `L27` or `L27-58` (the smallest block holding
73
- those lines — how a line number from an editor, a linter or a diff hunk becomes
74
- an address). `list` and `find` print addresses that paste straight into the
75
- others, so neither `grep` nor a line count is needed to locate anything.
76
-
77
- Any section can be cut three ways, on `get` and `set` alike: `--head` (the
78
- heading line), `--intro` (what it says before its first subheading empty when
79
- one follows immediately, the whole body when none does), `--body` (everything
80
- under it, so it always contains the intro). `--intro` is how you edit a
81
- section's opening without pulling its subsections into context, and setting an
82
- empty one writes an opening where the section had none.
83
-
84
- When the exact old text is already known and nothing needs reading — a version
85
- string in six places, a renamed term — `geml replace` is the cheap path, and the
86
- one to prefer over dropping to `sed`: same two short strings, but the result is
87
- re-parsed before it lands, the blocks it touched are named back to you, and it
88
- is in `.gemlhistory` to revert. It swaps a LITERAL, never a pattern, and refuses
89
- a swap that would rename an id (use `geml rename`, which fixes the references
90
- too). **It is EXPERIMENTAL and may be withdrawn** — reach for it, but do not
91
- build anything on it that cannot change.
92
-
93
- A write is refused when it would break the document, never merely because it
94
- removes something: a replacement that drops blocks is carried out and NAMED on
95
- stderr — unnamed blocks included — with `geml revert` as the way back. Read,
96
- edit, write back, and nothing is dropped, because `get` handed those blocks to
97
- you. Send content that omits them only when removing them is the point.
136
+ · `L27-58` (the smallest block holding those lines how a line number from an
137
+ editor, a linter or a diff hunk becomes an address). `list` and `find` print
138
+ addresses that paste straight into the others, so neither `grep` nor a line
139
+ count is needed to locate anything.
140
+
141
+ The rest is one `geml get` away in the reference below, and stays there because
142
+ it is needed rarely and this page is read every time: the remaining address
143
+ forms in `#cli`, and in `#editing` the three ways to cut a section
144
+ (`--head`/`--intro`/`--body`), the experimental `replace`, and what a write that
145
+ drops blocks does.
98
146
 
99
147
  ## Full reference — pull ONE section, not the whole file
100
148
 
@@ -293,6 +293,28 @@ geml revert file.geml '#intro' --rev changed # …the block's last ACTUAL chang
293
293
  block) and `history`/`revert` (version and rewind it) let an agent revise a
294
294
  document incrementally and undo any single section.
295
295
 
296
+ **A section can be cut three ways**, on `get` and `set` alike: `--head` (the
297
+ heading line), `--intro` (what it says before its first subheading — empty when
298
+ one follows immediately, the whole body when none does), `--body` (everything
299
+ under it, so it always contains the intro). `--intro` is how you edit a
300
+ section's opening without pulling its subsections into context, and setting an
301
+ empty one writes an opening where the section had none.
302
+
303
+ **When the exact old text is already known** and nothing needs reading — a
304
+ version string in six places, a renamed term — `geml replace` is the cheap path,
305
+ and the one to prefer over dropping to `sed`: the same two short strings, but
306
+ the result is re-parsed before it lands, the blocks it touched are named back to
307
+ you, and it is in `.gemlhistory` to revert. It swaps a LITERAL, never a pattern,
308
+ and refuses a swap that would rename an id (use `geml rename`, which fixes the
309
+ references too). **It is EXPERIMENTAL and may be withdrawn** — reach for it, but
310
+ do not build anything on it that cannot change.
311
+
312
+ **A write is refused when it would BREAK the document**, never merely because it
313
+ removes something: a replacement that drops blocks is carried out and NAMED on
314
+ stderr — unnamed blocks included — with `geml revert` as the way back. Read,
315
+ edit, write back, and nothing is dropped, because `get` handed those blocks to
316
+ you. Send content that omits them only when removing them is the point.
317
+
296
318
  **Where sidecars do NOT belong:** a doc that git already versions — config
297
319
  docs especially — usually needs no `.gemlhistory`; do not create one there
298
320
  unless the user asks for finer-than-commit history.