Commit Graph
31 Commits
Author SHA1 Message Date
Mex f4ce764d1c M13.1: validate remote MCP replies (#718)
Reject unrelated, malformed, incomplete and oversized replies without replaying commands.
Reconnect before sending when unsolicited reply bytes are buffered.

Contribution on behalf of @MMexicann.
2026-10-14 22:24:15 +02:00
Brandon Thomas 081c9fdc5e Merge the landing branch into land-r7
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	apps/deckcraft-cli/tests/cli.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/text.rs
#	crates/engine/src/lib.rs
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/textures.rs
2026-10-14 15:34:15 -04:00
Brandon Thomas 9fc910886c Merge PR #247 from isaac-levine: MCP: confine file access with --automation-read-root and --automation-write-root
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/lib.rs
2026-10-14 15:25:09 -04:00
Brandon Thomas 34f4c1b1df Merge the older community PRs integrated on land-r6 (#204 #243 #291 #345 #258 #303 #230 #168 #177 #692 #522 #466)
# Conflicts:
#	crates/ui-egui/src/canvas.rs
2026-10-14 15:24:58 -04:00
Brandon ThomasandClaude Opus 5.5 b9851d9329 Merge PR #611 from NikitkaRa: Draw: pen pressure scales ink width
Fix-ups in the merge (review): uniform-width and highlighter strokes are drawn as one path (on
the slide and in the live preview) so see-through ink doesn't darken where segments overlap;
segment pairs are destructured instead of indexed; tests that build pointer events set the new
pressure field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:18:04 -04:00
Brandon Thomas c354f02279 Merge PR #177 from Mathiasko: Export: animated GIF of the deck (Export… dialog, CLI, MCP) (#171)
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/lib.rs
#	crates/mcp/src/tests.rs
#	crates/mcp/src/tools.rs
#	crates/ui-egui/src/dialogs.rs
2026-10-14 14:52:34 -04:00
Brandon Thomas b590cb0b0b Merge PR #303 from hoblin: deckcraft-cli help explains the CLI to an agent
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/design.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/format.rs
#	crates/engine/src/tests.rs
2026-10-14 14:36:13 -04:00
Brandon Thomas 2009242055 Merge PR #684 from NikitkaRa: Export: a PNG or JPEG slide records 144 dpi at the default 2× size
# Conflicts:
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/tests.rs
2026-10-14 14:02:59 -04:00
Brandon Thomas 06a6b10d83 Merge PR #499 from NikitkaRa: Print: choose paper size and orientation for notes and handouts
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 13:08:46 -04:00
Brandon Thomas c15b1deaf9 Merge PR #375 from NikitkaRa: MCP tools refuse an argument that is not in their schema (#371)
# Conflicts:
#	crates/mcp/src/tests.rs
2026-10-14 13:08:42 -04:00
Brandon Thomas 44f4b037e2 Merge PR #244 from pierrevbc: Canvas: right click selects the shape under the pointer
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 12:58:01 -04:00
Brandon Thomas c57d25e8d3 Merge PR #97 from mikl0s: Commands: an invalid shape id is an error instead of the selection 2026-10-14 12:57:19 -04:00
Brandon Thomas 6d57610489 Merge PR #96 from mikl0s: Slides: going to a slide that does not exist is an error 2026-10-14 12:57:19 -04:00
Brandon Thomas 7862974cad Merge PR #95 from mikl0s: Export: an unknown format is an error instead of a deckcraft file 2026-10-14 12:57:19 -04:00
Nikita RakitinandCursor d04df05249 Export: record slide resolution in PNG and JPEG pictures
A default export is 2 pixels per point. Without a resolution, Preview
treats those pixels as 72 dpi and the picture opens at twice the slide's
size. PNG pHYs and JPEG JFIF density now say scale times 72, so the
default is 144 dpi. Screenshots stay untagged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 05:35:37 +03:00
Nikita RakitinandCursor 1a0ffc6413 Draw: pen pressure scales ink width
A pen reading of 1 is the full pen width. A lighter touch draws a thinner
stroke, and a zero reading stays visible at 8% of the pen. A mouse, a
missing or non-finite reading, and a stroke whose samples are all the old
placeholder 0.5 still draw at the pen width. PPTX keeps one width per
stroke: the mean of the samples for a pressured stroke, the pen width for
a legacy one. Tilt is not read.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 01:56:23 +03:00
Nikita RakitinandCursor e6920f8ebe Print: choose paper size and orientation for notes and handouts
The Print page always laid notes pages and handouts out on portrait US
Letter. It now offers Letter, A4, Legal and A3 in portrait or landscape,
as PowerPoint's Print settings do, and the preview shows the chosen
page. file.export, app.print and the MCP export tool take the same
`paper` and `orientation` params; unknown values are an error. A notes
page keeps its slide within the top half of the page, so landscape
paper still leaves room for the notes. Full-page slides still print on
slide-shaped pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 21:43:54 +03:00
MarekSpodBiedry d4cf50dd3d MCP: do not resend a command whose reply was lost (#409) 2026-10-13 17:38:28 +02:00
NikitaandCursor 591c06ba33 MCP tools refuse an argument that is not in their schema (#371)
A misspelled key used to be dropped, so the tool still succeeded with its defaults.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 13:14:07 +03:00
pierrevbc ab81f6bc73 Canvas: right click selects the shape under the pointer
A right click on an unselected shape opened the slide's context menu
(Layout, Reset Slide...) because only the primary button reached the
pointer tool; the shape had to be left-clicked first. The right-button
press now goes through Session::pointer as PointerKind::ContextClick
(`contextclick` on the control channel and MCP) and selects like
PowerPoint before the menu opens: an unselected shape is selected alone
(a text box or placeholder is not put into text editing, nothing is
dragged), a selected shape keeps the selection, multiple selection
included, and empty slide clears it. In the box whose text is being
edited, the caret and text selection stay, and the context menu offers
text items (Paragraph, Bullets, Numbering, Link) next to Cut, Copy and
Paste, which act on the selected text.
2026-10-13 11:26:20 +02:00
Yevhenii Hurin 66f7e6e1ed Self-review: no ID[=JSON] left, params grammar documented
A --cmd without a value now asks for COMMAND[=PARAMS]. The params field
says how describe reads it, table.split's row and col are optional as
the command reads them, and the MCP instructions name only shape
commands for `ids`.

[claude-opus-5-5] on behalf of hoblin
2026-10-13 00:15:53 +03:00
Yevhenii Hurin 717e855cec deckcraft-cli help explains the CLI to an agent
`deckcraft-cli help` and each subcommand's `--help` say what it does,
with a working example; `--help` never runs the subcommand. `describe`
spells out a command's parameters and what it acts on, `commands` lists
one command per line, and the MCP instructions say what format.* acts on.

[claude-opus-5-5] on behalf of hoblin
2026-10-12 23:41:42 +03:00
Isaac Levine a541dad33d MCP: confine the headless session to the automation roots 2026-10-12 09:58:07 -04:00
Matúš LacoandClaude Opus 5.5 c871c5f634 Export: animated GIF of the deck (Export… dialog, CLI, MCP) (#171)
There was no way to turn a presentation into an animated GIF. file.export now writes one: format
`gif` (or a .gif path), one frame per slide drawn by the slide renderer and shown for
secondsPerSlide, encoded with the `image` crate's GIF encoder (already a dependency, no new
crates) with a 256-colour palette per frame: exact when a slide has 256 colours or fewer,
NeuQuant otherwise. Slides are composited onto white.

Options: width (small 640, medium 960 (default), large 1280, extraLarge 1920, or 16-3840 px; the
height follows the slide's aspect ratio, no side over 3840), secondsPerSlide (0.1-600, default 5,
written in GIF hundredths), loop (forever by default, or once: no NETSCAPE2.0 block), slides (a
list of indices, in play order) and includeHidden (hidden slides are skipped by default).
Out-of-range or wrongly typed values, NaN and infinities are BadParams errors, never panics; at
most 500 frames and 200 million pixels in total, checked before anything is rendered.

- Engine: crates/engine/src/gif_export.rs (options, frame list, size, encoder);
  cmd::file::gif_bytes, save_bytes("gif"), format_for_path(".gif").
- UI: the Export… dialog (Command palette; the app has no File menu yet) gets "Animated GIF (.gif)" with Size, Seconds per slide, From/To slide,
  Loop forever and Include hidden slides; an invalid range or value keeps the dialog open with a
  message. The web build downloads the bytes (image/gif).
- CLI: convert IN OUT.gif, run --export OUT.gif --export-params JSON; usage lists the format and
  options.
- MCP: the export tool lists gif and width/secondsPerSlide/loop (slides and includeHidden now
  apply to PDF and GIF).
- Docs: file-format parity GIF row, gaps (video export remains), parity checklist row M -> P
  (P2 breadth 36% -> 37%, overall 79%), control protocol, MCP, README, ROADMAP progress log.

Transitions and build animations are not animated in the GIF (tracked with video export).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:00:33 +02:00
Mikkel Georgsen 736dd52b51 Commands: an invalid shape id is an error instead of the selection
A shape id that was present but not a valid id (negative, not an integer,
larger than u32) was treated as absent, so commands such as text.set and
text.edit silently edited the selected shape instead. id_param now tells three
cases apart: absent (the selection fallback is unchanged), valid, and invalid
(an error naming the command). arrange, edit (select), inspect, review, table,
text and the animation painter pick this up.
2026-10-10 22:05:22 +02:00
Mikkel Georgsen d34b5df775 Slides: going to a slide that does not exist is an error
slide.go clamped an out-of-range index to the last slide and reported
success, so a request for slide 99 of a short deck landed on the last slide
without a word. It now returns an error and stays on the current slide. A slide
id beyond u32 is reported as an unknown slide instead of being read as id 0.
2026-10-10 22:05:13 +02:00
Mikkel Georgsen 20366a8ea9 Export: an unknown format is an error instead of a deckcraft file
file.export with an explicit format outside png, jpeg, jpg, pdf, pptx, potx,
ppsx, deckcraft, outline and txt fell through to the native deckcraft zip, so a
request for "docx" reported success and wrote a deckcraft archive under that
name. It now returns an error and writes nothing. A format inferred from the
file extension behaves as before.
2026-10-10 22:04:58 +02:00
5c13f6ec72 MCP: the export tool lists PDF and its layout options (#65)
tools/list described export as png/jpeg/pptx/outline only, with no PDF parameters, although
file.export (which the tool runs) writes PDF slides, notes pages and handouts. The tool's
description now names PDF, format is an enum of the formats file.export writes, and the schema
lists the PDF options: layout, perPage, dpi, slides, includeHidden, textLayer and frame.

Co-authored-by: lloyd <lloyd@stackworx.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:37 -04:00
Brandon ThomasandClaude Opus 5.5 ae9d525bce Rename SlideCraft to DeckCraft: crates, apps, binaries, app id, file extension (.deckcraft; .slidecraft files still open), packaging, docs; ROADMAP alpha and parity estimates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:46:40 -04:00
Brandon ThomasandClaude Opus 5.5 f0d230bdcd Freeform, Curve and Scribble drawing tools; shape.freeform command; composite commands are one undo step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:00:06 -04:00
Brandon ThomasandClaude Opus 5.5 6078b68e97 M0: workspace, model, geometry, fonts, text, renderer, engine, MCP and CLI
Clean-room PowerPoint-class presentation engine in pure Rust:
- geom: units, transforms and 150+ re-derived preset shapes with adjust handles
- color: theme slots and colour transforms
- model: presentations, masters, 11 layouts, placeholder inheritance, themes,
  text, tables, charts, transitions, animations, text edit operations
- fonts: font DB with craft-fonts, system fonts and open substitutes
- text: shaping, line breaking, bullets/numbering, alignment, autofit, caret hit tests
- render: vello_cpu slides with fills, gradients, pictures, effects, tables, charts
- format: native .slidecraft (zip + JSON)
- engine: ~200 commands, undo/redo, clipboard, pointer tools, keys, sample deck
- mcp: MCP server (headless or bridged to the app); slidecraft-cli

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:27:20 -04:00