Skip to content

[tacet] Add the tacet cask - #5

Merged
drycode merged 3 commits into
mainfrom
dy/tacet-cask
Aug 5, 2026
Merged

[tacet] Add the tacet cask#5
drycode merged 3 commits into
mainfrom
dy/tacet-cask

Conversation

@drycode

@drycode drycode commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Adds tacet — push-to-talk dictation that pastes the transcript at the cursor — as a cask.

brew install --cask drycodeworks/tap/tacet after this lands.

Why a cask and not a formula

The artifact is a prebuilt .app that is signed with a Developer ID, notarized, and stapled. Building it from source in a formula would discard the stapled ticket, which is the part that makes it install without a Gatekeeper fight.

Why not the Mac App Store

Worth recording, since it is the obvious question. Tacet pastes at the cursor by synthesizing ⌘V with CGEvent.post(tap: .cghidEventTap) and controls other apps through the Accessibility API. The App Sandbox forbids both and no entitlement grants them, so the MAS version of this app would be one that cannot do the thing it exists to do. Every tool in this category ships outside the store for the same reason.

Decisions worth reviewing

  • No depends_on formula: "whisper-cpp". One bundle plays two roles; only tacet serve needs whisper. A laptop that is purely a client, talking to a server on another Mac, should not be made to build it. It is named in the caveats instead.
  • uninstall launchctl: covers both agents. The setup scripts load them, and an uninstall that leaves a service running is worse than one that leaves a file behind.
  • zap takes the config and both plists but not /tmp logs, which macOS clears anyway.

Verification

brew style drycodeworks/tap/tacet      # no offenses
brew audit --cask --online             # no errors

--new additionally reports "GitHub repository not notable enough (<75 stars)". That is the gate for submitting to upstream homebrew-cask, not for a personal tap.

The published asset was checked end to end: the downloaded bytes match the local build exactly, stapler validate passes on an extracted copy, and spctl reports source=Notarized Developer ID.

Coordination with the installers

tacet 0.1.1 ships the other half of this. Both install-server.sh and install-client.sh now detect a cask install and use Homebrew's bundle instead of rebuilding over it — previously they hardcoded ~/Applications and would have left a cask user with two copies, with launchd pointed at the one brew does not manage. Rebuilding over the cask's bundle would also have re-signed a notarized app and invalidated its TCC grants.

Not exercised end to end on the author's machine: installing and then uninstalling the cask would bootout the live tacet agents mid-session. The resolution logic is covered by 11 unit tests against a stubbed brew, and a real machine with no cask installed was confirmed to still resolve to ~/Applications.

drycode added 3 commits August 5, 2026 17:02
Push-to-talk dictation, distributed as a signed and notarized .app.
The Mac App Store is not an option for it: pasting the transcript at the
cursor means posting synthetic events into other apps, which the sandbox
forbids and no entitlement grants. Developer ID plus a tap is the
distribution path for this category.

Not a formula: the artifact is a prebuilt app bundle whose notarization
is the point. Building from source would discard the stapled ticket.

Deliberately no `depends_on formula: "whisper-cpp"`. One bundle plays two
roles, and only `tacet serve` needs whisper — a laptop that is purely a
client, talking to a server on another Mac, should not build it.

`uninstall launchctl:` covers both agents, since the setup scripts load
them and an uninstall that leaves a service running is worse than one
that misses a file.

Solves: install without cloning the repo and dragging a zip
Tests: brew style and brew audit --online are clean; the installers in
       0.1.1 detect this cask and use its bundle rather than rebuilding
The same failure as d6c45e9, in a new place. That commit fixed a gate
that tested nothing because the diff was empty; this one tests nothing
because test-bot has no cask step at all. `--only-formulae` on a
cask-only PR prints `testing_formulae (none)` and goes green — observed
on the tacet cask PR, three passing legs, zero cask installs.

--only-tap-syntax does cover casks, but only through style and audit.
Neither installs, so a wrong sha256, an unreachable url, or an `app`
stanza naming a bundle the archive does not contain all pass CI and
then fail for every user.

macOS legs only, since casks do not install on Linux.

Solves: a cask gate that silently installed nothing
Tests: this PR is the check — it should now install and remove tacet
The tap has casks now, and the README described only formulae — down to
the install line, the Brewfile example, and the section heading.

The PR requirement applies to both, for different reasons worth keeping
separate: formulae because test-bot's diff is empty on a push to main,
casks because test-bot has no cask step at all. Also records that
`brew audit --new`'s 75-star "notable" gate is an upstream homebrew-cask
rule and is expected to fail here.

Solves: a tap README that documented half of what the tap ships
Tests: none — documentation
@drycode
drycode merged commit 35ebd8c into main Aug 5, 2026
3 checks passed
@drycode
drycode deleted the dy/tacet-cask branch August 5, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant