Commit 96b37d3fa7

96b37d3fa745882eeebee306f12cf8b0dde54a79

parent: a6f707b7db

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-22 17:39 UTC

docs: previews render with FormattedBodyView, under the editor

Layout: unified · split

docs/superpowers/specs/2026-09-22-parity-followup-design.md +30 −23
@@ -123,29 +123,36 @@ on `loadMore`, and does not reorder; `MRFilter.flags()` with a label;
123The web previews by posting the draft back to its own form, where the 123The web previews by posting the draft back to its own form, where the
124server renders it with autolinks resolved for the viewer. No command 124server renders it with autolinks resolved for the viewer. No command
125renders markup (the CLI row is `n/a`), and the app resolves no 125renders markup (the CLI row is `n/a`), and the app resolves no
126autolinks anywhere. The app previews locally with the renderer it 126autolinks anywhere. The app previews locally with `FormattedBodyView`,
127already uses for READMEs and wiki pages. The preview therefore matches 127the view its threads, bodies and comments already render with. The
128what the app shows, not what the web shows: `#N` stays plain text in 128preview therefore matches what the app shows, not what the web shows:
129both the preview and the thread. 129`#N` stays plain text in both the preview and the thread.
130 130
131- New `MarkupEditor` in `gitbay/Views/Shared/`: a Write/Preview 131- New `MarkupPreview(text:format:identifier:)` in
132 segmented control over a `TextEditor`. Preview renders 132 `gitbay/Views/Shared/`: a collapsed "Preview" disclosure row that
133 `ReadmeView(name: "draft.<ext>", content: text)`, with `<ext>` `org` 133 renders `FormattedBodyView(text:format:)` when expanded, and "Nothing
134 for org and `md` otherwise. Each call site passes its existing 134 to preview." for blank text. It sits under the editor rather than
135 modifiers (font, autocorrection, accessibility identifier) through. 135 replacing it, so the draft stays visible and editable, as on the web.
136- Call sites: 136- `MarkupPreview.format(forFile:)` maps a file name to the format its
137 - `ComposeSheet` body: issue and MR create and edit, and release 137 contents render in: `org` for `.org`, `md` for `.md` and
138 edit. The extension follows the sheet's `format` binding. 138 `.markdown`, nil for anything else.
139 - Comment fields in `IssueView` and `MRView`: always `md`, since a 139- Call sites, each passing the format it already sends:
140 comment with no `--format` is markdown. 140 - `ComposeSheet`'s body: issue create, issue and MR edit, release
141 - Release notes in `ReleaseListView`'s create sheet: `md`. 141 edit. The format follows the sheet's `format` binding, which is
142 - `FileEditSheet`: the real file name, and the control only when it 142 `md` where the sheet shows no picker.
143 ends in `.md`, `.markdown` or `.org`. `ReadmeView` treats every 143 - `MRCreateSheet` in `MRListView`: its own `format`.
144 other name as markdown, so the gate is the sheet's. 144 - The comment rows in `IssueView` and `MRView`: their
145 145 `commentFormat` picker. Shown only while the comment is non-empty.
146Tests: the extension chosen for each format; `FileEditSheet` offers 146 - `ReleaseCreateSheet` in `ReleaseListView`: `md`, since
147preview for the three extensions and not for `.swift`. The live suite 147 `release create` sends no `--format` and the app renders notes as
148toggles preview on an issue comment and finds rendered text. 148 markdown.
149 - `FileEditSheet`: only when `format(forFile:)` is non-nil, with that
150 format.
151
152Tests: `format(forFile:)` for `.org`, `.md`, `.markdown`, `.MD`,
153`.swift` and a name without an extension. The live suite types a
154comment on the fixture issue, expands its preview and finds the
155rendered text, then clears the field without sending.
149 156
150## 1.6.0: admin 157## 1.6.0: admin
151 158