photocraft
Skill66 starsChanged 8 days agoMITView on GitHub
PhotoCraft is the ArtCraft clean-room, pure-Rust reimplementation of Adobe Photoshop — layers, masks, adjustment layers, layer styles, live type, vectors, smart objects and real PSD read/write, with every action exposed as an engine command that the UI, a headless CLI, a JSON control channel and a 26-tool MCP server all drive. Trigger this skill whenever the user mentions PhotoCraft, asks what it can or cannot do, which file formats it reads or writes, its keyboard shortcuts, how to script, automate or batch it, how to prepare assets for it, how to inspect, verify or repair a .pcraft, PSD, XCF or .ora it produced, or how to troubleshoot it — and also when they never name the app but describe the job, such as "edit this photo", "open this PSD", "make a transparent PNG", "batch-resize a folder of images", "remove the background with a quick selection", "convert these HEIC/NEF/PCX files" or "check what is in this layered file". It is early alpha — never promise Photoshop-grade PSD fidelity, generative AI features or a stable UI, and prefer the headless CLI and MCP over driving the GUI blind.
- Installs packages
2 other projects use a version of this.
Adopted by
Most recently taken up by
- PBandDev/skillstheir own version, first seen Oct 15, 2026
- hermes-pro/storytold-skillstheir own version, first seen Oct 13, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- hermes-pro/storytold-skills★ 36same name
- PBandDev/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- artcraft-studioSkill
- cadcraftSkill
- craft-anythingSkill
- deckcraftSkill
- designcraftSkill
- effectcraftSkill
- figcraftSkill
- filmcraftSkill
- gridcraftSkill
- lightcraftSkill
- materialcraftSkill
- pdfcraftSkill
- solidcraftSkill
- soundcraftSkill
- texturecraftSkill
- vectorcraftSkill
- wordcraftSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 72
Read this before assigning work — several of these are why agents must not promise Photoshop behaviour.
- Distinctive: line 85
Distribution gaps: no in-app bug-report dialog (DIST-220-3 missing), no periodic update recheck while the app stays open (DIST-220-1 …
- Distinctive: line 86
Wayland: no drag-and-drop (winit 0.30 limit) and XWayland fractional scaling is blurred (README.md).
- Very specific: line 103
Never launch the GUI just to inspect a file — use the CLI.
- Very specific: line 170
Version projects: Keep the .pcraft for lossless re-edits and hand Photoshop the PSD/PSB.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PhotoCraft
Audit basis. Refreshed 2026-11-07 against tag v0.21.0, commit efb7ebd0c0dab1fc108ee4642aa47c22694271a8 — git rev-parse HEAD in the pinned checkout confirms, and the installed bundle matches at 0.21.0 (its photocraft-cli prints photocraft-cli 0.21.0 (efb7ebd0c, 2026-11-06)). The previous release this skill described was v0.20.1 (327c4cc).
v0.20.1 → v0.21.0 delta. 916 files changed (+127,407/−6,129) and the registry grew while the automation method sets stood still. 993 commands now answer (photocraft-cli commands | wc -l on the installed bundle; 953 at v0.20.1) and menu parity is 660/660 (docs/parity-checklist.md:5, floor crates/ui-egui/src/menus/parity.rs:10). New: the Frame tool family layer.frame.{set,setContent,fit,convert,info}; OpenType Numerals (type.openType.numerals.*, 9 ids) and Stylistic Sets 1–20 (crates/engine/src/cmd/type_extra_cmds.rs); memory supervision — file.approveMemory (crates/engine/src/cmd/file_cmds.rs:293) behind a pre-flight gate (crates/engine/src/memory_gate.rs) and native scratch storage (crates/engine/src/scratch.rs), with --approve-high-memory on the CLI. JPEG XL is the 23rd codec format and is export-only (crates/codecs/src/format.rs:110 [Format; 23], :287 read: false, lossless via zune-jpegxl). Actions gained playback/history controls (21 actions.* ids) and the EVENTS table holds 204 rows with a new target_event! family (crates/engine/src/cmd/atn_cmds/events.rs:378). Locale catalogs 26 → 27 (Bosnian). filter.* measures 124 live ids (47 filter.gallery.*, 64 pairwise, 13 workspace/lifecycle) and filter.blur.shapeBlur is new. Unchanged at v0.21.0: control channel 28 methods, MCP 26 tools, headless serve 19 methods, 68 tools, 16 adjustment kinds, 10 layer effects, 34 blend modes, the 14 fail-closed filesystem commands — crates/automation moved only in jobs/progress and workspace internals.
v0.19.0 → v0.20.1 delta. 276 files changed; the wave was the Actions (.atn) surface — recorded Camera Raw Filter steps importing as filter.cameraRaw, string-class handling for Vibrance sets, a strict export of partial Levels edits refused, Stroke steps writing the settings they leave at default, and an Actions panel that records into the selected set (crates/engine/src/actions_record.rs, crates/engine/src/cmd/atn_cmds/). Also editable arrowheads on the Line tool (crates/vector/src/shapes.rs) and buffer-reuse work in the filter path. Older rounds (the bundled CLI and locale wave of v0.18.0, and v0.17.0) are folded into CHANGES.md; the facts from them that still matter live in the sections below.
Verify against your installed version — the ArtCraft Launcher auto-updates, so a newer build may differ; every count quoted here was re-measured at this tag, and code paths that moved were re-cited. The measurement method for each count is in evidence.md.
Overview
PhotoCraft is "Image editing; an open-source, clean-room reimplementation of Adobe Photoshop, rebuilt in pure Rust" (README.md), MIT/Apache-2.0 dual licence, storytold/photocraft. The native app is egui/eframe 0.37 on wgpu, using the shared craft-ui docking, with a CPU compositor kept as the reference oracle; the same engine and UI compile to WebAssembly (apps/photocraft-web). Every menu item, tool and dialog is one engine command, so the UI, photocraft-cli, the loopback JSON control channel and the MCP server run the same code (crates/engine/src/cmd.rs build()). Maturity is early alpha; docs/gaps.md (last updated 2026-11-05) is the ranked shortfall list against Photoshop 2026. All 660 Photoshop menu items are wired to a command (docs/parity-checklist.md:5, floor enforced at crates/ui-egui/src/menus/parity.rs:10); wiring is dispatch, not behaviour.
Capabilities (verified)
Editing core
- Documents and colour: RGB, Grayscale, CMYK, Lab, Bitmap, Indexed, Multichannel, Duotone at 8/16/32-bit; ICC management in pure Rust with Assign/Convert to Profile, four rendering intents, black-point compensation, soft proofing and Gamut Warning (
crates/cms,crates/engine/src/cmd.rsadjustments, CMYK compositing on stored inks). - Layers: pixel layers, groups (new-group dialog; new layers join an open group and its clip group), clipping masks, pixel and vector masks with Density/Feather, fill layers (solid/gradient/pattern), adjustment layers, live smart objects with smart filters and lossless transforms/warps (including Cylinder), artboards (New Document can start as an artboard; Artboard from Layers takes a custom size), alpha channels (drag-reorder in the Channels panel), Quick Mask, layer comps, advanced blending with per-layer Transparency Shapes Layer (
crates/doc/src/lib.rs,crates/doc/src/effects.rs). - 16 adjustment layers:
layer.newAdjustmentLayer.{brightnessContrast, levels, curves, exposure, vibrance, hueSaturation, colorBalance, blackWhite, photoFilter, channelMixer, invert, posterize, threshold, gradientMap, selectiveColor, colorLookup}plus the same 16 as destructiveimage.adjustments.*, all generated from the 16-entryADJtable (crates/engine/src/cmd.rs:1093). Extra destructive-only: Shadows/Highlights, Replace Color, Match Color, HDR Toning; 32-bit Hue/Saturation and Colorize behave as in Photoshop. - 10 layer effects, several instances per kind: DropShadow, InnerShadow, OuterGlow, InnerGlow, Stroke, ColorOverlay, GradientOverlay, PatternOverlay, Satin, BevelEmboss (separate Highlight/Shadow mode dropdowns), driven by
layer.layerStyle.*commands (crates/doc/src/effects.rs,crates/engine/src/layer_style.rs);.aslstyle libraries import. - Blend modes: PassThrough + 27 Photoshop modes + 6 Paint.NET-only modes = 34 enum variants (
crates/color/src/blend.rs); Shift+Alt+letter picks a blend mode from the keyboard. - 68 tools —
pub const ALL: [Tool; 68](crates/ui-egui/src/state/tool.rs:82), every classic Photoshop tool is now present: Art History Brush landed in v0.18.0 (upstream marks it partial, TOOL-213-20,docs/gaps.mdG6). Includes Remove, Spot/Healing/Patch, Content-Aware Move, Mixer Brush (renders mixed paint live during the stroke), Magnetic Lasso, Object/Quick Selection, Pen/Freeform/Curvature Pen, Type and Type Mask, Perspective Crop, Frame, Slice; mode dropdowns for Clone/Pattern Stamp, History Brush, Healing and Paint Bucket. - Selections: marquee/lasso/wand,
select.quick,select.object,select.subject,select.colorRange,select.focusArea,select.refineEdge,select.magneticLasso; Select and Mask refinement is guided-filter matting with Smooth/Feather/Contrast/Shift Edge and colour decontamination (crates/algo/src/matting.rs) — classical, no learned models; Select and Mask stays a dialog, not a workspace (crates/engine/src/cmd/cutout_cmds.rs,docs/gaps.mdG7). Remove Background (Properties › Quick Actions) turns Select Subject + edge refinement into a layer mask in one history step. - 124 live
filter.*command ids (counted from the registry, not from string literals): 47 Filter Gallery filters from thegallery!table incrates/algo/src/artistic.rs:38(each registered asfilter.gallery.<key>bycrates/engine/src/cmd/gallery_cmds.rs, plusfilter.filterGalleryitself), 64 pairwise filters registered incrates/engine/src/filters.rs/filters_ext.rs, and 13 workspace/lifecycle ids (filter.blurGallery.{field,iris,path,spin,tiltShift},filter.liquify,filter.adaptiveWideAngle,filter.cameraRaw,filter.vanishingPoint,filter.lensCorrection,filter.lastFilter,filter.convertForSmartFilters).filter.blur.shapeBluris new at v0.21.0. Filters applied to a smart object become re-editable smart filters; 53 PSD filter classes map one-to-one to 53 distinct commands throughfilterFX(crates/io/src/smart_map/import.rsKNOWN: [Known; 53]) — Diffuse, Trace Contour, Crystallize, Pointillize and Halftone Pattern round-trip like Photoshop. Field/Iris/Tilt-Shift/Spin Blur are on-canvas; Path Blur is still a parameter dialog. - Type: point/area/paragraph text on canvas, Character/Paragraph controls (paragraph-direction buttons, partial), manual+optical kerning with PSD round trip, variable-font axes, editable font size/leading/tracking preset menus, font menu with favourites/recents/class filters/live preview,
type.warpText,type.resolveMissingFonts; headless editing viatype.editText,type.hitTest,type.caret,type.navigate. OpenType Numerals (Adobe's figure styles:type.openType.numerals.{default,lining,oldstyle,proportional,proportionalLining,proportionalOldstyle,tabular,tabularLining,tabularOldstyle}) and Stylistic Sets 1–20 (type.openType.stylisticSets.set1…set20) sit alongside the eight older feature toggles, all incrates/engine/src/cmd/type_extra_cmds.rs. Type on a path follows path edits and PSD round-trips through the file'sTxt2(crates/psd/src/tiff.rs,docs/gaps.mdG8). - Vectors: Pen/Freeform/Curvature, anchor add/delete/convert, Paths panel, work paths, shape layers with dashed/aligned strokes, corner radii and gradient strokes (gradient stroke turns with the canvas), path↔selection, SVG as editable shape layers or vector smart object (
crates/engine/src/cmd/,docs/shape-strokes.md). - Actions: 21 live
actions.*commands (list/get/record/stop/play/move/delete/toggle/rename/load/save/insert/dialog/assignSet/newSet/setColor/conditional, plusstopMessage,performance,setPlayback,setHistory,createSingleHistoryState) with nesting to 16 levels; 204 rows in theEVENTStable (crates/engine/src/cmd/atn_cmds/events.rs:378) for.atnimport/export, built fromev!,adjustment_event!,stylize_event!,selection_event!,clipping_event!and the newtarget_event!; unsupported event kinds are preserved verbatim and fail at playback by name; actions ending in Save As/Close work (the result is taken at the Save step). - History: New Snapshot dialog, History Options with Allow Non-Linear History and undoable visibility changes (
crates/engine/src/cmd/, History panel rebuild). - Photomerge:
file.automate.photomerge(reposition/perspective) as a cancellable background job. - Frame tool: five commands —
layer.frame.set,layer.frame.setContent,layer.frame.fit,layer.frame.convert,layer.frame.info— for placing and re-fitting a frame's content (new at v0.21.0). - Memory supervision:
file.approveMemoryclears an operation that the pre-flight gate refused,crates/engine/src/memory_gate.rsasking whether an allocation can still be satisfied before it starts (a refusal changes nothing and says what to do), andcrates/engine/src/scratch.rsholds the native tile-storage settings outside the preference model; the CLI exposes the same approval as--approve-high-memory. - Print: File › Print renders one flattened page and prints through an in-process pure-Rust IPP client, the Linux print portal, the Windows spooler or to a PDF file;
file.printerslists queues,"dryRun": truepreviews (crates/engine/src/cmd/print_cmds.rs,docs/printing.md). - Video-lite: 7
timeline.*commands andfile.export.renderVideo(PNG sequence or animated GIF); animating GIF and WebP open every frame through New Video Layer from File. - Update check: Help › Check for Updates, an opt-out once-per-launch release-feed check, and a startup self-update prompt modal (
crates/engine/src/cmd/updates_cmds.rs, self-update delegated to the sharedcraft-updatecrate).
Files — read / write
- Native
.pcraft: directory bundle or zip of STORE entries =manifest.json(format version 1; manifests with too many JSON values are refused before parsing) + content-addressed BLAKE3/zstdtiles/+blobs/+thumb.png+ composite preview; incremental, atomic (temp/fsync/rename), crash-recovery autosaves with single-step sidecar replacement (crates/format/src/). - Read + write: PSD/PSB/PSDT (PSB chosen by encoded size; spot channels in Photoshop's polarity;
MTrnmerged transparency; layered TIFF text descriptors keep PSD byte order), layered TIFF including alpha and spot channels as extra samples, plus Photoshop's global layer mask block (crates/io/src/tiff_layers.rs,crates/codecs/src/codecs/tiff/), OpenRaster.ora, PDF write-only one flattened page, and the flat codecs: PNG, JPEG, TIFF, WebP (lossless + own lossy VP8), GIF, BMP, TGA, ICO, Netpbm (PBM/PGM/PPM/PAM/PFM), QOI, DDS (uncompressed or BC1/BC2/BC3 + optional mip chain, exports the document alpha), OpenEXR, Radiance HDR, FITS, DPX, Cineon, Amiga IFF (24-bit ILBM writer) and JPEG XL (lossless export only) (crates/codecs/src/format.rs:110Format::ALL [Format; 23]). - 23 codec formats; every one is read+write except the documented asymmetries (
ASYMMETRIC_EXCEPTIONS,crates/codecs/src/format.rs): read-only PCX, XPM and DICOM, JPEG XL write-only (lossless through the pure-Rustzune-jpegxl; JPEG XL reading is tracked separately —crates/codecs/src/format.rs:90), AVIF write-only behind the non-defaultaviffeature, HEIF/HEIC read-only behindheif(on in official builds). - Layered imports (read-only): Paint.NET
.pdn/PDN3, Krita.kra/.krz, GIMP.xcf/.xcf.gz, Affinity.af*, SVG; writing an import-only target is refused with a naming error inexport_stages(crates/io/src/lib.rs). - Camera raw: DNG (uncompressed/deflate/lossless-JPEG/lossy-JPEG/floating-point JPEG XL — lossy DNGs now decode, falling back to the JPEG XL preview rather than the tiny thumbnail), CR2, TIFF/EP raws (NEF, ARW, PEF), Nikon compressed NEF, Sony cRAW, Panasonic RW2, uncompressed Olympus ORF, uncompressed Fujifilm RAF; Camera Raw settings sidecars (
.xmp,crs:namespace) load, auto-fill the dialog when beside the raw file, and are written by Save Settings (crates/io/src/camera_raw_xmp.rs); Calibration panel, Auto button and live Camera Raw Defaults. CR3 remains preview-only — upstream assessed a clean-room CRX reader as not feasible (docs/gaps.mdG14). - Export As offers exactly
png, jpg, webp, tif, tga, ico(crates/engine/src/cmd/export_preset_cmds.rs:13); Save for Web offersgif, png8, png24, jpeg, wbmp, webp; Quick Export as PNG is a single menu item; the Save As picker lists every supported format. - Honest exports:
caps(format)andfidelity_warningsreport depth reduction, CMYK→RGB, dropped layers and missing fonts before writing; CLI/info/app.savesurface them as warnings.
Automation surfaces (counts re-measured at v0.21.0)
- One command registry, 660/660 menu items live (
crates/ui-egui/src/menus/parity.rs,docs/parity-checklist.md:5). The live registry at this tag measures 993 commands (photocraft-cli commands | wc -lon the installed bundle that matches this tag). Table macros still expand per row (the 16-entryADJtable alone generates 32 commands), so a static count stays uncertain by a few dozen — the CLI remains the authority. README's "500+" anddocs/architecture.md's "~700" are floors, not measurements. - CLI
photocraft-cli— 8 subcommands +help:convert, info, run, batch, droplet, commands, mcp, serve(apps/photocraft-cli/src/args.rs:31; re-verified live from the installed bundle), exit codes 0 ok / 1 failure / 2 usage. 12 export flags shared byconvert/run/batch:--format --quality --tiff-layers --tiff-compression --tiff-transparency --tiff-pyramid --tga-bits --dpx-bits --dds-compression --dds-mipmaps --jpeg-format --pcraft-full-composite(the last three are new at v0.21.0;convert/runalso take--approve-high-memoryand--gpu/--no-gpu).batchfolder sources accept every format PhotoCraft opens. - Control channel (
photocraft --control <port>, loopback only): first frame must be{"id":"auth","method":"auth","params":{"token":"<64 hex>"}}; then 28 methods, unchanged at v0.21.0 —engine.execute,engine.commands,jobs.list,jobs.cancel,ui.inspect,ui.set,ui.menu.invoke,ui.menu.list,ui.pointer,ui.click,ui.move,ui.key,ui.type,ui.resize,ui.focus,ui.screenshot,ui.context.choose,ui.dialog.open/set/confirm/apply/cancel,ui.window.open/close,ui.gpu.simulateLoss,app.open,app.save,app.quit(crates/ui-egui/src/control/dispatch.rshandler chain). Transports:apps/photocraft/src/control_server.rs; 60 s reply timeout, 1 MiB request cap, 16 connections; request paths refuse Windows device names and replacing a non-image file inside the write root. Preferences › Integrations wires Allow Agent Control and the control port in the UI. - MCP — 26 tools, unchanged at v0.21.0 (
crates/automation/src/server.rs#[tool]entries):session_list,doc_open,doc_place,doc_replace_smart_object,doc_export_layers,doc_export_data_sets,doc_import_data_sets,doc_new,doc_save,doc_export,doc_inspect,doc_render_preview,render_preview,doc_select,doc_close,command_list,command_run,jobs_list,jobs_cancel,command_batch,ui_inspect,ui_screenshot,ui_pointer,ui_menu_invoke,ui_set,control_call— unchanged as a set since 0.16.0, though waited commands now run as jobs with progress and cancel. 2 MCP resources (photocraft://document,photocraft://commands,crates/automation/src/server/conventions.rs). Bridge-only: the fiveui_*tools +control_call; headless-only:doc_select,doc_close. - Headless server
photocraft-cli serve(stdio or--port) answers 19 methods, unchanged at v0.21.0 (crates/automation/src/rpc.rs:42METHODS):engine.execute,jobs.list,jobs.cancel,engine.commands,session.list,doc.open/place/replaceSmartObject/new/save/exportLayers/exportDataSets/importDataSets/inspect/render/select/close,batch,methods. - Automation budgets: 8 MiB reply, 5 MiB PNG, preview
max_side2048, 64 M source pixels for renders, 256 batch steps, 30 s IO timeout, 10 s auth deadline (crates/automation/src/budgets.rs,security.rs). - Plug-ins: WebAssembly ABI v1 only —
plugin.list/install/remove/reload/run(5 commands), wasmi sandbox, no WASI/filesystem/network/clock, 32 MiB module, 512 MiB memory, 50 M instructions + 4,000 per sample, 60 s per run; duplicate manifest parameters are refused (docs/plugins.md,crates/plugins/src/runtime.rs). - Batch/droplets:
photocraft-cli batchtakes an actions JSON, an Actions set (--actionpicks by name) or a.atnset, applies it to a folder with{name}/{serial}/{date}output templates, and refuses--out == --inunless--in-place..pcdropletdroplets run viafile.automate.runDroplet.
Platform
- macOS (universal, signed+notarized), Windows x64/x86/ARM64 (per-user MSI install is now the default policy), Linux x86_64/aarch64 (AppImage, Flatpak, deb, rpm, tarball), FreeBSD 14, and a WebAssembly web build (
README.mdDownloads;docs/scorecard.mdDIST rows — Windows signing is skipped with a warning until the signing material exists). - GPU compositor on wgpu (Metal/Vulkan/DX12/WebGPU) with CPU fallback,
--safe-gpu, automatic device-loss fallback, one place records why a view left the GPU, andui.gpu.simulateLoss(withdestroy: true) for testing. - Pen tablets (
docs/hardware-parity.md,crates/tablet): macOS pressure/tilt/barrel-rotation (rotation not applied to tip angle); Windows pressure only (tilt and rotation missing); Linux X11 pressure+tilt with partial rotation; web pressure/tilt/twist; native Wayland tablet-v2 still open.
Known limitations and not-implemented
Read this before assigning work — several of these are why agents must not promise Photoshop behaviour.
- Alpha, by measurement:
docs/gaps.md(updated 2026-11-05) is the ranked shortfall list; the ROADMAP percentages were measured at 0.6.0 and have not been recomputed. Performance scorecard: readdocs/scorecard.mdfor the current pass/budget rows rather than trusting any snapshot here. The ROADMAP's headline rows (menus, tools, formats) are stale — the generated parity checklist and the code win. - PSD fidelity is the blocking gap (G1): enforced corpus floors are minimums — Photoshop-authored oracles 190/258, psd-tools 249/308, io corpus 148/169, round trips 258/258-era floors as CI enforces (
crates/io/tests/it/corpus.rs:151-159). A re-saved PSD is never byte-identical to its source (only the standalonephotocraft-psdcrate reproduces corpus files byte for byte), and Photoshop failing to reopen our files is tracked upstream (docs/gaps.mdG1). - No generative AI: no ONNX runtime or ML crate in the workspace; no Neural Filters, generative fill/expand, sky replacement or generative Remove. Select Subject/Remove Background and Refine Edge are classical algorithms (GrabCut/max-flow segmentation; guided-filter matting — the "local models" are local linear models of the guided filter). Learned segmentation remains open (
docs/gaps.mdG15). - No native Photoshop plug-ins:
.8BF, CEP and UXP are not hosted; only the Wasm ABI v1 (ABI v2 with panels/progress still open) (docs/gaps.mdG16). - Workspaces that are dialogs (G7): Select and Mask is a dialog, no Content-Aware Fill sampling workspace, Vanishing Point has a plane editor but no clone-in-plane, and Path Blur is still a parameter dialog while Field/Iris/Tilt-Shift/Spin are on-canvas.
- Type depth (G8): OpenType Numerals and Stylistic Sets 1–20 are menu commands at v0.21.0 (they landed after the previous round), and type on a path follows path edits; still open are the RTL visual caret and parts of the paragraph-direction UI (
docs/gaps.mdG8). - Formats absent: Photoshop PDF read; EPS/DCS and generic EPS/AI; Cloud PSD
.psdc; JPEG 2000; Pixar; MPO/JPS; PICT; Scitex CT; Photoshop Raw; AVIF read; JPEG XL read (it is export-only). WBMP is not a codec but Save for Web writes it. Affinity, Paint.NET, Krita and XCF are import-only (writable targets are refused incrates/io/src/lib.rs). File › Open takes only a GIF/WebP animation's first frame (use New Video Layer from File for all frames) and per-frame delays are not kept in.pcraft(docs/file-format-parity.md). - Camera raw partial: CR3 sensor data no (preview only; clean-room CRX assessed as not feasible), "lossy after split" NEF no, no Fuji colour calibration, Olympus ORF and Fujifilm RAF only uncompressed. Raw
.xmpsettings sidecars now load and save (camera-raw settings only — not a general XMP metadata writer). - Dead preferences: 10 of 192 settings do nothing (
docs/scorecard.md:212, generated by the prefs audit; was 12 of 181 at the previous pin, anddocs/gaps.md's header still says 11 of 183). CI regenerates that count, so re-read the scorecard rather than trusting this line. - Automation is fail-closed: these 14 commands are refused over control/MCP/
serve—file.open,file.openAs,file.save,file.saveAs,file.saveACopy,file.export.saveForWebLegacy,pattern.import,layer.smartObjects.{exportContents, replaceContents, relinkToFile, convertToLinked},measurementLog.export,layer.videoLayers.reloadFrame,edit.colorSettings; path params of other commands (layer.exportAs,filter.distort.displacemapPath, preset imports, plug-in install,layer.setAdjustment {"file": …},prefs.seton file-backed sections) are refused too, and the desktop app additionally refusesimage.mode.*(crates/automation/src/workspace/tests.rs:315pins the list;workspace.rsenforces it). - Localization: UI strings translated, engine messages stay English; 27 locale catalogs at v0.21.0 (
crates/ui-egui/src/i18n/*.tsv; Bosnian is new) and some remain partial (ROADMAP.mdLanguages,docs/gaps.mdG13). - Distribution gaps: no in-app bug-report dialog (DIST-220-3 missing), no periodic update recheck while the app stays open (DIST-220-1 partial — there is a startup prompt now), Windows signing skipped without secrets (DIST-2 partial).
- Wayland: no drag-and-drop (winit 0.30 limit) and XWayland fractional scaling is blurred (
README.md). - Docs lag the code — verify against your installed version before asserting a feature is missing; the generated scorecard/parity-checklist numbers are trustworthy, hand-written prose in the same docs can lag.
How to operate
Launch (macOS)
open -a PhotoCraft # normal GUI launch
open -a PhotoCraft /path/to/file.psd # open a file in the running instance
open -a PhotoCraft --args --control 7878 --control-token-file "$HOME/.photocraft/control.token" \
--automation-read-root "$PWD" --automation-write-root "$PWD"- Binary:
Contents/MacOS/PhotoCraftinside the app bundle. The macOS bundle also shipsphotocraft-clibeside it (Contents/MacOS/photocraft-cli, since 0.18.0); older bundles and other platforms: get the CLI fromphotocraft-cli-<ver>-macos-universal.zip(signed, notarized),cargo install --path apps/photocraft-cli --locked, or the Linux.deb/.rpm, which installphotocraft-clionPATH. - App flags, parsed by clap so a typo is a usage error (exit 2): files,
-h/--help,--version,--safe-gpu,--in-window-menus,--new-instance,--present-mode <fifo|vsync|autovsync|novsync|immediate|mailbox|autonovsync>,--frame-latency <1..3>,--stroke-trace <stderr|FILE.csv>,--control <port>,--control-token <64-hex>,--control-token-file <path>,--automation-read-root <dir>,--automation-write-root <dir>,--(apps/photocraft/src/launch_args.rs). Env equivalents:PHOTOCRAFT_CONTROL_PORT,PHOTOCRAFT_CONTROL_TOKEN(_FILE),PHOTOCRAFT_AUTOMATION_{READ,WRITE}_ROOT,PHOTOCRAFT_CONFIG_DIR,PHOTOCRAFT_NEW_INSTANCE. A token flag given without a value now fails the launch instead of silently falling back (#6429). - Without any token flag, a fresh 256-bit one is generated and printed to stderr; a token file is created mode 0600. Treat it as a credential: it grants the whole non-filesystem control surface over unencrypted loopback (
crates/automation/src/security.rsserver_token,docs/control-protocol.md). - Never launch the GUI just to inspect a file — use the CLI. On macOS occluded windows stop rendering, so
ui.screenshotraises the window and steals focus (ui.screenshot {focus:false}avoids it).
Headless CLI
photocraft-cli convert in.psd out.pcraft [--format <ext>] [--quality 1-100] [--tiff-layers] \
[--tiff-compression none|lzw|zip] [--tiff-transparency on|off] [--tiff-pyramid] \
[--jpeg-format baseline|optimized|progressive] [--pcraft-full-composite] \
[--tga-bits 24|32] [--dpx-bits 8|10|12|16] [--dds-compression none|bc1|bc2|bc3] [--dds-mipmaps] \
[--in-place] [--approve-high-memory]
photocraft-cli info out.pcraft [--compact] # JSON: size, mode, depth, layer tree, warnings
photocraft-cli run in.png --cmd layer.new.layer --params '{"name":"Ink"}' \
--cmd filter.blur.gaussianBlur --params '{"radius":3}' \
--out out.psd <same export flags>
photocraft-cli run --new '{"width":800,"height":600,"background":"white"}' --cmd document.inspect --out new.pcraft
photocraft-cli batch --actions actions.json [--action <name>] --in ./raw --out ./graded [--format jpg] [--in-place]
photocraft-cli droplet job.pcdroplet ./images [--out ./done]
photocraft-cli commands [--json] [--filter blur]
photocraft-cli mcp [--bridge 127.0.0.1:7878] [--control-token <hex> | --control-token-file <path>] \
[--automation-read-root <dir>] [--automation-write-root <dir>]
photocraft-cli serve [--port <port>] [--control-token <hex> | --control-token-file <path>] \
[--automation-read-root <dir>] [--automation-write-root <dir>]Behaviour that bites: each --params belongs to the --cmd before it; run needs exactly one of <FILE> or --new, and at least one --cmd or --out; command results are one JSON line each on stdout while warnings go to stderr; convert/run refuse an <OUT> that is the <IN> unless --in-place; batch refuses an --out equal to --in (canonicalised, so symlinks count), refuses to overwrite a same-named output, and fails the file whose nested action fails; --quality sets JPEG and lossy WebP (without it WebP is lossless); an operation the memory gate refuses needs --approve-high-memory here, or file.approveMemory over automation; MCP --bridge and serve --port refuse automation roots/token flags they cannot honour.
Document and window model
One window holds the open documents as tabs (the control channel exposes them as window.document.<index> in tab order, active one checked); ui.window.open adds an extra window. On Windows and Linux a second launch hands its files to the running instance as new tabs; --new-instance and any --control launch start a separate process (macOS relies on LaunchServices).
Open / save / export flow
- Open: File › Open (
Cmd+O), drag-and-drop,open -a PhotoCraft <file>,photocraft-cli, orapp.open/doc.openover automation. Save (Cmd+S) writes back to the document's own PSD/PSB/.pcraft; Save As (Cmd+Shift+S) picks the format from the extension —.pcraftfor lossless native, PSD/PSB for Photoshop handoff, any writable codec extension for flat output,.pdffor one flattened page,.cinfor Cineon,.ifffor Amiga IFF,.jxlfor lossless JPEG XL,.ddswith DDS Options..pcraftoutput can carry the flattened document at canvas size ascomposite/full.png(--pcraft-full-composite, or check the manifest'sfull_compositemember). Long opens/saves run as cancellable background jobs with progress. PSD/PSB open reads channel data as decoded, in bands, without loading the whole file. - Over the control channel/MCP use
app.open/app.save(desktop) ordoc.*(serve/MCP) with paths relative to the automation roots; the refused ambient commands are listed above. Embedded smart objects are the exception that works:layer.smartObjects.editContents,saveContents,convertToLayersrun pathless, and the capability-scopeddoc_place(MCP),doc.replaceSmartObject(serve) anddoc_replace_smart_objectread beneath the read root. - Modal workspaces gate menu invocation: while Camera Raw, Liquify, Content-Aware Fill, Filter Gallery or Adaptive Wide Angle is open,
ui.menu.invokerefuses every other item and accepts only that workspace's{"ui":{…}}requests — finish with{"ui":{"commit":true}}or{"ui":{"cancel":true}}first (docs/control-protocol.md).engine.executeis not gated. - Keyboard shortcuts: authoritative tables are
crates/engine/src/shell_commands.rs(shell + tool defaults) and the menu catalogue. Verified examples:Cmd+O/Cmd+S/Cmd+Shift+S,Cmd+Alt+Shift+WExport As,Cmd+FSearch…,Cmd+JLayer via Copy,Cmd+DDeselect,F5Brush Settings,F6Color,F7Layers; Shift+Alt+letter selects a blend mode. Photoshop.kyssets import/export throughedit.keyboardShortcuts.
State on disk
- Settings: macOS
~/Library/Application Support/Photocraft/(preferences.json,Presets/with.pcbrushes,actions.json, gradient/style presets,.aslstyle libraries,ui.ronfor window and dock geometry); Windows%APPDATA%\Photocraft; Linux$XDG_CONFIG_HOME/photocraftor~/.config/photocraft. Override withPHOTOCRAFT_CONFIG_DIR; portable mode (portable.txtorPhotoCraft.portablebeside the executable) keeps everything in<exe dir>/PhotoCraftData(apps/photocraft/src/app_dirs.rs). - Crash recovery:
<data dir>/Recovery/<key>.pcraftdirectory bundles plus<key>.jsonmetadata, offered at the next launch and deleted when the document is saved or closed. Autosave interval is preferencefileHandling.autosaveMinutes, default 10, valid 1–240.
Working with an AI agent
Preferred ladder — use the highest rung that answers the question:
- Headless CLI for convert/inspect/batch; no GUI, no token (
photocraft-cli convert|info|run|batch|droplet|commands). - MCP headless (
photocraft-cli mcp --automation-read-root … --automation-write-root …) for command sequences plus inspection; without roots it has no file authority (by design). - Control channel on a live app (
--bridge, orphotocraft --control) when UI state, dialogs, pointer gestures or screenshots are genuinely required. - GUI pointer events last —
ui.pointer/ui.keyare validated and replayable but depend on window focus on macOS.
Legitimate work:
- Prepare inputs: convert any supported source to
.pcraft/PSD/PNG (or DDS textures with--dds-compression/--dds-mipmaps), resize/grade viabatch, generate actions JSON or droplets, pre-export assets for other Craft apps. HEIC, NEF/CR2/DNG, XCF, KRA, PDN and Affinity files are sources, not deliverables. - Read and interpret documents:
photocraft-cli info <file>JSON, ordocument.inspect/layer.list/document.pixelover MCP;.pcraftmanifest.jsonis plain JSON and can be read directly. - Verify exports: reopen with
photocraft-cli info, read stderr warnings, probe pixels, compare size/alpha. Do not byte-compare a re-saved PSD to its source — PhotoCraft rewrites image resources, layer records and the composite, so only reopening the file tells you it is right. - Repair by regeneration, not by hand:
.pcrafttiles/blobs are content-addressed zstd objects — never edit them in place. Rebuild from the source image, an earlier bundle or the app; a bundle with a newerformat_versionis refused with a clear error (crates/format/src/migrate.rs). - Batch safely:
batchwill not silently overwrite and fails a file whose nested action fails; MCPcommand_batchis not atomic (earlier steps stay applied, no rollback), so inspect history afterwards and undo per entry. Long steps acceptwait: falseand are polled/cancelled withjobs.list/jobs.cancel.
Do not: assign generative-AI work, expect Photoshop to always open our PSD exports, assume a format is supported because Photoshop has it, drive the GUI blind when a headless command exists, use image.mode.* from desktop automation, assume XCF/KRA/PDN/Affinity files can be saved back, or trust doc statements that the code contradicts.
Verification protocol
PhotoCraft is alpha: verify every artefact, never trust a silent export.
- Round-trip smoke test in a scratch directory:
photocraft-cli run --new '{"width":64,"height":64,"background":"white"}' --cmd layer.new.layer --out t.pcraft, thenphotocraft-cli info t.pcraft, thenphotocraft-cli convert t.pcraft t.pngand open the PNG in another viewer. For edits, insert a command between--newand--outand read each command's JSON line. - Read the warnings. Depth reduction, CMYK→RGB, dropped layers, clipped values and missing fonts print to stderr on
convert/run/batchand appear ininfo/app.savewarnings. An export with no warning is the only export you should believe. - Version projects. Keep the
.pcraftfor lossless re-edits and hand Photoshop the PSD/PSB; keep the original source. Re-saved PSDs are not byte-identical, and.pcraftmigrates on load — never downgrade a bundle. - Update only between projects. This skill documents 0.21.0 (
v0.21.0, commitefb7ebd0); a launcher auto-update can change how files save. If the installed app differs, re-verify formats and counts (photocraft --versionprints version, commit and build date —crates/engine/src/build_info.rs; the bundledphotocraft-cli --versionprints the same triple). - Prefer reversible operations. Work on copies (
image.duplicate, orhistory.newDocumentwhich creates a new active document by default), inspectdocument.inspecthistory, and remember automation saves never fire script events.
Sources & evidence
- Repo: https://github.com/storytold/photocraft — inspected at tag
v0.21.0, commitefb7ebd0c0dab1fc108ee4642aa47c22694271a8, inspection date 2026-11-07; thev0.20.1tree (327c4cc82e737a3e0af7c147a477126d77525495) was read for the delta and for counting both sides of it. - Installed app:
/Applications/PhotoCraft.app— version 0.21.0, bundle idai.storyteller.photocraft, minimum macOS 11.0;Contents/MacOSholdsPhotoCraftand the bundledphotocraft-cli, which was run read-only (--version,commands,--help) and printsphotocraft-cli 0.21.0 (efb7ebd0c, 2026-11-06); the GUI was not launched. - Key files read:
README.md,docs/gaps.md,docs/scorecard.md,docs/parity-checklist.md,docs/{control-protocol,mcp,file-format-parity,plugins,printing,batch-naming}.md,Cargo.toml,apps/photocraft/src/launch_args.rs,apps/photocraft-cli/src/args.rs,crates/engine/src/{cmd,actions_record,memory_gate,scratch,shell_commands,build_info}.rs,crates/engine/src/cmd/{gallery_cmds,file_cmds,export_preset_cmds,web_cmds,type_extra_cmds,cutout_cmds,updates_cmds}.rs,crates/engine/src/cmd/atn_cmds/events.rs,crates/engine/src/{filters,filters_ext}.rs,crates/ui-egui/src/state/tool.rs,crates/ui-egui/src/menus/parity.rs,crates/ui-egui/src/control/dispatch.rs,crates/ui-egui/src/i18n/,crates/doc/src/effects.rs,crates/color/src/blend.rs,crates/algo/src/{artistic,matting}.rs,crates/codecs/src/format.rs,crates/codecs/src/codecs/{tiff/,iff.rs},crates/io/src/{lib,camera_raw_xmp,tiff_layers}.rs,crates/io/src/smart_map/import.rs,crates/io/tests/it/corpus.rs,crates/format/src/manifest.rs,crates/raw/src/lib.rs,crates/automation/src/{server,server/conventions,rpc,security,budgets}.rs,crates/automation/src/workspace{,/tests.rs},crates/plugins/src/runtime.rs,crates/vector/src/shapes.rs. - Shared libraries:
storytold/craft-libs, all craft crates pinned to one revision inCargo.toml(craft-ui,craft-print,craft-docpath,craft-jpeg,craft-update); only the pinning relationship was consulted, not shared-library behaviour. - Per-claim evidence, the count methods and this round's corrections:
evidence.mdnext to this file.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

