Releases: ostapondo/Plonk
Release list
Plonk 0.4.1
Changed
- Reduced idle CPU use for pointer tools: event taps now subscribe only to required events, crosshair redraws are coalesced, and drag monitors stop when disabled.
- Made background watcher teardown deterministic to avoid duplicate observers, timers, and stale queued UI work.
- Screen-aware API routes now reject monitors that are not attached instead of saving unreachable configuration.
- Window snapshots use typed internal models, and Accessibility values are checked before casting.
- Agent adapter processes now run outside the main thread and safely drain verbose stderr output.
Verification
Built from 6a90add3d7ad148ddff1c7992d4620cbfaed7552 by the release workflow.
gh attestation verify Plonk-0.4.1.zip -R ostapondo/Plonksha256: dfecd81a0e4e791843fbc0ff2630c0b8beefba639d267f82e088a9cc12f31c7f
Plonk 0.4.0
Added
- The windows go back after a display change, not only the ones Plonk
placed. Where each window on screen sits is noted as windows move, per
set of monitors, and put back when that set of monitors returns: unplug
the desk, work on the laptop, plug it back in, and the desk is as it was.
A window Plonk placed that the note has no line for still returns to its
zone. A switch under When the desktop changes, on by default beside the
one that was there; apps on the exceptions list are left alone as ever. - The zones can be clicked. Hold
⌃⌥Zand every screen's zones stay up;
click one, or press its digit while holding, and the front window goes
there. Let go and they linger a moment, still clickable. A tap is the
flash it always was. The overlay never takes focus, so the window that
was in front stays in front. - Shake a window to see the zones. With the modifier required, wiggle a
window sideways while dragging it and the zones come up anyway, for the
rest of that drag. A switch on the Zones page, off by default. - The click ring is yours to set. Ring every click was one colour, one
size, one shape: the zone colour, 34 points, an outline. Pointer and clicks
now says how it is drawn — a colour of its own, a second colour for right
clicks so the two can be told apart in a recording, a ring or a filled dot or
both, how wide it lands, how heavy its line is and how long it lasts. The
crosshairs get the same treatment, with a colour, a thickness and an opacity,
and finding the pointer gets the size of its circle and how far the rest of
the desk dims behind it. Everything left unset still follows the zone colour,
so a setup that was never touched looks exactly as it did. - An app can be told where its windows open. Where apps open, on the
Zones page: pick the app, a zone, and if it matters the monitor, and every
window it opens from then on lands there. A rule is written down, so it
outlives a relaunch where the habit of "where the last one went" does not,
and it wins when both apply. Agents getset_app_ruleandclear_app_rule,
andget_statelistsapp_rules. - Empty zones can fill themselves. A switch under When the desktop
changes: a window that opens on a screen with a free zone goes into the
first one. Most of what a tiling manager does, without it taking over the
windows you placed yourself. Off by default, like the habit beside it.
Both, and the habit, now leave dialogs, sheets and panels where they open:
only a window in the ordinary sense is placed, and hidden apps or windows
on another Space no longer count as holding a zone. - The MCP server reports its installed version. Run
plonk-mcp --version
orplonk-mcp -vto print the package version without starting the server. - Throw a window to the next display, grow it, shrink it, cycle a half.
⌃⌥⌘→and⌃⌥⌘←send the front window to the next or previous display,
into the same zone number where that display has one.⌃⌥=and⌃⌥-
grow and shrink it by 30 points about the centre, with a side against the
screen edge staying put.⌃⌥←on a window already in the left half takes
two thirds, then a third, then the half again, and the other three halves
do the same; the Keys card on the Zones page turns the cycle off. Keys,
names and cycle are Rectangle's, so they import with the rest, and the
next-displayURL is answered rather than refused. Out loud: "throw it to
the next screen", "make it bigger". - A zone can have a name. Give one to any zone in the editor — chat,
editor, build log — and it is drawn under the number in the overlay, on the
Zones page and beside the zone's shortcut. Then "put this in chat" works
out loud, on the screen the front window is on, and an agent can hand
snap_windowthe name instead of the number. The number keeps working;
a set with no names loses nothing. Zone sets inzone-sets/may carry
names too, and Call and Work now does.
Changed
- Every settings page is drawn the same way. Four pages — Zones,
Workspaces, Appearance and Home — had rolled their own scroll, margins and
spacing, so cards sat on a different rhythm depending on which sidebar entry
you came from. They share one now. Zones and Appearance gained the heading
and the line of description every other page already had; Workspaces keeps
its own, drawn by the same code as the rest. - One shape for every measurement. A number with a range — the zone gap,
edge spanning, the overlay's opacity, the ruler's sensitivity — is now one
row: the name, a knob and the exact value, with the explanation on hover.
Three different shapes were doing this, one of which took three lines per
number and one of which showed no value at all. Opacity reads as a
percentage rather than as nothing. - A switch that is off hides what it governs. Turning off "Grab a window
anywhere" used to leave its three settings on screen at half brightness,
costing the same room switched off as on. They are put away now and come
back when it is switched on; nothing is forgotten in between. - Choosing a zone colour no longer shifts the rows under it. The line
under Colour says where the colour comes from in both states instead of
appearing only while none was set. - A numbered zone's shortcut shows the zone. Zone 1 to Zone 9 all carried
the same grid glyph, which said nothing that "Zone 5" had not already failed
to say. Each row now draws the set that is actually on your main screen, with
its own zone filled and the rest outlined round it, the same way Left Half
draws a left half. A number the set has no zone for draws an empty screen,
which is what pressing it does. - A zone set's shortcut carries the set. Zone set 1 to Zone set 9 shared
one glyph and one generic name. Each row now draws the arrangement it
applies and calls it by the name you gave it, falling back to "Zone set 7"
only for a place the list does not reach. - Flashing the zones is filed with the zones. It sat under "Halves,
quarters and the rest", among the shortcuts that move a window; it moves
none. It is at the top of Numbered zones now, where it is the way to see
which number is which before pressing one. - Shortcut lists flow into columns. A shortcut is a thumbnail, a name and
a key — 300 points of content — and a full-width card gave each one the
whole window, names staring at keys across a gulf of nothing. Rows now flow
into as many columns as the card is wide: one on a narrow window, two or
three on a desk — and each row sits on a surface of its own, so a key reads
with its shortcut rather than with the neighbouring column's name. Every
page with a shortcut list gets this, the Keyboard page included — which is
also one card in sections now, like the Zones page, instead of a dozen cards
in a scatter. - A shortcut recorder looks like something to click. It has a border now
whether or not it is recording; a flat pill in a column of eleven read as a
label. - The Zones page puts its settings first and its shortcuts last. Which
zones the screen has, the two ways to drop a window into one by hand, then
how it all behaves — the overlay, display changes, the apps left alone. The
keys close the page under a labelled rule of their own, as one card in four
sections rather than four cards in a scatter, each section's explanation
right under its rows. They are the longest thing on the page and the least
often changed.
Fixed
- An invalid click-ring style in a hand-edited config repairs itself. The
overlay already drew a ring for an unknown value, but the settings picker
showed no selected style and the invalid value was saved again.
Built from 7768b8bae9ff00b46f8a04394c28fabc9a155062 by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.4.0.zip -R ostapondo/Plonksha256: 929dc8e07a52dfc6c1fc54d8bcfdce8d2dd358420dce4930aa1422cd71d5c752
Plonk 0.3.5
Changed
- Keep awake and Stay active are one feature, called Pulse. They were never two: a power assertion stops the Mac sleeping without touching the idle counter Slack and Teams read, so keep-awake alone still left you Away, and resetting that counter postpones sleep, so stay-active always implied keep-awake. Two switches for one thing, one of which quietly did the other's job. Now there is one session with a level — hold the Mac up, and optionally hold your chat status at available with it — and every way of starting one works at either level. The schedule and the watched apps used to arm only stay-active; a process binding used to end only keep-awake. All of them now start and end the one session, so
set_awakewith apidcan keep you available for exactly as long as a build runs.- Your setup carries over. A schedule or a watched-app list from Stay active comes across as it was, and turns the level on, unless the feature had been switched off in Tools. The two settings that existed twice — allow on battery, turn off after — keep their keep-awake values; check them if you had them set differently on each page.
set_activeis gone.set_awaketakesavailableinstead, and reportsavailablebesideawake./statereports oneawake_detailswith the schedule and the apps in it;activeandactive_detailsare gone, andactiveis no longer a switchable feature indisabled_features.
- Everything that starts a session by itself is in one card. The schedule, the watched apps and the charger were spread over two cards and a third page's Power section, and the app list armed itself by having anything in it, which read as though the schedule and the apps were two halves of one rule. They are three independent reasons: each has a switch, and the card says the rule out loud — any one of them is enough, and the session ends when the last one lets go. An app list can now be kept while switched off, the way the schedule keeps its hours.
- The screen numbers only appear when you ask for them. Opening the Zones page or moving the screen selector used to flash every display's number over whatever was on it. Preview does that now, and it draws each screen's own layout on it at the same time, so one press answers both which monitor is which and what is on it.
Built from a45664b349cd26117e560e94cbae0b36fda81bf7 by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.3.5.zip -R ostapondo/Plonksha256: dd4e2311abf244970fb11576103d66c3d7e4283f4d659d9ff949a22f18ba53e7
Plonk 0.3.4
Added
- Keep going with the lid closed. A switch under Awake > Power that stops the Mac sleeping when the lid is shut, so music keeps playing, a download keeps going and an ssh session stays up. Sleep on lid close is a forced sleep that no power assertion holds off, so this one turns system sleep off outright and asks for your password once. A root guard puts it back when you switch it off, and within a minute of Plonk being gone for good; it outlives a relaunch, so an update does not ask again. The menu bar cube goes half red while the hold is on, and
/statereportslid_closed. - Which monitor is which, said on the monitors. Opening the Zones page or moving the screen selector flashes the display's number and size on the display itself, the selected one in the zone tint. Picking "screen 2" in a settings window is no longer guesswork.
Fixed
- A divider stays where it is dropped. Dragging one used to round every zone to a twentieth of the screen on release, which on a 5120-point display is a 256-point jump away from the pointer, and made half the positions on the screen impossible to ask for. Dividers are now pulled onto halves, thirds, quarters and the edges of neighbouring zones from within twelve points, and left exactly where they are put otherwise. The pull happens under the pointer, so what you see while dragging is what you get.
- Splitting a zone left and right no longer needs a modifier. The right button does it: left click cuts a zone into top and bottom, right click into left and right. ⇧-click still works, and works more reliably, now that the invisible view reading keys in the editor has stopped swallowing right-button clicks before the canvas could see them.
Built from a39c7ca1f201391e9e2d769f08ae33c0ac15d5cb by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.3.4.zip -R ostapondo/Plonksha256: 3ef99720400bc706c755154b5375398f9c269c0f7db37c9f882ce8a64720b709
Plonk 0.3.3
Drafted by CI. Replace this with the release notes before publishing.
Built from c209405990967c9bd7613bf2e9965bcd0642ed97 by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.3.3.zip -R ostapondo/Plonksha256: 6cf3bdb2913b99f4a30b32705443f8592ba1c41c24c70d00684747c7179a33ef
Plonk 0.3.2
Drafted by CI. Replace this with the release notes before publishing.
Built from 0d276a4ac1b0bbd9e36dce2488e87f18d4f6f3b5 by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.3.2.zip -R ostapondo/Plonksha256: 3f463382a1852daf5c45cf92101afd79720c05b4979db26111305172dc774e6c
Plonk 0.3.1
The window, redrawn: the sidebar is a dark panel set into the window, the
page comes forward, and narrow windows stop breaking. Two fixes ride along:
a single click no longer moves your windows, and snap_window picks the
window the same way it looks for it.
Changed
- The window has been redrawn. The sidebar is a dark panel set into the
window, the page's cards sit a step lighter on the ground between them, and
the bar over the page is gone: the menu says where you are and every page
opens with its own title. The menu carries the zone palette, one hue per
destination, with the ⌘K search under the traffic lights, workspaces as
coloured dots and connected agents as a line in the footer; permissions
only speak up when one is missing. Light mode gets the same three steps as
dark. Narrow windows stop breaking: two-column blocks collapse, the zone set
header drops its buttons under the title, shortcut names truncate instead of
folding into a column, and a text field beside a button gives way instead of
the button.
Fixed
- A single click no longer moves your windows. Clicking a workspace in the
sidebar launched it on the spot, and clicking a row in the zone set palette
swapped the layout and relaid out every window on the screen. Both were one
stray click away from a mess. The sidebar row now opens the Workspaces page,
where each workspace has its own Launch button; in the palette a click only
moves the highlight, and return, a digit or a double click applies it. snap_windowwith a title that matches nothing no longer reports the app
as not running. Placing a window into a zone by app and title, without
naming a screen, looked for the window one way and moved it another: the
screen lookup gave up when no title matched, while the move fell back to the
app's front window as documented. Both now pick the window the same way.
Built from 3ac2f8b680ee15327a9537c4c0a0688d0a11121b by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.3.1.zip -R ostapondo/PlonkThe attestation is also on this release as Plonk-0.3.1.zip.sigstore.json.
sha256: 6e7ee562acd0a857e9ecf6d94a73eb5b402de7ab87389386c213445a1af0c4e0
Install: brew install --cask ostapondo/plonk/plonk
Plonk 0.3.0
The first minor since 0.2. Rectangle users can bring their bindings across,
the zone sets can be seen as a list, there is a ruler for the screen, and the
app can keep a Mac awake through a meeting. Under it, every string moved into
one catalog and a hand-edited config is held to the same limits as the sliders.
Added
-
Switching from Rectangle costs nothing now. The ten placement shortcuts
were already the same keys in both apps —⌃⌥and an arrow, a corner letter,
return or C — because that is the one combination macOS leaves alone and both
landed on it. What was missing was everything either side of that: a changed
binding had to be re-entered by hand, and arectangle://execute-actionURL
sitting in a Raycast script or on a Stream Deck button did nothing at all.Plonk looks once at launch, and a Mac with a Rectangle setup on it gets the
offer on the Home page rather than a button on a settings page nobody opens
first. Taking it or turning it down settles it for good, and a Mac with no
Rectangle is shown nothing.Shortcuts → Import from Rectangle reads the preferences of an installed
copy, or aRectangleConfig.jsonexported from an old machine, and takes the
bindings that mean the same thing here: the halves, the corners, maximize,
centre, restore, and the window gap. Rectangle's thirds, sixths, eighths and
ninths are deliberately left behind and named instead of imported. They are a
fixed grid; the equivalent here is a zone set, and there is no way to know
which numbered zone a "first third" should be without knowing what set that
screen is wearing. If an imported key was already doing something —⌃⌥T
copies text out of a region — the imported binding wins and the app says what
lost it, and a Rectangle whose bindings are all fixed-grid is told apart
from one that is not there at all.URLs answer to the same verb and the same names:
open -g "plonk://execute-action?name=left-half". The ten placements are
spelled exactly as Rectangle spells them andrestoreis accepted alongside
unsnap, so an existing script is onesedaway. Past that the vocabulary is
this app's own:zone-1tozone-9,zone-set-1tozone-set-9,
cycle-zone,focus-left,capture-text,ruler, and one name for every
other shortcut. Asking for a fixed-grid action, or fornext-display, says so
on screen rather than failing quietly — the nearest thing tonext-display
here moves the pointer and not the window, and answering to the name while
doing something else would be worse than not answering.rectangle://is declared as well, but answering it is a switch on the
Shortcuts page and it is off. A scheme belongs to one app at a time, so
turning it on takes those URLs from an installed Rectangle and its own stop
working, with nothing to say so. Off is not passive: declaring a scheme is
enough for macOS to hand it over on install, so arectangle://URL arriving
while the switch is off makes Plonk give the scheme back to Rectangle and run
that one URL anyway. The switch reads its state back from macOS rather than
from config, so it shows what is true rather than what was asked for.docs/from-rectangle.md is the whole of it, including
what happens when both apps are running and hold the same key. -
Stay active, a page of its own under Settings, for the thing keep-awake
was never able to do: stop Slack and Teams showing you as Away. They do not
ask whether the Mac is asleep, they ask how long it is since the last
keypress, and a power assertion does not touch that number. Stay active
resets it with a Shift every two minutes. Run it by hand with a timeout, on a
schedule of hours and weekdays, or while a chosen app is open. The schedule is
read from the clock rather than fired by a timer, so a Mac that slept through
09:00 and woke at 11:00 is inside the window rather than waiting for tomorrow,
and a window may cross midnight. Off on battery unless you allow it, and it
needs Accessibility — without the permission the page says so instead of
quietly sending nothing. Agents getset_active. -
The zone sets, as a list you can see.
⌃⌥Ldraws every set available for
the screen the cursor is on, each one as a small picture of itself, with the
one that screen is wearing marked. Arrows or the digit picks,returnputs it
on the screen,Eopens it in the fullscreen editor,Nstarts a new one,
Escape leaves everything as it was.⌃⌥⇧1–⌃⌥⇧9already swapped a set, but only for someone who remembers which
set is number four. The digits in the list are those same numbers, so the list
is also the thing that teaches them. Editing from here duplicates a built-in
template first, exactly as the Zones window does, so the shipped sets stay
intact. -
A ruler for the screen.
⌃⌥R, then hover: Plonk photographs the screen
once, walks out from the pointer in all four directions until one pixel is
unlike the one beside it, and draws each run as a dimension line with its own
number. That is the width of a row, the height of a bar, the size of the gap
between two things, without anybody aiming a drag at a corner. Drag instead
and it measures a straight line. Points and pixels both, because a 44-point
tap target is 88 pixels and only one of those numbers is in the asset. A click
copies,Spacetakes a fresh picture of the screen, Escape ends it.Two numbers on two lines rather than a box: the run across and the run down
are separate answers, often about different things, and a rectangle drawn
round them would claim they are the sides of one object — the one thing
pixels cannot say.Borrowed from PowerToys' Screen Ruler, tolerance setting included, on the
Ruler page under Capture. Ten out of 255 suits an interface: gradients and
shadows step by less, borders by more. Raise it for a photograph or a video,
where every pixel differs a little from the last. -
measure_screenfor agents, andplonk measurefor a shell. The same
measurement without a person: hand it a point and it answers with the two
runs through it, or two points and it answers with the distance. The reply
carries the points, the display's own pixels, and the fraction of the screen
ready to hand back toapply_layout. An agent that would have taken a
screenshot and guessed at sizes can ask for the number instead, at a fraction
of the tokens.interactive: truehands the ruler to the user and waits for
what they measure. Needs Screen Recording, like every other capture.
Changed
-
A hand-edited
config.jsonis held to the same limits the sliders are.
A gap of 100, an opacity of 0.02 or an edge span of 200 used to be honoured
verbatim and could leave zones you could not see or windows with nothing left
of them. They are now brought inside the same bounds on load, wherever the
value came from. Nothing else about the file changed: it is written exactly
as before. -
A
nullinconfig.jsoncosts you that one setting, not all of them.
Any field written asnull— by hand, or by a tool that spells "unset" that
way — used to make the whole file unreadable, which set it aside and reset
every setting, workspace and zone set you had. It now reads as "not set" and
falls back to that field's default, which is what a missing key has always
done. -
The window looks like the rest of Plonk now. Colour is the zone number
everywhere it is drawn, so the sidebar, the Zones page, the website and the
README all say the same thing the same way. The sidebar lists every page under
the heading it belongs to instead of hiding ten of them behind groups that
expanded, the selected row is the accent rather than a grey fill, and the
Zones page opens with the set named in full, what it is running under it, and
each zone printing the fraction an agent would send for it. -
The README and the docs dropped the screen recordings that still showed
the old single-accent overlay. What replaced them is drawn to the same palette
as the app, so a picture cannot go stale the next time the interface moves. -
Every word the app says now lives in one file. The text was written into
the views that draw it, spread across sixty-odd Swift files, which meant a
second language would have had to start by unpicking all of them. It is a
string catalog now —Resources/en.lproj/Localizable.strings, with counted
things inLocalizable.stringsdictso plural rules belong to the language
rather than to the code — and the source holds keys. Adding a language is one
new folder beside the English one and no Swift at all.Nothing looks different, and that is the point: this is the groundwork, not
the translation. Two things did have to change underneath. A shortcut's group
("Halves", "Numbered zones") was both the heading on screen and the value the
pages filtered on, so translating it would have quietly emptied those lists;
the two are separate now. And a handful of sentences are read by a person and
by an agent both — the update status, the keep-awake status, why an app in a
workspace did not land — so those reach the API in whatever language the app
is running in. Every machine-readable field beside them is untouched: ids,
route names andphasestay English, because that is the half a client
actually branches on.The two permission dialogs macOS draws are covered too, through an
InfoPlist.stringsbeside the catalog, since Info.plist itself cannot be
translated.
Fixed
- An update check that failed offline runs again when the network is back.
It stopped at "The update check failed: The Internet connection appears to be
offline", and that is where it stayed: nothing watched for the network
returning, so the next attempt was the daily timer or the Check Now button. A
copy launche...
Plonk 0.2.5
Two fixes, one of them a setting that only worked when a person asked for it.
The same zone gave an agent a different frame than the keyboard did, so the
zone gap looked broken to anyone driving Plonk over MCP.
Fixed
-
The zone gap applies when an agent drops a window into a zone.
⌃⌥3left
the gap around the window andsnap_windowdid not, so the same zone gave two
different frames depending on who asked for it. Both paths now compute the
frame in one function,ZoneGeometry.frame, so they cannot drift apart again. -
The main window's header sits at the top edge again. The title bar is
hidden so the app draws its own, but the hosting view still reserved the
height of the one it hid: every page opened under an empty strip.
Changed
- README and CONTRIBUTING are shorter. Roughly a fifth off each. Install
moved above the feature tour.
Built from 5c372cf2644039a9b4c08c5a882dd6f08ac3709b by this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.2.5.zip -R ostapondo/Plonksha256: e5715abcb64d6ffc2fa742ccfb9de095c8da569c5b945a868c8d9a08254292f3
Install: brew install --cask ostapondo/plonk/plonk
Plonk 0.2.4
The command palette got a key of its own, an agent can photograph a window it
names without disturbing it, and Claude Code installs the whole toolset in two
commands.
Added
⌃⌥A opens the command palette over whatever is in front of you. The
palette already existed and could only be opened from inside Plonk's own window
— the one place you are not standing when you want to move a window. Pressing
the key again closes it.
Type a sentence into it and it goes to your agent. Anything that is not a
command — "put the browser left and the terminal top right", "save this as a
workspace called review" — can be sent as it is, with ⌘return or by picking
the last row. It takes the same road a spoken command takes, so it can reach
nothing a key could not.
An agent can screenshot a window it names, even a covered one.
take_screenshot grew a mode: "app", taking app and title_contains: "what
is playing in Spotify" now works with Spotify hidden behind the editor. macOS
keeps every window's image apart from every other's, which is what makes a
buried one photograph cleanly — nothing is raised and no focus is taken.
Claude Code installs the tools in two commands.
/plugin marketplace add ostapondo/plonk
/plugin install plonk@plonk
The repository is its own marketplace, so there is no config file to find. It
needs the app installed — the server is a bridge to a loopback API and does
nothing on its own.
Fixed
⌘C, ⌘V, ⌘X and ⌘A work in Plonk's text fields. They never had, anywhere in
the app: AppKit delivers those through the main menu's key equivalents, and
Plonk had no main menu at all, so a field would take a typed sentence but not a
pasted one.
A prompt sent to an agent shows what it is doing. A CLI adapter takes tens
of seconds and moves nothing until it has decided what to move, so the palette
closing was followed by silence — which looks exactly like nothing happening.
There is now a ticking count while it runs, and it ends on how it went. A
failure used to be an NSLog nobody reads.
The changelog has
the rest, including new animations in the README and the docs.
Install
brew install --cask ostapondo/plonk/plonkOr Plonk-0.2.4.zip by hand, and plonk-0.2.4.mcpb for Claude Desktop.
Built from d8dcc422b7109a75a0a1f8cef36f5223cebe2c1c by
this run.
Verify it against that commit before installing:
gh attestation verify Plonk-0.2.4.zip -R ostapondo/Plonksha256: 9a6d7cdbfd4f5873410db46a2cfb2497640166b9f7a6fe09b96451950d9178d2