Repository navigation
Releases: PSCatLabs/pscat
Release list
pscat 0.6.1
Features and changes
- Move to PSCatLabs/pscat: repository, homepage, Pages and marketplace URLs (#656)
- plugin: Codex local plugin from the same plugin/ directory (#569 part b) (#655)
- cli: pscat --version / -V (#637) (#653)
Documentation
- docs: install from crates.io and the release binaries (0.6.0) (#651)
Build, CI and release
- release: --version probe, provenance attestations, post-publish install check, Dependabot (#659)
Each archive carries the licences (LICENSE-MIT, LICENSE-APACHE, LICENSE-OFL), THIRD_PARTY_NOTICES.md and the dependency notices (THIRD_PARTY_LICENSES.html). SHA256SUMS has the SHA-256 of every archive; release-manifest.json records the commit they were built from. Install guide: https://github.com/PSCatLabs/pscat/blob/main/docs/guides/getting-started.md
pscat 0.6.0
The first release published outside this repository.
Highlights
- Install without a checkout:
cargo install pscatfrom crates.io, or a
prebuilt binary from the GitHub Release (macOS arm64/x86_64, Linux
x86_64/arm64 musl, Windows x86_64). PostScript libraries (lib/) are
embedded in the binary. - Font packs:
pscat fonts installdownloads the extras, TeX Gyre and
CJK/Thai packs from thefonts-2026.10release, checked against a SHA-256
pinned in the binary. - Subcommands:
pscat handwrite,pscat typewriteandpscat photo-etch
are built into the binary. - pscat-mcp declares its MCP protocol versions, enforces timeouts and size
limits, and confinesout_path. A Claude Code plugin bundles the skills and
the server. - Licensing: code is MIT OR Apache-2.0, embedded fonts are OFL-1.1, and the
art is CC0-1.0 (THIRD_PARTY_NOTICES.md). - Plus paint and dry media kits, the typewriter's released-document look,
mathkit additions, Level 3clipsave/cliprestore, and new gallery pieces.
Fixes
- Fix hollow centre when a tiny curve is stroked wider than its diameter (#170)
- Fix clippath to report the true intersection of nested clips (#120) (#131)
- Fix P2s from #103 follow-up: centered ticks, SAFER note, remove PLAN_103.md (#108)
- Fix Codex P1s from #103 follow-up (pie arc, scatter, setdvframe) (#106)
- Fix pkoil porad cursor corruption for multi-subpath strokes (#90)
- Fix ShowCtx's fixed unicode_mode: re-segment per glyph on mid-show font switch (#70)
- work-issue: fix crash-resume race + branch-name bug (#29); address #33 punch list (#34)
- Fix silent stroke-drop in --pdf-only export; add PDF document metadata (#8) (#23)
- Fix work-issue deadlock: crashed in-progress issues must resume, not halt
Features and changes
- fonts: pin fonts-2026.10 (#642)
- licence: mochi reference photo is CC0 (owner's photo, #606); owner-merge SDLC.md, work-issue, sdlcify, settings.json (#641)
- Interp: dropping an Interp frees systemdict/userdict (Rc cycle) (#632)
- plugin: Claude Code plugin and marketplace for the skills and pscat-mcp (#569 part a) (#634)
- mcp: out_path takes render extensions only, no dot-directories (#627) (#628)
- pscat-mcp: declared protocol versions, timeouts, size caps, confined out_path; skills/ for an installed pscat (#568) (#624)
- licence: art/ is CC0-1.0 (owner decision); mochi.jpg stays NOASSERTION (#606) (#619)
- licence: MIT OR Apache-2.0 code, OFL embedded fonts, CC0 art; notices, asset manifest, URW provenance, Cargo metadata (#608)
- released: a copy sends the typed ribbon's colour through the copier's curve (#597)
- typewriter: erode a copy's body by the glyph outline so thin strokes drop out (T15) (#594)
- released: multi-page overlays for rel-page, via a /PageEnd hook for tw-type (#589)
- typewriter: a clogged counter takes the bleed colour and the worn lane's weave (#539) (#588)
- released: a gem paper clip with a dent and a rust ghost, not three ellipses (#587)
- typewriter: /worn's /Ribbon is 0.55, so the worn elite weighs x0.76 of T10, not x0.66 (#520) (#586)
- released: a copy softens its stamps, notes and redaction bars (/Soften) (#582)
- typewriter: /MisStrike and /MisStrikeScale, the mis-strike rate and size as machine and typist traits (#584)
- landscape cookbook: regenerate grass.png thumbnail against its snippet (#535) (#583)
- typewriter: opt-in /BleedGap pin stripe; /WornBand and /Bleed docs say what is measured (#571)
- typewriter: the mis-strike's y tail is 2x, not 4x (the d in restricted) (#550)
- released: thin-stroke dropout under a photocopy (/Dropout) (#548)
- capabilities: module docs say parameters is generic, not paintkit-so-far (#544) (#553)
- typewriter: reference search for two-colour bleed, embossing, worn lane and electric pages (none found) (#552)
- image/imagemask: paint the ImageMatrix⁻¹ footprint, not the unit square (#546)
- released: a copy's haze mottle is a crumpled-paper wave, not soft blocks (#528) (#542)
- typewriter: ribbon ink extras, a worn band and two-colour bleed (opt-in) (#540)
- currentrgbcolor: round the readback to the f32's short decimal like gs; alpine_lake still regenerated (one pixel, one level) (#536)
- drykit: split a chunk past dkbudget, refuse a too-wide stroke before drawing (#324) (#537)
- released: a copy's haze grain is imagemask stencils at the scans' strength (#474) (#529)
- artkit: scin refuses a hand-built region that carries a procedure, with no per-call walk of built ones (#503) (#533)
- Evening Stream: the cloud bodies' wet edge asks the sky at each stroke (pkwet /PerFill) (#525)
- Alpine Lake: notes on pulling the plane-streak re-lay into the reflection (#508 measured; invisible) (#524)
- typewriter: elite takes the ribbon ink separately from pica (#511) (#522)
- pscat: a Type 3 BuildChar runs in its own gsave level, so cliprestore and grestore there give back the state at show (#500) (#527)
- pscat: currentcmykcolor, currentcolor, currentlinecap, currentlinejoin, currentmiterlimit, currentstrokeadjust, as gs does (#523)
- Evening Stream: the clouds' light load follows the sun's glow along each cloud (#462) (#521)
- pkwet: /Smooth calms a directional pull's across-wobble so its side edges stagger less (#517)
- grestore/grestoreall at the bottom or a save boundary, and currentgray, as gs does (#518)
- typewriter: a light strike thins, not only dots out (#514)
- alpine lake: the shadow planes' streaks read through the far mist banks (#476) (#509)
- identity_check: a file that fails identically in both trees is SKIPPED, not an ERROR (#507)
- typewriter: lighter ribbon ink, a wider spread of strike weight (#423) (#478)
- artkit: scatter and scarea check a hand-built region before using it (#295) (#506)
- released: a photocopy's paper keeps a grey haze, mottle and grain (/Haze) (#466) (#475)
- paintkit: pkwet's directional /Layers cap is 32; the canvas specimen's wet pull no longer bands (#417) (#485)
- mathkit: \mod and \pod, \nolimits on a brace, a column's wander, alignat, mkbrace (#480)
- paintkit: pkfan runs are cut into overlapping ribbons for pkwet /FillLength (#502)
- pscat: Level 3 clipsave and cliprestore, scoped per gsave level as in Ghostscript (#501)
- paintkit: pkwet /FillLength cuts a long loaded run into per-stop fills so /PerFill follows a gradient along it (#499)
- check_md_links: a ref must end at a boundary, so blob/mainline is not main (#481) (#498)
- pscat: .sameclip, a clip identity query; drykit sees a bound wrapper's grestore in a dkbatch (#488) (#496)
- drykit: shadow cliprestore inside a dkbatch where the interpreter has it (#454) (#495)
- paintkit: pkwet /PerFill asks the backdrop at each loaded-colour fill (#403) (#493)
- drykit: document why a bound wrapper's grestore can't be seen in a dkbatch, with three workarounds (#459) (#489)
- docs/site: recount the font catalog to 67 files (#437) (#473)
- paintkit: pkbrushedge /Under and /Mass take a region list (#456) (#464)
- typewriter: released-document look -- aging, photocopy loss, stamps, redactions (#214) (#452)
- drykit: keep a plain clip inside a dkbatch, one gstate per clip change (#444) (#457)
- paintkit: pkbrushedge /Mass, a pull-out colour that can follow the mass's gradient (#426) (#460)
- mathkit: braces, overset/substack, style switches, \not, \pmod, align columns (#340) (#440)
- pscat: Level 2 gstate objects, an exact clip capture (#394) (#447)
- drycharcoal: dhsmudge and dhlift run inside a dkbatch, drawn after it (#393) (#442)
- fonts gallery: Courier Prime and /Typewriter cards (#412) (#438)
- typewriter: tw-type layout API, memo header, scripts/typewrite.sh, docs (#213) (#432)
- typewriter: ribbon ink -- weave, feathered edge, clogged counters, pressure (#212) (#425)
- drykit: /drawing paper's mottle 6 -> 1.5, so charcoal hatching breaks up in specks (#313) (#419)
- strokeglyphs: redraw the digit 4 so it no longer reads as a lightning bolt (#351) (#411)
- Specimen polish: canvas weave wanders, knife pulls lose the tape look, handscript 7 (#298) (#421)
- typewriter: the /Typewriter Type 3 font with machine, line and strike variation (#211) (#409)
- typewriter: reference board and design writeup (#210) (#341)
- paintkit: pktrowelplane bounds its area outline by wkmaxsegs (#401); reword stale pwsrand note (#397) (#406)
- claim.sh: move-free generation lock, no double claim in the transit window (#297) (#405)
- paintkit: pkwet /Box and /Bands, a backdrop per band (#359) (#404)
- paintkit: pkscanclosed carries walkpath's segment bound (pkribbon/pknib/pkfeather) (#299) (#402)
- srand: --sweep-seed leaves an rrand restore alone, so Alpine Lake's reflection matches (#202) (#400)
- sdlcify: quality gate matches what ci.yml runs (#216) (#398)
- Bind drycharcoal: } bind def on every procedure, checked by libbind (#326) (#399)
- paintkit: @summary of pkfan, pkbroad and pktrowel names the loaded colours (#291) (#396)
- drykit: dkclip lets a dkbatch hold strokes under different clips; dhhatch joins a caller's batch (#312) (#395)
- paintkit: pkbrushedge/pkfeather skip edges hidden inside overlapping blobs (#381) (#392)
- tests/landscape_cookbook: give the per-recipe CPU budget CI headroom (2 s to 5 s) (#387) (#391)
- strokeglyphs + mathkit: ASCII * in \text, \mathrm and \operatorname is a raised text asterisk (#378) (#390)
- landscape cookbook: light the far wood's crest with pkscumblein /Light (recipe 5) (#383) (#389)
- tests/mathkit: give the specimen's CPU budget CI headroom (2 s to 5 s) (#388)
- paintkit: light-aware massing, a lit side on a scumbled region (pkscumblein /Light) (#345) (#385)
- paintkit: pkbrushedge and pkfeather, a brushed edge for filled masses (#347) (#379)
- mathkit: ASCII * is \ast, so z^* and A_* lay out (#364) (#380)
- paintkit: pkpull /Scatter offsets each stroke start across the spine (#346) (#377)
- mathkit: UTF-8 delimiters after \left, \right and \big (#365) (#376)
- pktrowelplane: space the rows for the thinnest a tapering /Pressure gets (#362) (#375)
- s...
Font packs fonts-2026.10
pscat font packs fonts-2026.10. Install with pscat fonts install --version fonts-2026.10, or plain pscat fonts install with a pscat release that pins this index. Each pack carries manifest.json with every file's licence, copyright and SHA-256; SHA256SUMS covers the packs and font-index.json.
v0.5.1
v0.5.0
Known bug, fixed in v0.5.1: pscat invoked via a symlink (e.g. ln -s .../pscat ~/.local/bin/pscat) fails to find lib//fonts/catalog/. Use v0.5.1 instead.