Extend prose-minimum rule to all markdown files and apply it to the docs
This commit is contained in:
@@ -3,25 +3,21 @@
|
||||
Lossless conversion between **Atlassian Document Format** (ADF), an extended markdown flavour, and
|
||||
an HTML dialect.
|
||||
|
||||
**Status: specification only. No code is implemented yet.** `todo.md` holds the plan; `AGENTS.md`
|
||||
holds the decisions already made.
|
||||
**Status: specification only, no code yet.** Plan: `todo.md`. Decisions: `AGENTS.md`.
|
||||
|
||||
## What it is for
|
||||
|
||||
Atlassian Cloud REST APIs (Jira v3, Confluence) hand out rich text — issue descriptions, comments,
|
||||
pages — as ADF, a JSON node tree, ProseMirror-shaped, and take it back the same way. There is no
|
||||
Atlassian endpoint that converts it: `pf-editor-service/convert` was decommissioned and
|
||||
[JRACLOUD-77436](https://jira.atlassian.com/browse/JRACLOUD-77436) is still an open request. The npm
|
||||
ecosystem covers one direction each, drops what markdown cannot express, and none of it round-trips.
|
||||
|
||||
A consumer that shows a document and lets someone edit it needs both directions, and needs them
|
||||
lossless — otherwise saving an edit silently destroys the panels, mentions and attachments that were
|
||||
in someone else's document. That is what this library is.
|
||||
Atlassian Cloud REST APIs hand out rich text — issue descriptions, comments, pages — as ADF, a
|
||||
ProseMirror-shaped JSON tree, and take it back the same way. No Atlassian endpoint converts it
|
||||
(`pf-editor-service/convert` is decommissioned,
|
||||
[JRACLOUD-77436](https://jira.atlassian.com/browse/JRACLOUD-77436) open), and the npm ecosystem is
|
||||
one-directional and lossy. A consumer that shows a document and lets someone edit it needs both
|
||||
directions lossless — otherwise saving destroys the panels, mentions and attachments it could not
|
||||
represent.
|
||||
|
||||
## The shape
|
||||
|
||||
Pure functions and their types. No I/O, no network, no configuration. ADF is the hub: the
|
||||
markdown↔HTML directions compose through it.
|
||||
Pure functions, no I/O, no configuration. ADF is the hub: markdown↔HTML compose through it.
|
||||
|
||||
```ts
|
||||
adfToMarkdown(doc: AdfDocument): Result<string>
|
||||
@@ -37,36 +33,27 @@ isAdfDocument(v: unknown): v is AdfDocument
|
||||
|
||||
## The guarantees
|
||||
|
||||
- **`markdownToAdf(adfToMarkdown(doc))` equals `doc`** — including node types the library has never
|
||||
seen, which are carried opaquely (AGENTS.md §3).
|
||||
- **`htmlToAdf(adfToHtml(doc))` equals `doc`** — fidelity HTML cannot express rides `data-*`
|
||||
- `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely
|
||||
(AGENTS.md §3).
|
||||
- `htmlToAdf(adfToHtml(doc))` equals `doc` — fidelity HTML cannot express rides `data-*`
|
||||
attributes.
|
||||
- **Plain CommonMark is valid input** to `markdownToAdf`: any ordinary markdown a human types
|
||||
converts per the CommonMark spec. Converting back yields the library's canonical spelling, which
|
||||
then round-trips byte-identically.
|
||||
- **Foreign HTML** (not emitted by this library) maps a documented element set; an unmappable
|
||||
element is an error result, never a silent drop. The parser takes well-formed HTML, not
|
||||
WHATWG tag-soup recovery.
|
||||
- **The emitted formats are semver surface** (AGENTS.md §8): after 1.0, output an old version
|
||||
emitted always parses under a newer one within the same major.
|
||||
- Plain CommonMark is valid input to `markdownToAdf`; converting back yields the library's
|
||||
canonical spelling, which round-trips byte-identically.
|
||||
- Foreign HTML maps a documented element set; an unmappable element is an error, never a silent
|
||||
drop. Well-formed HTML only — no tag-soup recovery.
|
||||
- The emitted formats are semver surface (AGENTS.md §8).
|
||||
|
||||
## Who it is for
|
||||
|
||||
No actual consumer is named here or anywhere in this repo (AGENTS.md §7). The personas the design
|
||||
serves:
|
||||
Personas, never named consumers (AGENTS.md §7):
|
||||
|
||||
- **A viewer/editor app** — shows a document as markdown or HTML, lets a human edit, posts the
|
||||
result back. Needs losslessness above all.
|
||||
- **A bot posting content** — generates ordinary markdown (templates, LLM output) and converts it
|
||||
to ADF. Needs the CommonMark input promise; never reads ADF back.
|
||||
- **An export/indexing tool** — bulk-converts ADF to markdown or HTML for archives, search, static
|
||||
sites. Read-only; needs readable output.
|
||||
- **An LLM/agent pipeline** — feeds documents to a model as markdown, converts the model's edits
|
||||
back. Needs the round-trip plus markdown that stays legible to a reader that half-knows the
|
||||
flavour.
|
||||
- **Viewer/editor app** — shows a document, lets a human edit, posts back. Losslessness above all.
|
||||
- **Bot posting content** — converts generated markdown to ADF; needs the CommonMark promise.
|
||||
- **Export/indexing tool** — bulk ADF→markdown/HTML; needs readable output.
|
||||
- **LLM/agent pipeline** — documents to a model as markdown, edits back; needs the round-trip and
|
||||
markdown legible to a reader that half-knows the flavour.
|
||||
|
||||
## The package
|
||||
|
||||
ESM only, **no runtime dependencies**, published to public npmjs. Two entrypoints — built
|
||||
JavaScript for ordinary consumers, TypeScript source for consumers running Node's type stripping —
|
||||
with exported types either way. `AGENTS.md` §5–6 have the contract.
|
||||
ESM only, no runtime dependencies, public npmjs. Two entrypoints — built JavaScript, and
|
||||
TypeScript source for Node's type stripping — with types either way. Contract: `AGENTS.md` §5–6.
|
||||
|
||||
Reference in New Issue
Block a user