Seitk/tminus

★ 0Forks 0SvelteGitHub ↗Compare

README

tminus

A Chrome extension for developers who read timestamps from logs all day.

Click the toolbar icon and you get two things: live clocks across the timezones you care about, and a scratchpad for converting any moment in time across those same zones — paste an ISO string or a unix timestamp from a log and see what it means everywhere at once.

tminus popup showing live clocks and the converter

Features

Live clocks — Local, UTC, and any IANA zones you add. Each row shows wall-clock time and ISO string with the zone's offset; Local and UTC also show unix milliseconds. Click any value to copy. Updates every second.

Smart-paste converter — One ISO input and one unix-timestamp input, both bound to the same instant. Pasting a number auto-detects seconds (10 digits), milliseconds (13), microseconds (16), or nanoseconds (19) by magnitude.

Per-zone editable rows — In the converter, every tracked zone has six editable fields (YYYY-MM-DD HH:MM:SS). Editing any field re-resolves the underlying instant in that zone's calendar, then re-renders every other row. Type 13 in the month and the year ticks up.

Calendar-aware adjustments — −1y −1mo −7d −1d / +1d +7d +1mo +1y buttons. Adjustments use the calendar of whichever row you last edited, so "+1 month" means "+1 month in Tokyo" if Tokyo is what you were tweaking. Powered by Temporal for correct DST and month-length behavior.

Zero clutter — Toolbar popup, no options page, no host permissions. Add and remove timezones inline. Tracked zones persist via chrome.storage.local; the converter resets to "now" each time you open the popup.

Install

git clone https://github.com/Seitk/tminus.git
cd tminus
npm install
npm run build

Then in Chrome:

  1. Open chrome://extensions.
  2. Enable Developer mode (top right).
  3. Click Load unpacked and select the dist/ folder this build produced.

The T icon will appear in your toolbar. Pin it for one-click access.

Development

npm run dev      # rebuilds dist/ on save
npm run build    # production build
npm run check    # svelte-check + tsc on the Vite config

After npm run dev, edits trigger a rebuild but Chrome doesn't auto-reload extensions. Click the reload icon next to tminus in chrome://extensions to pick up changes.

Releases

A new release is cut by pushing a v* tag. GitHub Actions builds the extension, zips dist/ as tminus-<tag>.zip, and attaches it to a GitHub release with auto-generated notes.

# bump the version in package.json first, then:
git tag v0.1.0
git push origin v0.1.0

Stack

  • TypeScript + Vite + Svelte 4
  • temporal-polyfill for timezone-aware calendar math (millisecond precision)
  • Manifest V3, storage permission only — no service worker, no content scripts, no host access

Layout

popup.html              # extension popup entry (project root, not src/)
src/
  popup.ts              # mounts <App />
  App.svelte            # popup root
  app.css               # design tokens + base styles
  lib/
    stores.ts           # Svelte stores: liveNow, converterAt, lastEditedZone, userZones, parseError
    storage.ts          # chrome.storage.local wrappers
    format.ts           # wallClock / isoInZone / unixMs / offsetLabel / fields / instantFromFields
    parse.ts            # smart-paste parser (ISO + unix s/ms/μs/ns)
    timezones.ts        # IANA zone list + label helpers
  components/
    LiveClocks.svelte
    LiveClockRow.svelte
    Converter.svelte
    ConverterRow.svelte
    ZoneAdder.svelte
public/
  manifest.json         # MV3
  icons/                # 16 / 48 / 128 px PNGs

The popup-as-its-own-build-input pattern means popup.html lives at the repo root rather than in src/ — that's what makes Vite emit dist/popup.html (which the manifest references) instead of dist/src/popup.html.

Contributing

Issues and PRs welcome at https://github.com/Seitk/tminus.

License

MIT

Contributors

Seitk

Issues