mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-27 06:07:13 +01:00
* automation: doc.place reads a file through the read root (#2810) file.placeEmbedded takes an ambient path, so automation refuses it and an agent could not place a file into the open document at all. doc.place resolves the path beneath the read root the way doc.open does and hands the bytes it already read to the public file_cmds::place_bytes, so the existing cap-std rules stay the only path rules: no new scope logic, and the ambient command keeps its refusal. Trusted-local callers still run the command. * automation: export layers, data sets and CSVs through the roots (#3216) file.export.layersToFiles and file.export.dataSetsAsFiles take an ambient dir, file.import.variableDataSets an ambient path, so all three are refused in automation even for files inside the granted roots, and an agent could not export a single file or a data set at all. Both halves already existed: the engine writes bytes it has just encoded (save_doc is encode + write_file, and the data-set exporter encodes with photocraft_io::export before writing), and the automation side already holds a write capability — AuthorizedWorkspace::export_sequence creates the directory, refuses to overwrite, accepts only single-component names and removes every file it created when a step fails, which is what Render Video uses. So each command body moves behind the same sink callback render_video_with takes: the command keeps writing the bytes it is handed to its dir, the new methods write the very same bytes through the root, and the two implementations cannot drift. --------- Co-authored-by: switch87 <8284204+switch87@users.noreply.github.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>