Skip to content

Commit 6e1ffd3

Browse files
committed
docs(skill): document --markdown mode and MarkdownDoc component
Updates the Claude Code skill to cover v0.2.0 additions: - SKILL.md: rename 'three modes' to 'four modes', add --markdown (Mode 3) with --comments/--edits/--allow-html flags and comment object shape. Renumber HTML agent:// to Mode 4 with a 'try Mode 3 first' nudge. Add MarkdownDoc as component #12 in the A2UI catalog. Flag missing mode flag as the most common exit-3 failure. Document NSURLErrorDomain -1100 troubleshooting. - references/templates.md: fix stale 'no markdown — plain text only' line (true for Text, not for MarkdownDoc/--markdown). Add Template 5: markdown document review with flag matrix and response shape.
1 parent fb49ce3 commit 6e1ffd3

2 files changed

Lines changed: 97 additions & 8 deletions

File tree

skill/SKILL.md

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ If running the command feels risky, ask for permission to run it — not to past
2121
| Collecting 3+ related fields (name + role + options) | **Yes** — one form beats N questions |
2222
| Presenting 5-20 options to choose from | **Yes** — radio/select picker |
2323
| Showing a diff/preview/report before user confirms | **Yes** — formatted content is readable |
24+
| Reviewing a markdown doc (spec, PR description, draft) with comments/edits | **Yes** — use `--markdown` mode (Mode 3) |
2425
| Simple yes/no question | **No** — just ask in terminal |
2526
| Agent-side computation taking >30s before UI can render | **No** — show a text status instead |
2627
| Non-interactive environment (CI, piped output) | **No** — preflight will fail, fall back to terminal |
@@ -42,7 +43,9 @@ fi
4243

4344
If preflight fails, fall back to terminal Q&A — don't try to be clever. Report why the webview path isn't available and continue in text.
4445

45-
## The three modes
46+
## The four modes
47+
48+
**Exactly one of `--a2ui`, `--url`, or `--markdown` must be specified.** Omitting all three is the most common failure — the binary exits 3 with usage.
4649

4750
### Mode 1 — `a2ui` (recommended) · declarative UI
4851

@@ -60,9 +63,38 @@ Best for OAuth flows, external services, pre-built pages. The page must call `wi
6063
webview-cli --url "https://auth.example.com/oauth" --timeout 120
6164
```
6265

63-
### Mode 3 — `html` · custom HTML via `agent://`
66+
### Mode 3 — `markdown` · review / comment / edit a markdown doc
67+
68+
Best for spec review, PR-description review, draft approval — any flow where the agent produced markdown and the human needs to read, comment on, or edit it. Feed markdown on stdin. Rendered with CommonMark + GFM (tables, fenced code).
69+
70+
Three independent toggles:
6471

65-
Best when you need visual fidelity beyond A2UI (charts, diffs, diagrams). The HTML page uses the same `window.webkit.messageHandlers.complete.postMessage({...})` bridge.
72+
| Flag | Adds |
73+
|------|------|
74+
| (none) | Read-only preview + OK/Cancel. Returns `{"action":"acknowledge"}` |
75+
| `--comments` | Clickable blocks → inline comment sidebar + doc-level comment field. Returns `{comments:[...], doc_comment:"..."}` |
76+
| `--edits` | Preview/Source tabs (`Cmd+/` to toggle). Returns `{edited_text:"...", modified:bool}` |
77+
| `--allow-html` | Opt out of HTML sanitization (default strips `<script>`, `<iframe>`, event handlers, `javascript:` URLs). Use only for trusted content. |
78+
79+
`--comments` and `--edits` compose; turn both on to get all four fields back.
80+
81+
```bash
82+
cat /tmp/spec.md | webview-cli --markdown --comments --title "Review spec v1" --width 900 --height 720 --timeout 540
83+
```
84+
85+
**Comment object shape** (each entry in the `comments` array):
86+
87+
```json
88+
{"source_line_start": 5, "source_line_end": 5, "quoted_text": "...", "body": "..."}
89+
```
90+
91+
Line numbers are 1-indexed against the markdown source.
92+
93+
### Mode 4 — `html` · custom HTML via `agent://`
94+
95+
Best when you need visual fidelity beyond A2UI and markdown (charts, custom diffs, diagrams). The HTML page uses the same `window.webkit.messageHandlers.complete.postMessage({...})` bridge.
96+
97+
**Before reaching for Mode 4, ask whether Mode 3 (markdown) covers the case.** Markdown renders GFM tables, fenced code, links, and lists — enough for ~80% of "show the user some formatted content" needs, with no HTML to author or debug.
6698

6799
**Two separate Bash calls** (don't chain — the `load` command and the webview invocation sequence matters):
68100

@@ -81,28 +113,33 @@ webview-cli --url "agent://host/index.html" --timeout 120 < /tmp/wv-load.json
81113

82114
**The `--url` CLI flag is required** — without it the binary exits with usage. The stdin `load` command populates the in-memory resource map that `agent://host/...` reads from.
83115

84-
Pick Mode 3 over A2UI only when you need charts, syntax-highlighted diffs, images, or custom interactions. If you're writing >200 lines of HTML, consider splitting the work into a proper tool instead.
116+
**Common failure — `NSURLErrorDomain error -1100`**: the resource key in the `load` command doesn't match the path in `--url`. If you use `--url "agent://host/index.html"`, the `resources` map must contain the key `"index.html"` (exact match, no leading slash). When this persistently fails, fall back to Mode 3 — pipe the rendered content as markdown instead of hand-rolling HTML.
117+
118+
Pick Mode 4 over Mode 3 only when you need charts, syntax-highlighted diffs, images, or custom interactions. If you're writing >200 lines of HTML, consider splitting the work into a proper tool instead.
85119

86120
## A2UI catalog (Mode 1)
87121

88-
All 11 components in the built-in renderer:
122+
All 12 components in the built-in renderer:
89123

90124
| Component | Purpose | Key props |
91125
|-----------|---------|-----------|
92126
| `Column` | Vertical stack | `children.explicitList` (array of IDs) |
93127
| `Row` | Horizontal arrangement | `children.explicitList`, `alignment` ("center" \| "end" \| "space-between") |
94128
| `Card` | Visual grouping with padding | `child` (single ID) or `children.explicitList` |
95-
| `Text` | Typography | `text.literalString`, `usageHint` ("h1" \| "h2" \| "h3" \| "subtitle" \| "body" \| "caption") |
129+
| `Text` | Typography (plain text only — no markdown parsing) | `text.literalString`, `usageHint` ("h1" \| "h2" \| "h3" \| "subtitle" \| "body" \| "caption") |
96130
| `TextInput` | Single-line or multiline input | `label.literalString`, `placeholder.literalString`, `fieldName`, `multiline` (bool) |
97131
| `Select` | Dropdown | `label.literalString`, `fieldName`, `options` (array of `{value, label}` or strings) |
98132
| `Checkbox` | Single checkbox | `label.literalString`, `fieldName`, `checked` (bool, default false) |
99133
| `RadioGroup` | Mutually-exclusive set | `label.literalString`, `fieldName`, `options` (array of `{value, label}` or strings) |
100134
| `Image` | Inline image | `url` (literal or data ref), optional `alt`, `width`, `height` |
101135
| `Button` | Action button | `label.literalString`, `variant` ("primary" \| "secondary" \| "danger" \| "success"), `action.name`, optional `action.context` |
102136
| `Divider` | Horizontal rule ||
137+
| `MarkdownDoc` | Rendered markdown inside an A2UI form (CommonMark + GFM) | `fieldName` (required), `text` (required markdown source), `allowComments` (bool), `allowEdits` (bool), `allowHtml` (bool), `title` (string) |
103138

104139
**Form data collection**: every component with `fieldName` is collected when a Button is clicked. The response `data` contains `{fieldName: value, ...}` plus the button's `action.name` (and `action.context` if set).
105140

141+
**`MarkdownDoc` vs `--markdown` mode**: use `MarkdownDoc` when the markdown review is one part of a larger form (e.g. spec review + "approve/reject" radio + notes field). Use `--markdown` mode (Mode 3) when the window is *only* about the markdown doc — simpler invocation, no JSONL to generate.
142+
106143
## Response format reference
107144

108145
Canonical stdout shape on successful completion (exit 0):
@@ -166,7 +203,11 @@ For anything beyond trivial substitution, **write the JSONL in a Python generato
166203
## Workflow: when asked to show UI
167204

168205
1. **Run preflight** (above). If it fails, fall back to terminal Q&A with a one-line note.
169-
2. **Pick the mode**: A2UI (forms/approvals/selection — 90% of cases), URL (existing page), HTML (rich visuals only).
206+
2. **Pick the mode**:
207+
- A2UI (forms/approvals/selection) — most common
208+
- `--markdown` — reviewing a spec / PR description / draft; simpler than A2UI when the window is only about the doc
209+
- URL — existing page (OAuth, external service)
210+
- HTML via `agent://` — last resort for rich visuals that neither A2UI nor markdown can render
170211
3. **Window size**: small forms 520×460, mid-size 620×580, full content 720×700. Tight height prevents dead space at the bottom.
171212
4. **Pick a `--timeout`**:
172213
- 120s — simple approval (user is present)

skill/references/templates.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,61 @@ or
105105

106106
(`data.data` is empty because this template has no `fieldName` inputs — it's an acknowledgement-only flow.)
107107

108+
## 5. Markdown document review (`--markdown` mode)
109+
110+
Use for: spec review, PR description review, draft approval, any flow where the agent produced markdown and the human needs to read / comment on / edit it.
111+
112+
This is **not** A2UI JSONL — it's a separate mode. Pipe raw markdown on stdin.
113+
114+
```bash
115+
cat /tmp/spec.md | webview-cli --markdown --comments --edits \
116+
--title "Review: PORTAL-169 bulk-link SQL" \
117+
--width 900 --height 720 --timeout 540
118+
```
119+
120+
**Flag matrix** (comments and edits compose):
121+
122+
| Flags | Window shows | Submit returns |
123+
|-------|--------------|----------------|
124+
| (neither) | Read-only preview + OK/Cancel | `{"action":"acknowledge"}` |
125+
| `--comments` | Preview + clickable blocks + comment sidebar + doc-level field | `{comments:[...], doc_comment:"..."}` |
126+
| `--edits` | Tabbed Preview/Source (`Cmd+/` toggles) | `{edited_text:"...", modified:bool}` |
127+
| `--comments --edits` | Both sidebars + tabs | all four fields |
128+
129+
**Response shape (comments + edits):**
130+
131+
```json
132+
{
133+
"status": "completed",
134+
"data": {
135+
"action": "submit",
136+
"data": {
137+
"comments": [
138+
{"source_line_start": 5, "source_line_end": 5, "quoted_text": "Phase 1: canary deploy.", "body": "Clarify the ramp rate."}
139+
],
140+
"doc_comment": "Looks good overall.",
141+
"edited_text": "# Updated spec\n\n...",
142+
"modified": true
143+
}
144+
}
145+
}
146+
```
147+
148+
**Notes:**
149+
- `source_line_start` / `source_line_end` are 1-indexed against the submitted markdown source
150+
- `comments` is always an empty array `[]` (not absent) when `--comments` is on and the user added none
151+
- `doc_comment` is `""` (not absent) when left blank
152+
- `modified` is `true` iff the source tab differs from the input
153+
- Keyboard shortcuts: `Cmd+Enter` submit, `Esc`/`Cmd+W` cancel, `Cmd+/` toggle Preview/Source
154+
- HTML in the markdown is sanitized by default. Pass `--allow-html` for trusted content only
155+
108156
## Template variables guide
109157

110158
When substituting into templates:
111159

112160
- **Titles**: 3-6 words, imperative or declarative. "Deploy Approval Required", "Choose a Base Branch".
113161
- **Subtitles**: one sentence, ~10-15 words, give context.
114-
- **Descriptions**: can be multi-paragraph but no markdown — plain text only (the renderer doesn't parse markdown).
162+
- **Descriptions**: in a `Text` component, plain text only — `Text` does not parse markdown. If you need rendered markdown (headings, lists, code blocks, tables, links), use the `MarkdownDoc` component inside your A2UI form, or switch the whole window to `--markdown` mode.
115163
- **Button labels**: 1-2 words, action verb. "Approve" > "Yes, I approve".
116164
- **Field names**: snake_case identifiers. These become JSON keys in the response.
117165
- **Field labels**: human-readable, Title Case.

0 commit comments

Comments
 (0)