Omahub
← All plugins
G

GTA VI Countdown

by Gabriel Borges

A minimalist Grand Theft Auto VI countdown for the Omarchy bar: one icon, a panel with the exact time remaining and both dates that matter, a daily reminder, and a link to the official page. Retires itself once the game is out.

Security review

Potentially dangerous behavior detected · 1 finding

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
a6100a9
Scanned
3 weeks ago
  • high destructive_filesystem tests/helper.test.py:161

    Destructive operation on the root filesystem or a block device.

    rm -rf /", "../../etc/passwd",

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

None
AI risk level
None
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
a6100a9
Reviewed
3 weeks ago

The automated 'high' finding is a false positive: the `rm -rf /` and `../../etc/passwd` strings are test fixtures in tests/helper.test.py that verify the state helper rejects hostile day keys, and they are never executed. The plugin is a date-arithmetic countdown widget whose code runs a bounded, symlink-safe state helper and only invokes xdg-open or wl-copy on explicit user actions, with no network, installer, or destructive behavior.

  • The deterministic destructive_filesystem finding refers to string literals inside a unit test, not to executable commands; no install or runtime path executes them.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/xgborgeso/omarchy-gta6-countdown --enable
Widgets #bar #quickshell #games

GTA VI Countdown for Omarchy

Check

A minimalist Grand Theft Auto VI countdown for the Omarchy bar: one icon, a panel with the time remaining and both dates that matter, a link to the official page, and one reminder a day. It is pure date arithmetic: no daemon, no network, and nothing read from the system but its own reminder stamp.

<p align="center"> <img src="preview.png" width="428" alt="The GTA VI Countdown panel open in the Omarchy bar, titled Grand Theft Auto VI - Countdown, reading 82d 09h 26m above the release date of November 19, 2026 and the pre-load date of November 12, 2026"> </p>

Features

  • One icon on the bar, the same width as every other chip. The reading lives in the tooltip and the panel rather than a string that grows and shrinks and shoves its neighbours sideways once a minute
  • One line of exact time in the panel — 82d 09h 26m, ticking every minute. Switch it for the plain sleeps count with panelFormat
  • Pre-load as well as release, since pre-load opens a week ahead and is the date you actually have to act on
  • One reminder a day, at an hour you choose, with a milestone line at 100 days, 50, a month, two weeks, pre-load day, and the last three days
  • A line that escalates as launch approaches, from Sit tight at six months out to This is not a drill in the final days. It changes every time you open the panel and on every daily reminder, drawn from a bag so it never repeats before the tier is exhausted
  • Counts to local midnight, because that is how Rockstar gates pre-orders, pre-load and launch
  • Packs up after release: a farewell line, the removal command with a copy button, and a widget that takes itself off the bar a month later

Install

omarchy plugin add https://github.com/xgborgeso/omarchy-gta6-countdown.git --enable

--enable puts the icon on the right of the bar.

The dates

Release November 19, 2026, local midnight, on PS5 and Xbox Series X|S
Pre-load November 12, 2026, local midnight

Rockstar confirmed November 19 in a Newswire post on November 6, 2025, and Take-Two has reaffirmed it since. It has moved twice before, which is why releaseDate is a setting rather than something baked into the code — if it moves again you retarget it yourself instead of waiting for a release here.

Settings

Key Default What it does
releaseDate 2026-11-19 Target date, YYYY-MM-DD, counted to local midnight. An unparseable value falls back to the shipped date and says so in the panel.
barFormat icon icon shows the glyph alone. days shows the sleeps count. dhm shows exact time remaining, and ticks every minute.
panelFormat exact exact shows one line of ticking time. days shows the sleeps count instead. auto shows the sleeps count, adding the exact figure beneath it in the final two days. both always shows both.
notifyMode daily daily, milestones only, or off.
notifyHour 9 Earliest hour for the daily reminder, 0–23.
hideAfterDays 30 Retire the widget this many days after release. 0 keeps it forever.
omarchy bar set io.github.xgborgeso.gta6-countdown barFormat dhm --json
omarchy bar set io.github.xgborgeso.gta6-countdown notifyMode milestones --json
omarchy bar move io.github.xgborgeso.gta6-countdown --section right

Reminders

One notification per local day, on the first tick at or after notifyHour. Booting at 14:00 fires immediately; a machine left running overnight fires at notifyHour rather than at midnight.

Every toast is headed Grand Theft Auto VI - Countdown, the same words the panel uses and the same on every day, so it is recognisable at a glance. The body is always two parts: where the countdown stands, then a line from the current tier.

Grand Theft Auto VI - Countdown
83 days · A real countdown now

The line comes from a bag rather than at random, so every phrase in the tier appears once before any repeats and no two mornings running say the same thing.

State lives in $XDG_STATE_HOME/omarchy-gta6-countdown/last-notified: the last day spoken on, so restarting the shell five times before lunch does not produce five identical toasts, and the bag, so a reboot does not reset the rotation.

On an ordinary day the body opens with the count. On a milestone it says what the milestone is instead:

Sleeps left Body opens with
any other day 83 days
365 · 300 · 200 · 100 · 50 One year to go … 50 days to go
30 One month to go
14 Two weeks to go
7 Pre-load is open
3 · 2 · 1 Three days to go · Two days to go · Tomorrow
0 Out now

Release day is announced, and then the countdown has nothing left to say and stops speaking.

What they look like

An ordinary morning: the count, then a line from the tier.

<img src="docs/notification-daily.png" width="408" alt="A notification headed Grand Theft Auto VI - Countdown, reading 83 days, A real countdown now, with a controller glyph">

A month out, where the practical nudges live.

<img src="docs/notification-milestone.png" width="408" alt="A notification headed Grand Theft Auto VI - Countdown, reading One month to go, Weeks not months">

Pre-load day, one week ahead of launch.

<img src="docs/notification-preload.png" width="408" alt="A notification headed Grand Theft Auto VI - Countdown, reading Pre-load is open, One week One week">

The last two days come through as critical, so they stay on screen.

<img src="docs/notification-tomorrow.png" width="408" alt="A notification headed Grand Theft Auto VI - Countdown, reading Tomorrow, Clear your calendar">

And then it is done.

<img src="docs/notification-release.png" width="408" alt="A notification headed Grand Theft Auto VI - Countdown, reading Out now, Why are you still here">

After release

A countdown that outlives its date is clutter, so this one packs up on its own.

On release day the panel says Go and play. You can remove this whenever. Afterwards it counts the days until it retires — Nothing left to count. Retiring in 12 days. — and shows the removal command with a button that copies it to the clipboard, so you do not have to go looking for it. On day hideAfterDays the widget takes itself off the bar. Set hideAfterDays to 0 if you would rather it stayed.

omarchy plugin remove io.github.xgborgeso.gta6-countdown

What it touches

Plugins run unsandboxed in the Omarchy shell process, so here is everything this one does outside its own window.

Runs python3 helper/state.py to read and write the reminder stamp
omarchy-notification-send for the daily reminder, from $OMARCHY_PATH
xdg-open for the official page, only when you click the link or press o
wl-copy for the removal command, only when you click copy after release
Writes $XDG_STATE_HOME/omarchy-gta6-countdown/last-notified, one line of JSON, mode 0600 in a 0700 directory
Reads That same file, and nothing else. No /sys, no /proc, no config beyond its own bar settings
Network None. The only URL is the one handed to xdg-open on a click

No daemon, no installer, no remote build, and no elevated privilege. Python 3 is the only dependency, and the standard library is all the helper uses.

Why the stamp goes through a helper

Quickshell's FileView takes a path and nothing else. It cannot open with O_NOFOLLOW, cannot fstat what it opened, and cannot stop reading at a byte limit. The stamp sits at a predictable path under $XDG_STATE_HOME, so any process running as you could replace it with a symlink to /dev/zero, or with a gigabyte of text, and that would be read straight into the long-lived shell. atomicWrites guards the write; nothing in QML guards the read.

helper/state.py does the read instead, where the real primitives exist. It opens the directory O_NOFOLLOW|O_DIRECTORY and the file relative to that descriptor, so neither component can be swapped between the check and the open. It fstats the descriptor for a regular, same-owner, single-link file before a byte is read, stops at 4 KiB, refuses an oversized file rather than truncating it, and validates every field of the parsed shape.

Anything it refuses fails closed to an empty state, which the widget reads as "nothing said yet today". The cost is at most one repeated notification, and the next write replaces the offending file atomically. Refusing to speak at all would let anyone who can touch that file silence the reminder permanently, which is the worse failure.

Every value that reaches a label or a notification also goes through Model.safeText, and every text sink is pinned to Text.PlainText, which tests/qml.test.py enforces.

Controls

Left click opens the panel, middle click opens the official page.

Key Action
o Open rockstargames.com/VI
r Refresh
Tab Next stock panel
Esc Close

The panel is also scriptable:

omarchy-shell io.github.xgborgeso.gta6-countdown status   # 82d 10h 24m
omarchy-shell io.github.xgborgeso.gta6-countdown days     # 83
omarchy-shell io.github.xgborgeso.gta6-countdown toggle
omarchy-shell io.github.xgborgeso.gta6-countdown link

Why the two numbers disagree

Set panelFormat to both and the panel shows 83 days above 82d 10h 24m remaining. Both are correct.

83 is how many sleeps away it is, which is what a person means by "days left". 82d 10h is exact time on the clock. They differ by one for most of the day and agree at local midnight. Every bare number — the tooltip's neighbour, the days bar format, every notification — uses the sleeps count; only the ticking figure is exact.

The panel ships showing only the exact figure, so the two never sit together unless you ask for it. auto is the middle ground: the sleeps count on its own until the final two days, then the exact figure joins it, when the minutes are actually the point.

The gap can also be more than you expect. Between August and November the clocks go back, so there is one more real hour of waiting than the calendar suggests, and the exact figure counts it. That is a fact about November, not a rounding error.

Tests

Everything testable is a pure function in Model.js, so the suite needs no compositor, no shell and no display:

node tests/model.test.js
python3 tests/helper.test.py
python3 tests/qml.test.py
omarchy plugin validate .

tests/model.test.js re-runs itself once per timezone — a southern-hemisphere zone, where the clocks go the other way before launch, and a half-hour offset among them. Half of what it checks is local-midnight behaviour, which a runner in UTC alone would happily agree with a bug about. It also walks every day between now and release to prove the reminder fires once a day and each milestone exactly once.

tests/helper.test.py runs the stamp helper against a real temporary directory and asserts it refuses the substitutions that motivated it: a symlink at the stamp path, a symlinked state directory, an oversized file, a directory where the file should be, a group-writable state directory, invalid UTF-8, and crafted field values. It also checks that writing over a symlink replaces the link rather than its target.

tests/qml.test.py reads the QML rather than running it, and checks the things that load fine in an editor and fail silently in the bar: a text sink left on Text.AutoText, a property name starting uppercase, a manifest default nothing reads, or a nerd-font glyph pasted in as an invisible private-use character instead of written as an escape.

Remove

omarchy plugin remove io.github.xgborgeso.gta6-countdown

That takes the widget off the bar and deletes the plugin folder. The one thing it leaves is the reminder stamp, which is deliberate: reinstalling on a day the widget has already spoken for stays quiet rather than repeating itself. Delete it if you would rather start clean.

rm -r "${XDG_STATE_HOME:-$HOME/.local/state}/omarchy-gta6-countdown"

License

MIT. This is an unofficial fan project. Not affiliated with, endorsed by, or associated with Rockstar Games or Take-Two Interactive. Grand Theft Auto is a trademark of Take-Two Interactive Software, Inc., referred to here only to identify the game being counted down to.