Skip to content

SAM v3.3.0 — The Pocket Connects

Choose a tag to compare

@richhabits richhabits released this 10 Aug 13:44
· 464 commits to main since this release
11ff952

The release where the phone app stops being a demo of itself. Two things in SAM had never actually worked end to end — pairing a phone, and the yard when SAM runs as an app rather than from a checkout — and both failed in ways that looked like your fault.

Fixed

The yard could never work from the packaged app, and said only "500". yardDir() derives from its own module path, which inside SAM.app resolves to a directory inside app.asar — a read-only archive. Every file the yard owns (jobs.db, paired.json, worker.lock, logs/) failed to open, and /api/yard answered a bare 500 to a phone that was correctly paired. The yard has only ever worked when the server ran from a checkout, which is exactly why the launchd daemon could serve it and SAM.app never could. Packaged builds now keep state under ~/SAMYard; a checkout keeps its repo-local yard/, so no existing job moves.

The status endpoint no longer answers with a shrug either — it returns 200 with the path it could not read.

You could not pair a phone at all. POST /api/pair/new mints the code, and nothing in the app had ever called it; the desk pointed at a button that was never built. There is now a "+ Pair a phone" button that calls it.

A refusal from before pairing outlived the pairing that fixed it, locking the phone out of a SAM it had just been granted. And the desk no longer offers a pairing that cannot work when a second SAM already holds the port.

Security

Anyone on the network could mint a pairing code under SAM_REMOTE=1 and claim a full session. The cause was middleware ordering, not a missing check. Remote mode is off by default.

Added — the Pocket

  • It asks before it spends. A paid brain needs consent, and the grant can be taken back from Settings — it used to be a one-way door, which is not a permission.
  • A demo, so the app is not dead without a Mac — sample data, labelled as such on every screen it reaches.
  • Settings that contains settings: spending, appearance, version, help, and an icon on every row.
  • A task list you can filter — the Running / Queued / Failed / Done counts became the control that opens the rows behind them.
  • A job says what it DID, folded from its own step list, instead of printing a timestamp.

Changed

  • The tint stopped being a status. Terracotta meant "running" in one place and "this is a link" in another; colour now carries one meaning, and running is carried by motion.
  • The palette was failing AA on the most repeated text in the app — fixed, including under Increase Contrast, which the app now honours.
  • Four different logos were shipping as SAM. One mascot now, everywhere.
  • VoiceOver was reading parts of the app out as punctuation.

Build

build:mac:signed packaged whatever was already in dist/ — every other target runs preflight and a build first. A release cut that way carries the last build someone happened to run, possibly predating the fix it was cut for, while reporting the new version number. It now builds first, makes skipping notarization an explicit flag, and refuses to upload an unnotarized build as a release.


Signed with a Developer ID certificate and notarized by Apple. Gatekeeper's own verdict on this build: accepted, source=Notarized Developer ID.


🔒 Verify your download (SHA-256)

The one-paste installers verify this automatically. To check by hand, compute the hash and match:

  • macOS/Linux: shasum -a 256 <file>
  • Windows (PowerShell): Get-FileHash <file> -Algorithm SHA256
5efc259cda02b153a914525d930fdbeeedcf6a7cd4dfedab7e4c293b91274780  SAM-3.3.0-arm64.dmg
e4962824923c69edbcfe5510fad4f83da51c066a4b6aa8fbf50812c55a917cb5  SAM-3.3.0.AppImage
51f341a568c3eeca285a597a22a675ab41992039f64ca49844b4198249cee651  SAM-3.3.0.dmg
09bc24d5b91ee632197b7c268e2d888b64ceee02b42e654233b887c966e50358  SAM-Setup-3.3.0.exe
f437d9ebdc38358e116b0518e60b841d8f76709480ddb5a1cbb3361d40bfe3db  sam_3.3.0_amd64.deb