Skip to content

Releases: promptityourself/piy-dial-countdown

5.0.0 — Dial It Countdown, the first release

Choose a tag to compare

@cicmorgi cicmorgi released this 11 Oct 08:45

The first release of Dial It Countdown: countdown timers for Stream Deck dials and keys, from
Prompt It Yourself.

Added

  • A countdown timer on every dial and every key. Each control keeps its own timer, its own
    presets, its own colour theme and its own display.

  • The dial: turn for seconds, push the dial in and turn for minutes, press to start or pause.

  • Three gestures, the same on the touchscreen and on a key: tap to pause or resume, tap twice
    to reset to full, hold to put the clock right and then to go to the next preset.

  • A preset can be a list. Type 40, 10, 10 and each step starts when the last one ends. Up to
    twenty steps, each from one second to twenty-four hours.

  • An alert at the end of every step. A press silences it and does nothing else. The dial
    shows a bell and a key says ringing while it sounds.

  • Seven colour themes, a ring or a bar on the touchscreen, a name for each timer and the
    finish time on screen.

Internal

  • A new plugin, not an update of Dial Countdown. It has its own identifier,
    com.promptityourself.dial-it-countdown, and its own Marketplace listing, so nothing carries
    across from Dial Countdown: its users place the actions again and type their presets again. The
    code is Dial Countdown 4.5.0 under the new identifier. Dial Countdown stays on its own listing,
    frozen at 4.5.0, and its settings panel points here.

  • One test holds every copy of the identifier to the manifest. test/identity.test.ts
    checks the folder name, both action identifiers, the two @action decorators, and the build,
    release, icon, mock-host, version and CI files. It goes red if one copy is left behind.

  • docs/releasing.md records all three identifiers — the original one (spent when its listing
    was deleted), -v2 (frozen at 4.5.0), and this one — and why a rename alone never justifies a
    new one.

4.5.0 — the last release of this plugin

Choose a tag to compare

@cicmorgi cicmorgi released this 11 Oct 08:39

The last release of this plugin. Dial It Countdown carries on as a new plugin with its own
Marketplace listing.

Changed

  • The plugin says it has moved. The settings panel opens with a notice: install Dial It
    Countdown
    from the Marketplace, because this plugin gets no more updates. The listing
    description says the same. Every timer, setting and button keeps working as before.

  • The name is Dial Countdown again. 4.4.0 renamed it to Dial It Countdown, but that name now
    belongs to the new plugin. With both installed, the actions list shows two different names.

Internal

  • The diagnostics report and the release page read the plugin's name from the manifest, as they
    already read its version. The name changed three times in two days, and each change had to find
    every copy.

4.4.0 — the plugin is now called Dial It Countdown, and its mark is D|C

Choose a tag to compare

@cicmorgi cicmorgi released this 11 Oct 04:38

Changed

  • The plugin is now called Dial It Countdown, and its mark is D|C. The actions list, the
    category and the property inspector say Dial It Countdown. An idle clock shows the D|C mark in
    the middle of its ring, and every icon is drawn from it. It is the P|Y mark of Prompt It
    Yourself, the same letters' face and the same cursor, with the plugin's own initials. The brand
    is still Prompt It Yourself: the author, the colour theme and the links do not change.

    Nothing else moves. The plugin keeps its identifier, so every installed copy updates in place and
    every configured dial and key keeps its settings.

Internal

  • The mark is assets/dc-mark.svg, replacing assets/piy-mark.svg. It is built by the recipe
    that builds P|Y, motion/brand.mjs in mergodon/piy-short-production: Fira Code Medium, its
    glyph grid at +35% letter spacing, and the cursor 15% past the capitals. The same recipe run on
    P and Y reproduces the old file byte for byte, so the two marks are siblings and not a redraw.
    render.test now fingerprints the D.

  • A release title keeps its capitals. npm run release lowered the whole headline, so the 3.9.1
    and 3.10.0 titles said "stream deck" and 4.3.0's said "prompt it yourself". It now lowers only the
    first letter. The three published titles were corrected by hand.

  • The licence and the README's trademark line now name Prompt It Yourself. 4.3.0 missed both:
    the search that should have found them used ? in a basic regex, where it matches a literal ?.

4.3.0 — the plugin now carries the Prompt It Yourself brand

Choose a tag to compare

@cicmorgi cicmorgi released this 10 Oct 01:13

Changed

  • The plugin now carries the Prompt It Yourself brand, which replaces Mate Wish Key. An idle
    clock shows the new P|Y mark in the middle of its ring, and the icons in the Stream Deck
    application, on the keys and in the preferences are drawn from the same mark. The author is now
    Prompt It Yourself, and the plugin's website link goes to
    promptityourself.com.

  • The brand colour theme is now called Prompt It Yourself. Its colours did not change. A
    dial or key already set to the old Mate Wish Key theme moves to it on its own, and does not
    fall back to the default.

    Nothing else moves. The plugin keeps its identifier, so every installed copy updates in place and
    every configured dial and key keeps its settings.

Internal

  • The repository is promptityourself/piy-dial-countdown, renamed from mwk-dial-countdown.
    GitHub does not redirect every old link — an issue under the old name returns 404 — so every link
    in this file, the docs and the published release notes was rewritten to the new name. Release
    pages are now written to pro-piy-dial-countdown/ on the shared drive, since the folder is
    derived from the remote; the pages already cut stay where they were.

  • A test can import the action subclasses now, and does. The blocker was never the Stream Deck
    SDK — it imports in under a tenth of a second and needs no connection. It was that the tests ran
    on Node's type stripping, which erases types and leaves @action decorators standing, so
    importing either subclass was a SyntaxError. test/ts-resolve.mjs transpiles through
    TypeScript's own compiler instead — the one rollup already uses for the shipped bundle — and
    test/actions-live.test.ts drives the real DialCountdown and KeyCountdown through their own
    events: rotation, the press that did not turn, the release with no press, the hold on the knob,
    the tap on the glass, the key's double-press window, and a step running out and being silenced
    while the next one keeps counting. Closes the gap #12
    was opened on.

    Reintroducing the 4.1.0 bug — the ringing flag set and nothing rendering it — now fails two of
    those tests as well as four in test/frame.test.ts. This commit leaves the packaged plugin
    untouched — its own source edits are comments, which minification strips.

    The 2ca616ec… that stood here was the wrong baseline. That is what v4.2.0 shipped, and the
    refactor above had already moved the bundle off it, so the id was stale the moment it was written.
    Measured since: v4.2.0's published asset is 2ca616ec…, and everything from the refactor onward
    builds 530160038f…, differing in bin/plugin.js alone and by 46 bytes. Nothing a user can see
    changed, so this still is not a release — but the claim that the bytes were identical was false,
    and that claim is the one the release rule turns on.

  • What each control puts on screen is now a value, in src/frame.ts, and is tested directly.
    Both draw methods built their payload inline, inside classes no test can import — the @action
    decorator survives type stripping — so nothing about what the user actually sees was reachable.
    The scripted demo covered part of it and could never cover this part: a Linux box has no audio
    player, so no alert rings here and nothing downstream of one runs. That is how 4.1.0 shipped with
    a ringing state that existed in the code and appeared nowhere on the screen, through a green suite
    and a green demo.

    test/frame.test.ts asserts the frame being sent rather than the flag behind it. Reintroducing
    the 4.1.0 bug exactly — the flag set, nothing reading it — now fails four of its tests. No
    behaviour changed, so this is not a release; it travels with the next one.

  • The release page is one folder per version again, named for the version and not the day. It was
    <date>_v<version>, so cutting the same version twice across midnight wrote a second folder beside
    the first, with nothing in the index to say which was current. That is not cosmetic: mate has the
    only hardware and opens these by browsing the index, and 2026-09-20_v4.1.0 described a design —
    a Keep ringing until pressed checkbox, no hold on the knob, alerts only at the end of a job —
    that had been replaced by the morning of the 21st. A re-cut now overwrites the page in place. The
    date is still on the page, under the title, where it cannot multiply. Folders cut before this keep
    their names so the links in old issues still resolve. Closes
    #19.

  • A failing test no longer takes the whole suite down with it. The render loop is a 4 Hz
    setInterval that nothing unrefs, so an instance left running holds the event loop open and the
    test file never finishes — --test-timeout does not catch it, because the test itself completed.
    Teardown at the end of a test body cannot prevent that: a failing assertion throws before the line
    is reached, so exactly when a test has something to report is when it hangs instead. The rule was
    written in CLAUDE.md and in the file's own header, and followed by two tests out of thirty-seven.

    It cost a real CI run: on 2026-09-21 a timing-sensitive precondition failed and the job sat silent
    for fourteen minutes until its 15-minute ceiling killed it, taking the assertion detail with it.

    driver(t) now registers the teardown itself, so the next test added is covered by having been
    written at all. Breaking that assertion on purpose used to hang past a 90-second ceiling; it now
    fails in 2.4 seconds with actual: 2, expected: 99 on screen.

  • The test that failed was one late tick from failing on any loaded machine. It waited 1,200 ms
    for a 1 s step, but a step boundary is only noticed on a render tick — those are 250 ms apart and
    can only ever run late, so the margin was 200 ms against a 250 ms tick. It waits 1,500 ms now.

4.2.0 — you can now see that it is ringing

Choose a tag to compare

@cicmorgi cicmorgi released this 21 Sep 09:58

Added

  • You can now see that it is ringing. The dial draws a bell in the middle of its ring, and a key
    says ringing on its one line — a key cannot have the bell, because the middle of a key is where
    its clock is drawn. It is there for as long as the sound is, and gone the moment the sound is,
    whether you silenced it or it ran out on its own.

    The bell outranks whatever the clock itself is doing, and that is the whole point of it. On
    40m, 10m, 10m the forty runs out, its alarm starts, and the first ten starts counting in the
    same breath — so the timer is running, and until now the screen showed you a running timer and
    nothing else. It was true and it was no use: the thing to know is that there is a noise and that a
    press will take it away.

Fixed

  • A frame is now compared against what is actually being drawn, rather than against a hand-written
    list of the things a frame was thought to depend on.
    Nothing failed when that list fell behind:
    the screen simply stopped being able to change for whichever field had been left out. The bell
    above would have been the next one caught by it — a sounding alert changes nothing else about a
    frame, so at a step boundary the clock behind it reads the same second and the frame is judged
    identical and dropped. The list is gone rather than extended, because a list can go stale and the
    picture cannot.

Internal

  • Publishing no longer waits to be asked. npm run release with no flag is the procedure, and
    the Marketplace form is the only step left to a human. docs/releasing.md keeps the reasoning it
    replaced rather than deleting it, and also now warns that a release run rewrites the hand-over
    page's README.md, so anything hand-written into it has to be re-applied afterwards.

  • Three claims in this file were wrong. 4.1.0 was dated the day the entry was written rather
    than the day it shipped, and both the Unreleased compare link and 4.0.0's own link pointed at a
    v4.0.0 tag that has never existed — measured, 404 — so a heading that reads as a link to a
    release led to a GitHub error page.

4.1.0 — a press silences an alert that is playing, and does nothing else

Choose a tag to compare

@cicmorgi cicmorgi released this 21 Sep 09:17

Added

  • A press silences an alert that is playing, and does nothing else. That is what makes a high
    repeat count usable — up to sixty now — because an alarm meant to outlast you walking back to the
    desk is no good if it cannot be called off. The press will not start, pause or reset the clock, so
    you cannot quieten a sound into changing what the timer was doing; press again for the gesture you
    meant, or press and hold to silence it and put the timer right in one go. Turning the dial
    silences it too, and still adjusts.

    Every step of a multi-step preset gets its own silenceable alert. There is no keep ringing
    switch: it existed for one unreleased build and it was a second idea of the repeat count in a
    different vocabulary, with a rule reconciling the two that got it backwards — only the end of the
    whole job could be silenced. On 40m, 10m, 10m, 10m that is the wrong way round: the end of the
    forty is the moment you must not miss, the ten after it is already counting by the time you hear
    it, and the press made to quieten the alert went through to the clock and paused that ten. One
    count and one rule cannot disagree with themselves.

    The trade, stated plainly: with the default single chime, a press made inside those two seconds is
    spent on silencing and the clock does not move. Press again.

  • Holding the dial's own knob puts the clock right, the same as holding the touchscreen: back to
    the top of the preset, and on to the next one only when there was nothing to put right. It is also
    how a dial silences a ringing alarm and resets it in one gesture, the hold being the one gesture
    a ring does not swallow — until now that needed the touchscreen, because the knob had no hold.

    The threshold is measured on release, never by a timer running while your finger is down, and
    that is the whole reason the dial can have a hold at all. Pushing the knob in is how you ask for
    minutes, so a timer firing mid-press would go off in the pause between pushing in and starting to
    turn, silently loading a preset under a wind that began a beat late. A press that turned the dial
    is already discarded as the end of a wind, so what reaches the threshold can only be a finger that
    went in, stayed, and came back up with the clock untouched. The trade: a slow, deliberate press
    meant as a pause reads as a hold, and costs one more hold to undo.

  • Quieter after the third play. One checkbox: the first three plays sound at the volume you set,
    everything after at half of it. Half of your volume, not a fixed level, so a quiet alarm does not
    get louder as it goes on.

Fixed

  • Repeats no longer play on top of each other. Set to three, the alert was heard as one chime,
    then two at once, then three — stacking up and never going past three. Every repeat was scheduled
    at a fixed 900 ms from the first, and the bundled chime.wav is 2.00 s long, so the second play
    started while the first was still sounding. A play now begins when the previous one has ended,
    which is right for a sound file of any length, on either platform, including your own.

  • A step running out no longer layers its alert over the previous step's. Two runs playing at
    once sound exactly like the bug above.

  • The inspector's Test button is a toggle. Clicking it while a preview was still going used to
    start a second one underneath the first — bearable at three plays, and most of a minute of chime at
    sixty.

  • Closing the property inspector stops whatever it was auditioning. A preview is reachable only
    through the panel, so closing it mid-audition left the sound running with the button that would
    have stopped it gone from the screen. The reason the repeat count could be raised at all is that
    no setting may produce a noise there is no way to call off; this was the hole in that.

Internal

  • The code and the docs now state what is true today; the changelog keeps the history. src/
    lost a third of its comment volume to passages narrating designs that had already been replaced,
    docs/how-it-works.md lost its archaeology, and a CLAUDE.md was added carrying the constraints a
    tidy-up would otherwise undo. Nothing was deleted until it had been located by name elsewhere. One
    live defect fell out of it: src/plugin.ts carried a truncated comment describing a per-minute
    cost report that no longer exists. The packaged plugin is unaffected — same content id before and
    after.

3.11.0 — the fault that prompted most of the last two days was never in this plugin

Choose a tag to compare

@cicmorgi cicmorgi released this 18 Sep 00:46

The fault that prompted most of the last two days was never in this plugin. A Stream Deck + was
drawing 500 mA through a Studio Display's hub — the documented ceiling for that port, and not
enough for a touchscreen, eight LCD keys and four dials. Moved to a port on the Mac, everything
works: the dials, the keys, and the built-in actions that had also stopped.

So the instrumentation built to find it comes back out. The bug fixes stay, because none of them were
ever about the hardware.

Removed

  • The per-minute health report, and everything that fed it. Two timers ran for the life of the
    process — an event-loop sampler twice a second and a report every sixty seconds — writing a line of
    performance telemetry into the log of every install, for ever. A countdown timer does not need to
    file a report about itself once a minute.
  • The round-trip probe, which sent a message to Stream Deck every minute purely to time the reply.
  • Per-gesture logging. A line was written for every press, release, turn and tap.
  • The pressed || down override on a rotation. It was borrowed from another plugin on the theory
    that the flag might lag the button, never measured, and a reviewer pointed out it trades a
    self-correcting reading for a latch that stays wrong until the next complete press. No evidence for
    it ever appeared — and the actual cause was three feet of USB away. The rotation's own flag decides
    the step again.

Changed

  • Copy diagnostics stays, and is leaner. It costs nothing until it is pressed, and it is what
    makes the next hardware problem ten minutes rather than a day. It now carries warnings and
    errors
    rather than every gesture and a per-minute performance line, and gathers what it needs at
    the moment you press it rather than from a reporter running in the background.

Kept

For the record, since this release removes a great deal: the ten fixes from the last two days all
stay.
The paused clock that threw away its count, the no-detent rotation that ate a press, the
duration ratchet, the floor that added time when you turned it down, the repeat tally that ran a
timer six times for a setting of four, the key's press-then-hold firing twice, the stray release
after a page flip, the orphaned long-press timer, the inspector undoing a gesture, and a release gate
that can now actually fail. Every one was reproduced before it was written, and every one is still
caught by deliberately breaking it and watching a test go red.

3.10.0 — copy diagnostics now names the Stream Deck application version and the connected device

Choose a tag to compare

@cicmorgi cicmorgi released this 17 Sep 23:43

Added

  • Copy diagnostics now names the Stream Deck application version and the connected device. Both
    arrive when the plugin starts, in a handshake no user could go and look up — and they are exactly
    what the two most commonly reported causes of an unresponsive Stream Deck turn on.

    Stream Deck 7.1.0.0 on mac 14.0.0
    devices: Stream Deck + (type 7)
    

    When the plugin has not been told, the line is left out entirely rather than printed with question
    marks in it: a line reading Stream Deck ? on ? ? looks like an answer.

Internal

  • Researched what is actually reported when a Stream Deck stops responding, prompted by keys from
    other plugins failing too. The two recurring answers are insufficient USB power — the device
    browns out, restarts without initialising and is left in a bad state, which is why it is usually
    cured by a powered hub or a direct port rather than by any software change — and an out-of-date
    application
    . Neither is a plugin fault, and neither could be advised on without the two facts now
    in the report.

  • What the research did not support is recorded too: a page offering to fix Stream Deck lag gave
    tidy percentages for each cause, which is the shape of a number written to be quotable rather than
    measured. It is not used here. The one figure that is cited comes from a plugin vendor describing
    their own support queue, and is attributed as that rather than as a fact about anyone's hardware.

3.9.1 — copy diagnostics now carries Stream Deck's own log as well as this plugin's

Choose a tag to compare

@cicmorgi cicmorgi released this 17 Sep 12:46

Fixed

  • Copy diagnostics now carries Stream Deck's own log as well as this plugin's. The application
    keeps a separate log, and it is the component every plugin talks through — so when the complaint is
    that the whole machine is slow and other applications are lagging too, its side of the story was in
    a file the report was not reading.

    Its tail is included unfiltered, unlike this plugin's own lines. The format is Elgato's, and picking
    lines out of it would mean guessing which ones matter; twenty-five lines of everything is more
    honest than a filtered view built on an assumption.

Internal

  • The two logs are known with different confidence, and the report is careful about it. This
    plugin's log location is asked of the running process and cannot be wrong. Stream Deck's is
    derived from Elgato's logging guide and therefore can be — so a miss there is reported as an
    absence rather than an error, and on a platform Stream Deck does not run on it says so plainly.

  • Both platform branches are tested from whichever platform the suite runs on. Otherwise the
    Windows path is never executed on a Mac and the Mac path never on Windows, and the one that is wrong
    is precisely the one nobody ran.

  • Two things turned up while reading the documentation, recorded rather than acted on: the docs say a
    plugin's log files "never exceed 10 MiB", while the SDK that actually ships is configured for 50 MB
    — the code is what runs. And the property inspector is Chromium with DOM access, which is why a copy
    button inside it can reach the clipboard at all.

3.9.0 — a "copy diagnostics" button in the property inspector

Choose a tag to compare

@cicmorgi cicmorgi released this 17 Sep 12:33

Added

  • A "Copy diagnostics" button in the property inspector. One press puts everything needed to
    investigate a problem on your clipboard, ready to paste into a message or an issue.

    It replaces an instruction that ran: find your Stream Deck plugins folder, which is in a different
    place on each platform and depends how you installed it; open the .sdPlugin directory; find
    logs; open the newest file; scroll to the bottom; find the lines beginning health:; copy some of
    them.
    Seven steps, each one a place to give up — and none of it is the job of somebody who has
    reported that their device is slow. The plugin is the one thing that knows where its own log is, so
    it fetches it.

    Dial Countdown 3.9.0.0
    linux 6.8.0-139-generic x64 · 12 cores · 31GB · node v24.21.0
    log: <the plugin's own folder>/logs
    
    last 6 health, warning and gesture lines:
    2026-09-17T12:26:00.904Z INFO  dialDown
    2026-09-17T12:26:00.955Z INFO  dialUp turnedWhileDown=false down=true
    (and so on)
    

    It carries the health lines and the gesture lines, because those are the two kinds of
    trouble this plugin has actually had — is it slow and is it this plugin, and what did the
    hardware really send
    . A report that answered only one would send you back for the other. Everything
    else the plugin has ever logged is left out: a whole log is unreadable in a chat window.

    Find it under Diagnostics, at the bottom of the settings for any countdown.

Internal

  • Driven end to end through the real socket rather than read, and both runs found something reading
    it had not.
    os.version() is the kernel's version, not Node's — the report printed node #139-Ubuntu SMP PREEMPT_DYNAMIC, which is precisely the shape of thing that reads as a
    checked fact when it lands in a bug report. And the first version of the filter kept only health
    lines, so a gesture problem would have produced a report with nothing about gestures in it.

  • The empty case is tested as carefully as the full one: a button that hands back an empty box reads
    as broken, so it says the first health line is about a minute away instead. Six mutations, all
    caught, including one that puts the kernel version back.