@markdstage/markdstage 2.5.0 → 2.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdstage/markdstage",
3
- "version": "2.5.0",
3
+ "version": "2.6.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
@@ -78,11 +78,12 @@ The themed slide is displayed and updates automatically
78
78
  presenter, and PDF output.
79
79
  - The **canvas renderer** owns the compact navigation controls, shape editing,
80
80
  the slide list, and current position. **More controls > Shape editing**
81
- toggles the same placement mode as `edit_architecture`. For Markdown loaded
82
- with **More controls > Open Markdown**, **Advanced editing** opens
83
- the dedicated `architecture-editor` canvas. The agent only opens the deck and
84
- does not run an `ask_user` loop. Margin clicks are installed only in normal
85
- canvas and presenter modes, never print mode. `goto_slide` remains available
81
+ opens the dedicated `architecture-editor` canvas directly for Markdown loaded
82
+ with **More controls > Open Markdown**; slides with multiple diagrams first
83
+ show a diagram picker. Decks without a source association retain the
84
+ lightweight placement mode. The agent only opens the deck and does not run an
85
+ `ask_user` loop. Margin clicks are installed only in normal canvas and
86
+ presenter modes, never print mode. `goto_slide` remains available
86
87
  for an explicit page request from chat.
87
88
  - **PDF Export is available from More controls > Export PDF.** When
88
89
  `sourceName` is passed
@@ -374,7 +375,9 @@ When writing explicit JSON, `elements` is required by the JSON Schema.
374
375
  ````
375
376
 
376
377
  - A `node` has a unique `id`, multiline `text`, and shape `rect`,
377
- `rounded-rect`, or `ellipse`.
378
+ `rounded-rect`, `ellipse`, `diamond`, `triangle`, `hexagon`, or
379
+ `parallelogram`. These additive shape values remain Architecture DSL v1 and
380
+ export as native PowerPoint shapes.
378
381
  - `icon` is a built-in name or a path under an adjacent or workspace-root
379
382
  `assets/` folder. See [Icons](#icons).
380
383
  - An `image` places an `assets/` image as an independent element. `fit` is
@@ -407,7 +410,9 @@ When writing explicit JSON, `elements` is required by the JSON Schema.
407
410
  `opacity`, `dash`, and `cornerRadius`. Prefer theme tokens `accent`,
408
411
  `accentStrong`, `accentSoft`, `accentLine`, `surface`, `fg`, `muted`, `body`,
409
412
  `border`, and `bg`. Literal colors are limited to hex, white, black, and
410
- transparent.
413
+ transparent. Omit `dash` (or use an empty value) for a solid line, use
414
+ `"dash": "1 5"` for a dotted line, or provide another space-separated numeric
415
+ pattern such as `"10 6"` for dashed/custom output.
411
416
  - Invalid JSON, out-of-range numbers, duplicate IDs, unknown references, and
412
417
  unsupported elements, styles, or colors render an inline diagram error while
413
418
  preserving other slide content. DSL values never generate HTML, script, or
@@ -760,8 +765,8 @@ Enter mode with:
760
765
 
761
766
  | Method | Purpose |
762
767
  | --- | --- |
763
- | Canvas action `edit_architecture` with `{ "enabled": true }` | Normal agent-controlled operation |
764
- | Pencil control during CLI `present --watch` | User-controlled live authoring; the browser starts with editing off |
768
+ | Canvas action `edit_architecture` with `{ "enabled": true }` | Agent-controlled lightweight placement operation |
769
+ | **Shape editing** for a deck without a source association | User-controlled lightweight placement operation |
765
770
  | Renderer URL `?architectureEdit=1` | Local debugging |
766
771
 
767
772
  `reset` disables editing. The query parameter also updates server state through
@@ -777,7 +782,6 @@ from disabling a client-only mode or `POST /edit` returning an unexpected 409.
777
782
  | Undo | Toolbar **Undo** | Ctrl+Z |
778
783
  | Redo | Toolbar **Redo** | Ctrl+Shift+Z / Ctrl+Y |
779
784
  | Clear selection | Click outside the diagram | Escape |
780
- | Full editing | Toolbar **Advanced editing** | — |
781
785
 
782
786
  Every move redraws the complete diagram and reroutes connectors. A live status
783
787
  region announces results.
@@ -791,8 +795,21 @@ blocks.
791
795
 
792
796
  - Add, delete, duplicate, reorder, and reparent nodes, groups, images, and
793
797
  connectors.
794
- - Drag, resize, snap to grid, zoom, and pan. Scroll horizontally/vertically
795
- when the diagram exceeds the workspace, or pan with middle-drag / Space-drag.
798
+ - Add nodes from a bounded shape palette containing rectangles, ellipses,
799
+ diamonds, triangles, hexagons, and parallelograms.
800
+ - The primary toolbar keeps Undo, Redo, Shape, Save, and More visible. Secondary
801
+ add, edit, ordering, view, grid, and reload commands are grouped under
802
+ **More**.
803
+ - Drag and resize with live feedback, snap to grid, zoom, and pan. Drag blank
804
+ canvas space with the primary button to pan horizontally and vertically;
805
+ middle-drag and Space-drag remain available.
806
+ - **Elements** and **Properties** are collapsible. Medium windows use nonmodal
807
+ docks so the canvas remains selectable; narrow windows use lightweight
808
+ overlays without a blocking backdrop. Opening a panel moves keyboard focus
809
+ to its content, and each panel has a local close control.
810
+ - Empty Architecture blocks show a focused **Add first shape** action. Toolbar
811
+ additions start near the visible canvas center and move to an unoccupied
812
+ sibling position when necessary.
796
813
  - Context menus on elements, empty space, and tree items provide appropriate
797
814
  add, connect, duplicate, delete, front/back order, Undo/Redo, and Save
798
815
  commands. Group **Layout** menus offer `none`, `row`, `column`, `grid`, and
@@ -804,7 +821,7 @@ blocks.
804
821
  return with `ArrowLeft`, execute with Enter/Space, and close with Escape.
805
822
  - A typed inspector edits geometry, layout, style, icon, ports, routing,
806
823
  polyline points, canvas metadata, and other editable v1 fields.
807
- - Add a standalone **Image** from the toolbar or context menu. Node inspector
824
+ - Add a standalone **Image** from **More** or a context menu. Node inspector
808
825
  **Select image from assets/** uses the same picker. It searches
809
826
  Markdown-adjacent and workspace-root `assets/` in that order. Import SVG,
810
827
  PNG, WebP, JPG, or JPEG up to 10 MB into workspace-root `assets/`; collisions
@@ -817,8 +834,11 @@ blocks.
817
834
  - Saving reloads any MarkdStage canvas or watched CLI presentation showing the
818
835
  same Markdown while preserving the current page and theme.
819
836
 
820
- Source-backed decks imported through **More controls > Open Markdown** and CLI `present --watch` enable
821
- **Advanced editing**. Agents can open the editor canvas directly:
837
+ For a source-backed deck imported through **More controls > Open Markdown**,
838
+ **Shape editing** opens this editor directly. If the slide contains multiple
839
+ Architecture blocks, select one from the accessible picker first. CLI
840
+ `present --watch` opens the same editor in a browser window. Agents can open
841
+ the editor canvas directly:
822
842
 
823
843
  ```json
824
844
  {
@@ -7,6 +7,8 @@
7
7
  --editor-muted:#a8b0bd;
8
8
  --editor-accent:#67a7ff;
9
9
  --editor-accent-soft:#17365d;
10
+ --editor-brand:#ffb547;
11
+ --editor-brand-soft:#4a3519;
10
12
  --editor-danger:#ff8f8f;
11
13
  --editor-grid:rgba(255,255,255,.07);
12
14
  }
@@ -19,6 +21,8 @@
19
21
  --editor-muted:#606775;
20
22
  --editor-accent:#0f6cbd;
21
23
  --editor-accent-soft:#dcecff;
24
+ --editor-brand:#8a4f00;
25
+ --editor-brand-soft:#fff0d5;
22
26
  --editor-danger:#b3261e;
23
27
  --editor-grid:rgba(0,0,0,.08);
24
28
  }
@@ -27,34 +31,83 @@ html,body{height:100%;margin:0;overflow:hidden;}
27
31
  body{display:grid;grid-template-rows:auto minmax(0,1fr) auto;
28
32
  color:var(--editor-fg);background:var(--editor-panel);font:14px/1.4 "Segoe UI",sans-serif;}
29
33
  button,input,select,textarea{font:inherit;}
30
- button{min-height:30px;padding:4px 9px;border:1px solid var(--editor-border);
34
+ button{min-height:34px;padding:5px 10px;border:1px solid var(--editor-border);
31
35
  border-radius:6px;color:var(--editor-fg);background:var(--editor-panel-2);cursor:pointer;}
32
36
  button:hover:not(:disabled){border-color:var(--editor-accent);background:var(--editor-accent-soft);}
33
37
  button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
34
38
  outline:2px solid var(--editor-accent);outline-offset:1px;}
35
39
  button:disabled{opacity:.42;cursor:default;}
36
- .editor-header{display:flex;align-items:center;gap:16px;padding:8px 12px;
40
+ .editor-header{position:relative;z-index:4;display:flex;align-items:center;gap:16px;padding:8px 12px;
37
41
  border-bottom:1px solid var(--editor-border);background:var(--editor-panel-2);}
38
42
  .editor-title{display:flex;align-items:center;gap:8px;min-width:230px;white-space:nowrap;}
43
+ .editor-title strong{font-size:15px;letter-spacing:-.01em;}
39
44
  .editor-title #sourceLabel{max-width:28vw;overflow:hidden;text-overflow:ellipsis;color:var(--editor-muted);}
40
- .dirty-badge{padding:2px 7px;border-radius:999px;color:#fff;background:#b26a00;font-size:12px;}
41
- .editor-actions{display:flex;align-items:center;gap:6px;min-width:0;overflow-x:auto;padding-bottom:2px;}
45
+ .dirty-badge{padding:2px 7px;border-radius:999px;color:#fff;background:#8a4f00;
46
+ font-size:12px;font-weight:600;}
47
+ .editor-panel-actions{display:flex;align-items:center;gap:6px;margin-left:auto;}
48
+ .editor-panel-actions button[aria-expanded="true"]{border-color:var(--editor-accent);background:var(--editor-accent-soft);}
49
+ .editor-actions{display:flex;align-items:center;gap:6px;min-width:0;}
42
50
  .toolbar-separator{width:1px;height:24px;background:var(--editor-border);flex:0 0 auto;}
43
- .save-button{font-weight:700;color:#fff;background:#0f6cbd;border-color:#0f6cbd;}
51
+ .shape-palette-host{position:relative;}
52
+ .shape-palette{position:fixed;z-index:30;display:grid;grid-template-columns:repeat(2,minmax(118px,1fr));
53
+ gap:6px;width:min(288px,calc(100vw - 24px));max-height:min(360px,calc(100vh - 24px));
54
+ padding:8px;overflow:auto;border:1px solid var(--editor-border);border-radius:12px;
55
+ background:var(--editor-panel-2);box-shadow:0 18px 45px rgba(0,0,0,.32);}
56
+ .shape-palette[hidden]{display:none;}
57
+ .shape-palette button{display:grid;grid-template-columns:32px minmax(0,1fr);align-items:center;
58
+ gap:8px;min-height:44px;padding:6px 8px;text-align:left;}
59
+ .shape-swatch{width:24px;height:20px;justify-self:center;border:2px solid currentColor;
60
+ background:color-mix(in srgb,var(--editor-accent) 18%,transparent);}
61
+ .shape-swatch[data-shape="rounded-rect"]{border-radius:7px;}
62
+ .shape-swatch[data-shape="ellipse"]{border-radius:50%;}
63
+ .shape-swatch[data-shape="diamond"]{width:18px;height:18px;transform:rotate(45deg);}
64
+ .shape-swatch[data-shape="triangle"]{border:0;clip-path:polygon(50% 0,100% 100%,0 100%);background:currentColor;}
65
+ .shape-swatch[data-shape="hexagon"]{border:0;clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%);
66
+ background:currentColor;}
67
+ .shape-swatch[data-shape="parallelogram"]{border:0;clip-path:polygon(18% 0,100% 0,82% 100%,0 100%);
68
+ background:currentColor;}
69
+ .save-button{font-weight:700;color:#17120a;background:var(--editor-brand);border-color:var(--editor-brand);}
70
+ .save-button:hover:not(:disabled){color:#17120a;background:color-mix(in srgb,var(--editor-brand) 86%,white);
71
+ border-color:color-mix(in srgb,var(--editor-brand) 86%,white);}
44
72
  .snap-toggle{display:flex;align-items:center;gap:4px;white-space:nowrap;color:var(--editor-muted);}
45
- .editor-layout{display:grid;grid-template-columns:230px minmax(0,1fr) 300px;min-height:0;}
46
- .editor-sidebar{min-height:0;overflow:auto;background:var(--editor-panel-2);}
47
- .editor-sidebar h2{position:sticky;top:0;z-index:2;margin:0;padding:10px 12px;
48
- border-bottom:1px solid var(--editor-border);background:var(--editor-panel-2);font-size:13px;}
73
+ .toolbar-more-host{position:relative;}
74
+ .toolbar-more-menu{position:fixed;z-index:35;display:grid;grid-template-columns:repeat(2,minmax(132px,1fr));
75
+ gap:10px;width:min(320px,calc(100vw - 16px));max-height:min(520px,calc(100vh - 16px));
76
+ padding:10px;overflow:auto;border:1px solid var(--editor-border);border-radius:10px;
77
+ background:var(--editor-panel-2);box-shadow:0 16px 34px rgba(0,0,0,.38);}
78
+ .toolbar-more-menu[hidden]{display:none;}
79
+ .toolbar-more-group{display:flex;flex-direction:column;gap:5px;min-width:0;}
80
+ .toolbar-more-label{padding:2px 4px;color:var(--editor-muted);font-size:11px;font-weight:700;
81
+ letter-spacing:.08em;text-transform:uppercase;}
82
+ .toolbar-more-menu button{width:100%;text-align:left;}
83
+ .toolbar-more-row{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;}
84
+ .toolbar-more-row button{text-align:center;}
85
+ .toolbar-more-menu>.snap-toggle{min-height:34px;padding:5px 8px;border-radius:6px;background:var(--editor-panel);}
86
+ .toolbar-more-menu>button:last-child{grid-column:1/-1;}
87
+ .editor-layout{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr);
88
+ min-height:0;overflow:hidden;}
89
+ body[data-elements-open="true"] .editor-layout{grid-template-columns:210px minmax(0,1fr);}
90
+ body[data-inspector-open="true"] .editor-layout{grid-template-columns:minmax(0,1fr) 300px;}
91
+ body[data-elements-open="true"][data-inspector-open="true"] .editor-layout{
92
+ grid-template-columns:210px minmax(0,1fr) 300px;}
93
+ .editor-sidebar{display:flex;flex-direction:column;min-height:0;overflow:auto;background:var(--editor-panel-2);}
94
+ body[data-elements-open="false"] .element-panel,
95
+ body[data-inspector-open="false"] .inspector-panel{display:none;}
96
+ .editor-sidebar-head{position:sticky;top:0;z-index:2;display:flex;align-items:center;
97
+ justify-content:space-between;min-height:42px;padding:4px 6px 4px 12px;
98
+ border-bottom:1px solid var(--editor-border);background:var(--editor-panel-2);}
99
+ .editor-sidebar h2{margin:0;font-size:14px;}
100
+ .editor-panel-close{min-width:34px;padding:0;font-size:18px;line-height:1;}
49
101
  .element-panel{border-right:1px solid var(--editor-border);}
50
102
  .inspector-panel{border-left:1px solid var(--editor-border);}
51
103
  .element-tree{padding:8px 0;}
52
- .tree-item{display:flex;align-items:center;gap:7px;width:100%;min-height:30px;padding:4px 10px;
104
+ .tree-item{display:flex;align-items:center;gap:7px;width:100%;min-height:34px;padding:5px 10px;
53
105
  border:0;border-radius:0;text-align:left;background:transparent;}
54
- .tree-item[aria-selected="true"]{background:var(--editor-accent-soft);color:var(--editor-accent);}
106
+ .tree-item[aria-selected="true"]{background:var(--editor-accent-soft);color:var(--editor-fg);}
107
+ .tree-item[aria-selected="true"] .tree-icon{color:inherit;}
55
108
  .tree-icon{width:18px;text-align:center;color:var(--editor-muted);}
56
109
  .tree-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
57
- .editor-viewport{position:relative;min-width:0;min-height:0;overflow:auto;
110
+ .editor-viewport{position:relative;min-width:0;min-height:0;overflow:auto;cursor:grab;
58
111
  background-color:#101217;
59
112
  background-image:linear-gradient(var(--editor-grid) 1px,transparent 1px),
60
113
  linear-gradient(90deg,var(--editor-grid) 1px,transparent 1px);
@@ -63,20 +116,36 @@ button:disabled{opacity:.42;cursor:default;}
63
116
  background-color:#e9edf3;}
64
117
  .canvas-surface{display:flex;align-items:flex-start;justify-content:center;width:max-content;min-width:100%;min-height:100%;
65
118
  padding:48px;transform-origin:top center;}
119
+ .editor-empty-state{align-self:center;display:grid;justify-items:center;gap:10px;width:min(420px,calc(100vw - 64px));
120
+ margin:auto;padding:36px 32px;text-align:center;color:var(--editor-fg);}
121
+ .editor-empty-state h2{margin:4px 0 0;font-size:24px;letter-spacing:-.025em;}
122
+ .editor-empty-state p{max-width:34ch;margin:0;color:var(--editor-muted);font-size:15px;}
123
+ .editor-empty-state small{color:var(--editor-muted);}
124
+ .empty-state-shape{width:64px;height:48px;border:3px solid var(--editor-accent);border-radius:12px;
125
+ background:var(--editor-accent-soft);box-shadow:8px 8px 0 color-mix(in srgb,var(--editor-brand) 72%,transparent);}
66
126
  .canvas-surface>.architecture-diagram{flex:0 0 auto;width:960px;margin:0;padding:18px;
67
127
  border:1px solid var(--editor-border);border-radius:10px;background:var(--surface);
68
128
  box-shadow:0 12px 36px rgba(0,0,0,.3);}
69
129
  .canvas-surface .architecture-svg{width:100%;max-height:none;overflow:visible;touch-action:none;}
70
130
  .canvas-surface [data-editor-ref]{cursor:pointer;outline:none;}
71
131
  .canvas-surface [data-editor-ref][data-editor-movable="true"]{cursor:grab;}
132
+ .editor-viewport.is-panning{cursor:grabbing;user-select:none;}
133
+ .editor-viewport.is-dragging [data-editor-ref]{pointer-events:none;}
134
+ .canvas-surface [data-editor-ref],.canvas-surface .editor-resize-handle{will-change:transform;}
135
+ .canvas-surface .editor-drag-target{filter:drop-shadow(0 12px 16px rgba(0,0,0,.28));opacity:.92;}
136
+ .canvas-surface .editor-settle{animation:editor-settle 150ms ease-out;transform-box:fill-box;
137
+ transform-origin:center;}
138
+ @keyframes editor-settle{from{opacity:.9;transform:scale(.985);}to{opacity:1;transform:scale(1);}}
72
139
  .canvas-surface [data-editor-selected="true"]>rect,
73
- .canvas-surface [data-editor-selected="true"]>ellipse{
74
- stroke:var(--editor-accent);stroke-width:7;filter:drop-shadow(0 0 7px var(--editor-accent));}
140
+ .canvas-surface [data-editor-selected="true"]>ellipse,
141
+ .canvas-surface [data-editor-selected="true"]>polygon{
142
+ stroke:var(--editor-accent);stroke-width:5;filter:drop-shadow(0 0 4px var(--editor-accent));}
75
143
  .canvas-surface [data-architecture-type="connector"][data-editor-selected="true"] path{
76
- stroke:var(--editor-accent);stroke-width:8;}
144
+ stroke:var(--editor-accent);stroke-width:6;}
77
145
  .editor-resize-handle{fill:var(--surface);stroke:var(--editor-accent);stroke-width:4;cursor:nwse-resize;}
78
146
  .editor-resize-handle[data-corner="ne"],.editor-resize-handle[data-corner="sw"]{cursor:nesw-resize;}
79
- .connector-source>rect,.connector-source>ellipse{stroke:#f9c74f!important;stroke-width:8!important;}
147
+ .connector-source>rect,.connector-source>ellipse,.connector-source>polygon{
148
+ stroke:#f9c74f!important;stroke-width:8!important;}
80
149
  .inspector{display:flex;flex-direction:column;gap:10px;padding:12px;}
81
150
  .inspector-section{display:grid;grid-template-columns:minmax(88px,1fr) minmax(0,1.35fr);
82
151
  gap:7px 10px;padding-bottom:11px;border-bottom:1px solid var(--editor-border);}
@@ -146,10 +215,37 @@ button:disabled{opacity:.42;cursor:default;}
146
215
  .asset-dialog-footer>span{min-width:0;color:var(--editor-muted);font-size:12px;}
147
216
  .asset-dialog-footer>span[data-kind="error"]{color:var(--editor-danger);font-weight:600;}
148
217
  .asset-dialog-footer>div{display:flex;gap:8px;}
149
- @media(max-width:900px){
150
- .editor-layout{grid-template-columns:180px minmax(0,1fr);}
151
- .inspector-panel{position:absolute;right:0;top:52px;bottom:28px;width:280px;z-index:5;
152
- box-shadow:-10px 0 24px rgba(0,0,0,.25);}
218
+ @media(max-width:1100px){
219
+ .editor-header{flex-wrap:wrap;gap:8px 12px;}
220
+ .editor-title{min-width:0;flex:1 1 260px;}
221
+ .editor-title #sourceLabel{max-width:min(48vw,420px);}
222
+ .editor-actions{margin-inline-start:auto;}
153
223
  .asset-dialog-body{grid-template-columns:minmax(0,1fr);}
154
224
  .asset-preview{display:none;}
155
225
  }
226
+ @media(max-width:620px){
227
+ .editor-header{gap:8px;padding:8px;}
228
+ .editor-title{flex-basis:100%;order:1;}
229
+ .editor-title #sourceLabel{max-width:32vw;}
230
+ .editor-panel-actions{order:2;margin:0;}
231
+ .editor-actions{order:3;margin-inline-start:auto;}
232
+ .editor-actions button,.editor-panel-actions button{min-height:40px;padding-inline:10px;}
233
+ .editor-layout{grid-template-columns:minmax(0,1fr)!important;}
234
+ .editor-sidebar{position:absolute;inset-block:0;z-index:12;width:min(340px,88vw);
235
+ visibility:hidden;box-shadow:0 16px 34px rgba(0,0,0,.34);
236
+ transition:transform 160ms ease-out,visibility 160ms;}
237
+ .element-panel{inset-inline-start:0;transform:translateX(-105%);}
238
+ .inspector-panel{inset-inline-end:0;transform:translateX(105%);}
239
+ body[data-elements-open="true"] .element-panel,
240
+ body[data-inspector-open="true"] .inspector-panel{display:flex;transform:translateX(0);visibility:visible;}
241
+ .shape-palette{grid-template-columns:1fr;width:min(220px,calc(100vw - 16px));}
242
+ .toolbar-more-menu{grid-template-columns:1fr;width:min(260px,calc(100vw - 16px));}
243
+ .toolbar-more-menu>button:last-child{grid-column:auto;}
244
+ }
245
+ @media(pointer:coarse){
246
+ button,.tree-item,.toolbar-more-menu>.snap-toggle{min-height:44px;}
247
+ }
248
+ @media(prefers-reduced-motion:reduce){
249
+ .editor-sidebar{transition:none;}
250
+ .canvas-surface .editor-settle{animation:none;}
251
+ }