Skip to content

Releases

Focus Exe 1.4.0

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 11 Oct 20:44

Added

  • Badge-style close button on widget (visible on hover/touch)
  • Changelog now loads from GitHub at runtime — no rebuild needed for updates

Changed

  • Local builds (npm run build:local) now create stable folders in dist/<browser>/ — no separate dist/hot/ needed
  • Page served from dist/page/ (GitHub Pages); extension packages no longer include page assets

Removed

  • dist/hot/ folder and --hot flag
  • Build-time changelog parsing (was src/changelog.ts)

Focus Exe 1.3.0

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 06 Oct 19:51

Added

  • Bullseye target icon for the focus session counter row
  • Single-audio cross-tab lease: brown noise and the metronome are audible from exactly one tab no matter how many are open
  • src/leadership.ts — shared chrome.storage.local lease with heartbeat renewal and TTL expiry
  • test/smoke.mjs — shared-store boot helper and 10-check shared-audio smoke suite

Changed

  • About & support now opens the source repository on GitHub instead of the product page
  • build.mjs generates a stable page/changelog.json from CHANGELOG.md; the product page renders the condensed release history at runtime from this JSON instead of hand-typed HTML
  • src/changelog.ts — Keep a Changelog parser emitting a stable JSON schema

Fixed

  • Reopening the widget pushes the running session into the audio engine only when this tab holds the shared lease, so a reopened panel is no longer silent but also never layers noise beds or metronome streams with other open tabs

Tests

  • 146/146 checks: test/run.mjs verifies the built manifest.json declares the all-URL content script and keeps <all_urls> out of permissions (3 manifest checks), plus the three suites (page 31, worker 20, smoke 95).

Focus Exe 1.1.2

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 27 Sep 16:40

Focus Exe 1.1.2 - 2026-09-27

Added

  • Changelog on the product page (#changelog, in the nav): the release history from v1.0.0 condensed into one card per version, linked to the full CHANGELOG.md. The page test fails if the current version is missing there, so the page can never ship stale.
  • The release process, written down: .clinerules/releases.md (the always-on rule - no version bump without a changelog entry, no release push without an annotated tag) and the /release skill with the full checklist.

Changed

  • Audio keeps playing while the tab is in the background: brown noise and the 60 BPM metronome no longer pause when the tab is hidden. The metronome queues up to 75 s of beats on the audio clock, never schedules a beat in the past, and fades the queued backlog on stop or mode switch. A suspended AudioContext resumes as soon as the browser allows it, and any page gesture unlocks it.
  • Reopening the widget restores sound: the running session is pushed into the fresh audio engine, so a reopened panel is no longer silent.
  • package-lock.json version fields are back in sync with package.json.

Tests

  • 141/141 checks (page 31, worker 20, smoke 90); tsc --noEmit clean.

Full history: https://github.com/vallimuthuraja-git/focus-exe/blob/main/CHANGELOG.md

Focus Exe 1.1.1

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 27 Sep 07:58

Fixed

  • The mechanical digit scroll on the countdown always runs. Two prefers-reduced-motion gates in the extension build (one in the render path, one forcing animation-duration: 1ms) stopped the reel animation whenever the desktop reported reduced motion — which Chrome does when OS animations are off. The digits snapped instead of scrolling, unlike the original app. The roll is now unconditional and matches the original 540 ms mechanical-roll; reduced motion still applies to the button, popover and progress-bar transitions.

Verify

Reload the unpacked extension from dist/<browser>, or re-download the zip for your browser below. The product page download links now point at this tag.

Focus Exe 1.1.0

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 27 Sep 05:52

Minor release. The widget's ⓘ button moves into the settings panel and gains a
GitHub link beside it. No timers, audio or stored state changed, and nothing
needs migrating — 1.0.1 installs keep working and their settings are read
untouched.

What changed

The header held a single-purpose ⓘ button that opened the bundled product page.
It is now a row inside the settings panel, and because the panel is built once
per view it is reachable from the compact bar too, which it never was
before:

Settings
  Brown Noise              [switch]
  60 BPM Neuro-Metronome  [switch]
  -----------------------------
  About & support        ↗  bundled product page
  GitHub                 ↗  source repository

Each row is a full-width button that mirrors the toggle-row layout, so the whole
strip is one comfortable target rather than a small icon. Clicking a row closes
the panel and asks the service worker to open the tab, since a content script
cannot create tabs. The worker maps the target to a URL it chooses — no URL
is ever taken from the message.

The panel is now titled "Settings" rather than "Audio settings", since it no
longer holds only audio options. Row accessible names begin with the visible
text, so screen readers announce "About & support" rather than something that
merely resembles it (WCAG 2.5.3).

Code layout

The settings panel had grown inside widget.ts; it now has its own files, and
widget.ts keeps only the shell, cards, controls and confirmations:

File Contents
src/ui.ts shared shadow-DOM builders (need, icon, button, popButton, replaceIcon)
src/settings.ts the panel: audio toggles plus the About/GitHub rows
src/settings.css the panel styles, lifted out of widget.css

The panel is driven by data (TOGGLES / LINKS) instead of a hand-built
fragment, and the repository URL is injected from package.json by build.mjs,
keeping it a single source of truth with the product page.

Tests

Suites: 131/131 (page 30, worker 20, smoke 81), up from 110. The new checks
assert the rows exist in both panels, that each sends exactly one correct
message, that the row child order stays copy-then-arrow, and that accessible
names start with the visible label. The worker suite also pins that the repo
link opens the real repository, that foreign senders are ignored, and that an
unknown target opens nothing.

Still to configure

The Support section ships with placeholder handles. Each button safely falls
back to its platform's home page with a small setup note, so nothing 404s — but
donations cannot be received until real handles are filled in.

Downloads

Same six builds, ~34 KB each, unsigned.

Asset Install
focus-exe-1.1.0-chrome.zip Unzip → chrome://extensions → Developer mode → Load unpacked
focus-exe-1.1.0-edge.zip Same, via edge://extensions
focus-exe-1.1.0-brave.zip Same, via brave://extensions
focus-exe-1.1.0-opera.zip Same, via opera://extensions
focus-exe-1.1.0-firefox.zip about:debugging#/runtime/this-firefox → Load Temporary Add-on → pick manifest.json
focus-exe-1.1.0-safari.zip xcrun safari-web-extension-converter dist/safari --macos-only --no-open

Minimums: Chromium 102+, Firefox 115+, Safari 16+.

Focus Exe 1.0.1

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 26 Sep 19:17

Patch release. v1.0.0 had a bug that made the timer unusable after the first dismissal — please read if you installed 1.0.0.

The bug

sanitize() used Number.isFinite(Number(x)) to check whether a stored value was a number. But Number(null) is 0, and Number.isFinite(0) is true, so a null passed the check and became 0.

The extension writes remaining: null whenever it is idle, so the first summon looked fine (sanitize(null) returns the defaults untouched). Every summon after that:

  • the clock rendered 0:00 instead of 25:00, and
  • pressing Start created a zero-length session that settled instantly — the session counter incremented and a "Focus session complete" notification fired.

A stored running: true, endAt: null record was also settled as a phantom completion, which is exactly the corruption sanitize() exists to reject.

If you installed 1.0.0, update to this release — your session counter may have been incremented by a session that never happened.

The fix

src/state.ts now accepts only a real finite number for endAt and remaining; anything else is treated as absent. clampNumber no longer coerces either, so non-numeric input falls back instead of silently becoming 0.

Why it shipped

The 109 checks that were passing were living outside the repository, and no suite ever seeded a stored idle record. Both are fixed here:

  • test/ is now tracked, with npm test (pretest builds first) running all three suites against the built bundles
  • a regression case covering all four symptoms, confirmed failing before this fix and passing after
  • GitHub Actions now type-checks, tests, packages and deploys the product page on every push to main

Also in this release

  • MIT LICENSE added. package.json declared MIT and the product page advertised it, but there was no licence text, so GitHub reported no licence and the repository was legally all-rights-reserved.
  • test/page.mjs derives the release-asset URLs from package.json instead of hard-coding the version, so it no longer breaks on every release.

Suites: 110/110 (page 30, worker 17, smoke 63).

Still to configure

The Support section ships with placeholder handles. Each button safely falls back to its platform's home page with a small setup note, so nothing 404s — but donations cannot be received until real handles are filled in.

Downloads

Same six builds, ~33 KB each, unsigned.

Asset Install
focus-exe-1.0.1-chrome.zip Unzip → chrome://extensions → Developer mode → Load unpacked
focus-exe-1.0.1-edge.zip Same, via edge://extensions
focus-exe-1.0.1-brave.zip Same, via brave://extensions
focus-exe-1.0.1-opera.zip Same, via opera://extensions
focus-exe-1.0.1-firefox.zip about:debugging#/runtime/this-firefox → Load Temporary Add-on → pick manifest.json
focus-exe-1.0.1-safari.zip xcrun safari-web-extension-converter dist/safari --macos-only --no-open

Minimums: Chromium 102+, Firefox 115+, Safari 16+.

Focus Exe 1.0.0

Choose a tag to compare

@vallimuthuraja-git vallimuthuraja-git released this 26 Sep 18:58

First public release. A Manifest V3 focus assistant that runs on any site, on demand, and is torn down when you dismiss it.

What you get

  • 25/5 focus and recovery modes with mechanical split-flap digits and a countdown to a deadline
  • Brown noise and a 60 BPM neuro-metronome from a Web Audio look-ahead scheduler
  • Session counter with a progress bar
  • Confirmations on every state change, so a stray click can't end a session
  • Minimize/expand, a compact bar, and audio that pauses when the tab is hidden
  • Desktop notification when a session or break ends

How to run it

Action Result
Click the extension icon Show the widget on the current page (press again to hide)
Alt+Shift+F Same, without leaving the keyboard (rebindable in your browser's shortcut settings)
Click anywhere on the page Widget collapses to its compact bar
Click ⓘ in the widget Open the bundled product page in a new tab

Downloads

Six builds, one codebase, ~33 KB each.

Asset Install
focus-exe-1.0.0-chrome.zip Unzip → chrome://extensions → Developer mode → Load unpacked
focus-exe-1.0.0-edge.zip Same, via edge://extensions
focus-exe-1.0.0-brave.zip Same, via brave://extensions
focus-exe-1.0.0-opera.zip Same, via opera://extensions
focus-exe-1.0.0-firefox.zip about:debugging#/runtime/this-firefox → Load Temporary Add-on → pick manifest.json
focus-exe-1.0.0-safari.zip xcrun safari-web-extension-converter dist/safari --macos-only --no-open

The Chromium builds are identical; pick whichever browser you use. Minimums: Chromium 102+, Firefox 115+, Safari 16+.

These are unsigned self-hosted packages. Loading unpacked takes a minute and needs no developer account. Firefox temporary add-ons are removed on restart — sign with web-ext sign for a permanent install. Safari needs the Xcode converter because it ships through the App Store.

Privacy

Not a tracking product, and the permission list is the proof:

  • Permissions are only activeTab, scripting, storage, notifications — no host_permissions, no blanket <all_urls>, and no access to any page until you summon the widget
  • No remote code. No eval, no new Function, no CDN, and no network calls at all. The product page is a single self-contained file bundled into every build
  • The UI lives in a closed shadow root in the extension's isolated world and never touches page JavaScript — nothing is written to window, so a page can neither read nor drive the widget
  • Timer state lives in extension storage, not the page's localStorage, so the site can neither read it nor correlate it
  • Everything read back from storage is re-validated and clamped, and both the service worker and the content script ignore any message whose sender.id isn't this extension

Build it yourself

npm install && npm run pack   # tsc, build all six, write the zips

Requires Node 18+, Chrome 102+, Firefox 115+ or Safari 16+. npm run verify type-checks and produces a packaged build; npm run dev gives you an unminified build with inline sourcemaps.

What's next

v1 is deliberately small. Likely v2 additions: editable focus/break lengths and deadline in the settings panel, per-tab vs global session stats, a session history chart, custom sound packs, and an optional "auto-open on this site" list.


Found a problem or want to help? Open an issue.