Fixed
-
Nested styled-text notation no longer leaks raw tags onto slides —
agents sometimes emit{{bold:{{#FF0000:X}}}}instead of the canonical
{{bold,#FF0000:X}}; the parser could not see through nesting and rendered
the inner tag as literal text. A flatten pre-pass now normalizes nesting
(any depth, partial nesting included) to the comma form, with inner
attributes taking priority. Non-nested input is untouched. (#123) -
Builtin template download works from the Web UI — downloading blank-dark /
blank-light did nothing: the download used afetch()+blob path that requires
CORS, and the builtin resource bucket has no CORS configuration (user templates
live in a different bucket that has one). Downloads now use the same direct-link
navigation as deck PPTX downloads (no CORS involved), the presigned URL carries
Content-Disposition: attachment, and failures show an error toast instead of
silently doing nothing. (#281) -
gridtool returns actionable errors and supports%/repeat()—
unsupported CSS track syntax (auto,minmax(), previously also%and
repeat()) crashed with an uncaughtValueErrorinstead of an error message
the agent can react to.%andrepeat(n, X)are now supported, unsupported
syntax returns{"error": ...}naming the offending token, and the supported
subset is documented in the tool docstring and grid guide. (#282) -
Live preview: icons relying on even-odd fill no longer render as solid
boxes — LibreOffice's SVG export declaresfill-rule="evenodd"only on the
root<svg>, which the per-component fragment split dropped, so multi-subpath
line-art icons (many AWS resource icons) lost their cutouts and appeared as
filled rectangles in the live preview (final PNGs were unaffected). Root
inheritable attributes are now propagated onto each fragment. (#288) -
Architecture diagram box auto-height now works on non-16:9 templates and
with CJK text — the engine used a fixed 16:9 pt-to-px ratio for text
measurement, causing boxes to undersize on 4:3 and other aspect ratios, and
did not account for fullwidth (CJK) character width.analyze_templatenow
reportsptPerPxinslide_size, the agent records it indeck.json
slideSize, andarch_diagramaccepts apt_per_pxparameter for accurate
calibration. (#285) -
Remote MCP:
analyze_templatenow includesslide_sizein cached
results — the cached template analysis omitted theslide_sizefield, so
subsequent calls returned an incomplete response and the agent could not
populatedeck.jsonslideSize. (#285) -
Custom templates with non-16:9 slide sizes (4:3 etc.) now lay out correctly —
the engine's px coordinate system followed the template width but assumed a
fixed height of 1080, so 4:3 decks left the bottom quarter of every slide
empty, reported false out-of-bounds warnings, mismatched placeholder
coordinates, mis-measured text overflow, and rendered cropped previews in the
Web UI. The canvas is now derived from the template's real dimensions
(1920 px wide, height following the aspect ratio — 4:3 becomes 1920×1440),
andanalyze_template/deck.jsoncarry the canvas size so slide
composition uses the full slide. Behaviour for 16:9 templates is unchanged.
Known limitation: architecture diagram boxes with an omittedbox.height
can still under-estimate text height on non-16:9 templates — specify
box.heightexplicitly. (#208) -
Live slide preview: the first few slides now animate — animation was
suppressed for 3 seconds after the slides tab appeared, and because a new
deck switches to that tab as soon as slides arrive, the first slides were
always shown instantly. Suppression is now based on whether the slides
already existed when the view mounted, instead of a timer. -
Live slide preview: the PNG fallback now actually appears — the error
state was reset on every 1-second poll, so the fallback was unmounted before
it could be seen; a failure to find the render container also marked the
slide as permanently processed, leaving an empty black box. Slides with
nothing to draw now fall back to the rendered PNG, and the fallback image
retries expired signed URLs. -
AWS: uploaded custom templates now apply to PPTX generation — the remote
server's template resolution only searched builtin templates, so a deck
referencing an uploaded user template silently fell back to
blank-dark.pptx. Generation now resolves user templates first (same order
asanalyze_template), and an unresolvable template name raises an explicit
error listing available templates instead of silently using the wrong
design. (#206)