@markdstage/markdstage 3.3.0 → 3.8.0

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/README.md CHANGED
@@ -16,8 +16,8 @@ exported PDF, or hybrid editable PowerPoint deck.
16
16
  ## Install
17
17
 
18
18
  ```console
19
- npx @markdstage/markdstage present slides.md
20
- npx @markdstage/markdstage preview slides.md
19
+ npx @markdstage/markdstage
20
+ npx @markdstage/markdstage slides.md
21
21
  npm install --global @markdstage/markdstage
22
22
  ```
23
23
 
@@ -31,6 +31,8 @@ npm install --global .\markdstage-markdstage-<version>.tgz
31
31
  ## Commands
32
32
 
33
33
  ```console
34
+ markdstage
35
+ markdstage slides.md
34
36
  markdstage present slides.md
35
37
  markdstage preview slides.md --watch
36
38
  markdstage validate slides.md --json
@@ -38,36 +40,46 @@ markdstage inspect slides.md --json
38
40
  markdstage capture slides.md --pages 2,4
39
41
  markdstage export slides.md --output slides.pdf
40
42
  markdstage export slides.md --output slides.pptx
43
+ markdstage export slides.md --output slides.pptx --mermaid-image-fallback
41
44
  markdstage guide architecture-dsl
42
45
  markdstage skill install --target codex
43
46
  markdstage skill install --target claude
44
47
  ```
45
48
 
49
+ `markdstage` opens an empty Canvas-equivalent UI for the current workspace.
50
+ Choose **Open Markdown** to load a deck. `markdstage slides.md` opens the same UI
51
+ in slide view with automatic refresh enabled.
52
+
46
53
  | Command | Description |
47
54
  | --- | --- |
48
- | `present` | Opens the presenter view with the current slide, next-slide preview, speaker notes, and navigation. Select **Start presentation** to open the synchronized audience-facing window; select **End presentation** to close it. `--watch` reloads on save, and `--no-open` serves the presenter URL without launching a browser. |
49
- | `preview` | Serves the deck on loopback and opens the MarkdStage preview: navigation, presenter view, next-slide preview, speaker notes, overview, custom themes, Mermaid, Architecture DSL, and local assets. `--watch` reloads on save while preserving the current slide, keeps the last valid deck when a save is broken, and enables Architecture editing. Without `--watch`, the source is read-only. `--no-open` serves the deck only. |
55
+ | `present` | Opens the full MarkdStage UI in presenter view. Open Markdown, automatic refresh, editing, export, and audience controls remain available. `--watch` starts in live mode, and `--no-open` serves the UI without launching a browser. |
56
+ | `preview` | Opens the same full UI in slide view. It is a compatibility/convenience entry point; `--watch` starts in live mode, and `--no-open` serves the UI without launching a browser. |
50
57
  | `validate` | Checks deck structure, Architecture DSL blocks, themes, and theme paths. |
51
58
  | `inspect` | Reports the same compact 1280x720 clipping diagnostics as the canvas `inspect_layout` action. `--slide <n>` limits it to one page, `--all` includes slides that fit, `--fail-on-issues` exits with code 5. |
52
59
  | `capture` | Writes 1280x720 PNG files. Without `--pages` only the slides reported as clipped are captured. |
53
- | `export` | Produces the same 16:9 PDF or hybrid editable PowerPoint as the canvas Extension. PowerPoint output includes speaker-note Markdown as readable plain text notes. The `--output` extension selects the format; PDF remains the default. |
60
+ | `export` | Produces the same 16:9 PDF or hybrid editable PowerPoint as the canvas Extension. PowerPoint output includes speaker-note Markdown as readable plain text notes. The `--output` extension selects the format; PDF remains the default. Use `--mermaid-image-fallback` with an explicit `.pptx` output to place each Mermaid diagram as one image instead of editable PowerPoint shapes, equivalent to choosing **Images** in the UI export dialog. |
54
61
  | `guide` | Prints the canonical `markdstage_guide` topics. |
55
62
  | `skill` | Installs or checks the portable Agent Skills for Codex (`.agents/skills/markdstage/`), Claude Code (`.claude/skills/markdstage/`), and GitHub Copilot (`.github/skills/markdstage/`). Locally modified files are never overwritten without `--force`. |
56
63
  | `help` | Shows the overview, or the help for one command. `markdstage help <command>` prints the same text as `markdstage <command> --help`. |
57
64
 
58
- Global options: `--workspace <dir>`, `--theme <name>`, `--theme-file <path>`,
59
- `--json`, `--help`, `--version`.
65
+ Application options: `--workspace <dir>`, `--theme <name>`,
66
+ `--theme-file <path>`, `--no-open`, and `--json`. Use `--help` and `--version`
67
+ for global information.
60
68
 
61
69
  ## Architecture editing
62
70
 
63
- Run `markdstage preview slides.md --watch` for the live authoring workflow. The
64
- browser starts in viewing mode. Select the pencil control to move Architecture
65
- elements; those placement changes are saved atomically to the matching
66
- `architecture` fence. Select **Advanced edit** to add, update, duplicate,
67
- reparent, or delete elements in the detailed designer, then select **Save**.
71
+ Run `markdstage slides.md` for the live authoring workflow. The browser starts
72
+ in the fixed 16:9 output preview and remains in viewing mode.
73
+ Select **Output preview** to switch to the retained responsive layout. Select
74
+ the pencil control to move Architecture elements; editing automatically switches
75
+ to the responsive layout, and those placement changes are saved atomically to
76
+ the matching `architecture` fence. Select **Advanced edit** to add, update,
77
+ duplicate, reparent, or delete elements in the detailed designer, then select
78
+ **Save**.
68
79
 
69
80
  The server rejects a save if the Markdown changed outside the editor. Successful
70
- saves reload the watched deck without changing the current slide. Presenter,
81
+ saves reload the watched deck without changing the current slide. Automatic
82
+ refresh can be toggled without disabling Architecture editing. Presenter,
71
83
  capture, inspect, and export views contain no editing UI.
72
84
 
73
85
  ```console
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdstage/markdstage",
3
- "version": "3.3.0",
3
+ "version": "3.8.0",
4
4
  "description": "Present, validate, inspect, capture, and export MarkdStage Markdown decks from the command line — no Copilot canvas required.",
5
5
  "license": "MIT",
6
6
  "author": "runceel",
package/shared/README.md CHANGED
@@ -60,8 +60,9 @@ The themed slide is displayed and updates automatically
60
60
  Theme-file lookup tries the source Markdown folder before the repository
61
61
  root, allowing a deck-local file to override a shared file with the same
62
62
  path. Files outside the workspace and arbitrary selectors are rejected.
63
- A sibling `theme.json` may define cover background, cover/back-cover logos,
64
- and copyright. **Every theme automatically receives a final
63
+ A sibling `theme.json` may define common and default/center backgrounds, cover
64
+ background, cover/back-cover logos, and copyright. Per-slide `background-image`
65
+ overrides all themes and layouts. **Every theme automatically receives a final
65
66
  `layout: backcover` slide** unless one already exists. Logo and copyright
66
67
  appear only when supplied by metadata or front matter.
67
68
  - See [`docs/custom-theme-authoring.md`](docs/custom-theme-authoring.md) for
@@ -108,6 +109,11 @@ The themed slide is displayed and updates automatically
108
109
  notes are converted from Markdown to readable plain text in the corresponding
109
110
  PowerPoint notes pane. AI may call `export_pptx` with another
110
111
  workspace-confined `.pptx` path.
112
+ - **PowerPoint export offers Mermaid output options when the deck contains diagrams.**
113
+ Choose **Editable shapes** or **Images** in the export dialog, then **Export**.
114
+ Each opening defaults to editable shapes. **Cancel** or **Esc** closes without
115
+ exporting; decks without Mermaid export immediately. This choice is not saved
116
+ in the deck. The CLI equivalent is `--mermaid-image-fallback` for image output.
111
117
  - **Both export buttons show a visible notification outside More controls.**
112
118
  Progress remains visible while saving, and both buttons are disabled until
113
119
  the operation finishes. Export buttons return to their normal appearance and
@@ -118,12 +124,13 @@ The themed slide is displayed and updates automatically
118
124
  dismissed or another export starts. Success and error notifications also have
119
125
  a dismiss button and are announced to screen readers. Notifications never
120
126
  appear in exported files or the external presentation window.
121
- - Use **More controls > Output preview** to letterbox the current slide inside
122
- the canvas with
123
- the same fixed 1280×720 typography, spacing, diagram limits, and clipping used
124
- by PDF output. This preview is local to the canvas and does not change deck
125
- state. A visible and accessible warning identifies content that would be
126
- clipped.
127
+ - The canvas starts in **More controls > Output preview**, letterboxing the
128
+ current slide with the same fixed 1280×720 typography, spacing, diagram
129
+ limits, and clipping used by PDF output. Select **Output preview** to return
130
+ to the retained responsive canvas layout. This preview is local to the canvas
131
+ and does not change deck state. A visible and accessible warning identifies
132
+ content that would be clipped. Entering lightweight Architecture editing also
133
+ returns to the responsive layout so its placement controls remain available.
127
134
  - AI should call **`inspect_layout` before exporting a non-scrolling deck**. It
128
135
  renders the currently registered in-memory output snapshot in headless
129
136
  Chromium; it does not read or validate the source file named by `sourceName`.
@@ -181,7 +188,8 @@ slides remains the AI's responsibility.
181
188
  - **Initial front matter is deck configuration** inherited by all slides
182
189
  (`theme`, `theme-file`, `deck`, `kicker`, `size`, `logo`, `copyright`, and
183
190
  related keys). It is also slide one's own front matter, so
184
- `layout: title` affects slide one only.
191
+ `layout: title` affects slide one only. `background-image` is also per-slide
192
+ and is never inherited by later slides.
185
193
  - **Each page may have front matter.** When the block after the separator
186
194
  contains only `key: value` entries and is closed by `---`, it is treated as
187
195
  that page's front matter; the separator line also opens the block.
@@ -294,6 +302,7 @@ delimited by `---`, followed by GFM-compatible content.
294
302
  | `size` | `auto` (default), `normal`, `large`, or `xlarge` |
295
303
  | `theme` | Per-slide override; normally use the deck theme |
296
304
  | `theme-file` | CSS for `custom`, resolved beside the Markdown before workspace root |
305
+ | `background-image` | Per-slide decorative image, e.g. `/assets/background.png`; overrides every layout and theme |
297
306
  | `logo` / `copyright` | Override `backcover` metadata |
298
307
 
299
308
  Make the first slide a `layout: title` cover. The extension appends a final
@@ -342,7 +351,8 @@ total: 8
342
351
 
343
352
  For an intermediate chapter divider, use `layout: section`, normally with one
344
353
  H1/H2. Add `kicker` or footer data only when needed. The background follows the
345
- theme and contains no image, logo, or icon.
354
+ theme and contains no image, logo, or icon unless a per-slide `background-image`
355
+ is supplied.
346
356
 
347
357
  ```markdown
348
358
  ---
@@ -352,6 +362,23 @@ layout: section
352
362
  ## Key GitHub Copilot features
353
363
  ```
354
364
 
365
+ Use `background-image: /assets/background.png` (or the `assets/background.png`
366
+ alias without the leading slash) in a slide's front matter to
367
+ override its background, including `title`, `section`, and `backcover`, under
368
+ `dark`, `light`, `microsoft`, or `custom`. It applies only to that slide, even
369
+ when specified in the initial file front matter. Lookup tries `assets/` beside
370
+ the Markdown, then workspace-root `assets/`; without `sourceName`, it uses the
371
+ workspace root. Accepted extensions are `.svg`, `.png`, `.webp`, `.jpg`, and
372
+ `.jpeg`, at most 2 MiB per image. Remote and `data:` URLs are rejected.
373
+
374
+ Images are centered and cropped to fill the slide (`object-fit: cover`) behind
375
+ content and logos, preserving the existing background underneath. A custom
376
+ theme uses `layouts.default.background` or `layouts.center.background` before
377
+ its common root `background`; that common fallback applies to default/center
378
+ only. Without a per-slide override, `title` still uses `cover.background` and
379
+ section/back-cover colors and logos are unchanged. Only absent settings trigger
380
+ fallback: invalid paths, missing files, and oversized images fail explicitly.
381
+
355
382
  ### `sourceName` role
356
383
 
357
384
  `sourceName` is workspace-relative metadata used to resolve adjacent themes and
@@ -382,6 +409,16 @@ workspace-relative source path as `sourceName`.
382
409
  | `microsoft` | Microsoft, Fluent, Office, or the Microsoft four-color style |
383
410
  | `custom` | Reproduce brand colors or an organizational template with CSS custom properties |
384
411
 
412
+ Custom `theme.json` may specify a common `background` and individual
413
+ `layouts.default.background` / `layouts.center.background` entries, each using
414
+ `{ "image": "assets/background.png", "alt": "Optional description" }`.
415
+ These theme-local images use the existing safe `assets/` grammar and 2 MiB
416
+ limit. For default/center, precedence is per-slide `background-image`, then
417
+ layout image, then common image, then the existing background. Common images
418
+ never replace `cover.background` on title slides or section/back-cover
419
+ backgrounds. Per-slide overrides work across all layouts and built-in themes.
420
+ See [Custom theme authoring](docs/custom-theme-authoring.md) for the full contract.
421
+
385
422
  ## Architecture DSL v1
386
423
 
387
424
  An `architecture` code fence renders a position-stable JSON DSL as SVG. Canvas
@@ -107,11 +107,8 @@ body[data-inspector-open="false"] .inspector-panel{display:none;}
107
107
  .tree-item[aria-selected="true"] .tree-icon{color:inherit;}
108
108
  .tree-icon{width:18px;text-align:center;color:var(--editor-muted);}
109
109
  .tree-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
110
- .editor-viewport{position:relative;min-width:0;min-height:0;overflow:auto;cursor:grab;
111
- background-color:#101217;
112
- background-image:linear-gradient(var(--editor-grid) 1px,transparent 1px),
113
- linear-gradient(90deg,var(--editor-grid) 1px,transparent 1px);
114
- background-size:20px 20px;}
110
+ .editor-viewport{position:relative;min-width:0;min-height:0;overflow:auto;cursor:default;
111
+ background-color:#101217;touch-action:none;}
115
112
  :root[data-theme="light"] .editor-viewport,:root[data-theme="microsoft"] .editor-viewport{
116
113
  background-color:#e9edf3;}
117
114
  .canvas-surface{display:flex;align-items:flex-start;justify-content:center;width:max-content;min-width:100%;min-height:100%;
@@ -130,6 +127,13 @@ body[data-inspector-open="false"] .inspector-panel{display:none;}
130
127
  .canvas-surface [data-editor-ref]{cursor:pointer;outline:none;}
131
128
  .canvas-surface [data-editor-ref][data-editor-movable="true"]{cursor:grab;}
132
129
  .editor-viewport.is-panning{cursor:grabbing;user-select:none;}
130
+ .editor-viewport.is-panning [data-editor-ref]{cursor:grabbing;}
131
+ .editor-viewport.is-selecting{cursor:crosshair;user-select:none;}
132
+ .editor-grid,.editor-marquee{pointer-events:none;}
133
+ .editor-marquee{fill:var(--editor-accent);fill-opacity:.18;stroke:var(--editor-accent);stroke-width:1;
134
+ vector-effect:non-scaling-stroke;}
135
+ .visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;
136
+ clip-path:inset(50%);white-space:nowrap;}
133
137
  .editor-viewport.is-dragging [data-editor-ref]{pointer-events:none;}
134
138
  .canvas-surface [data-editor-ref],.canvas-surface .editor-resize-handle{will-change:transform;}
135
139
  .canvas-surface .editor-drag-target{filter:drop-shadow(0 12px 16px rgba(0,0,0,.28));opacity:.92;}