Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 0.3.4 — 2026-09-01

- Derive the ChatGPT launch-button date dynamically from the installed
executable's local package/update timestamp instead of hardcoding a version.
- Verify that the existing ChatGPT app button still brings a minimized app
window to the foreground after the package update.

## 0.3.3 — 2026-09-01

- Show the installed ChatGPT package/version and Codex CLI version in the two
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@
native expandable section, which opens automatically after recent activity.
- Launches an installed ChatGPT desktop app or Codex CLI directly, with native
installation guidance when either is missing. Web shortcuts cover ChatGPT,
Codex Cloud and ChatGPT Analytics.
Codex Cloud and ChatGPT Analytics. The ChatGPT launch tooltip derives its
displayed date from the installed executable's local package/update timestamp;
this is not an upstream publication-date guarantee.
- Shows `5h` automatically only when an active API limit exposes that window;
an accompanying `7d` panel block can be hidden in settings while unnamed
internal buckets stay hidden.
Expand All @@ -92,7 +94,7 @@ cd cinnamon-chatgpt-usage
Then open **System Settings → Applets** and add **ChatGPT Usage** to a panel.
Requirements: Cinnamon 5.8+, Python 3 and a current
[Codex CLI](https://learn.chatgpt.com/docs/codex/cli#getting-started) signed in
with ChatGPT. Version 0.3.1 is tested on Cinnamon 6.6.9 with Codex CLI 0.150.1.
with ChatGPT. Version 0.3.4 is tested on Cinnamon 6.6.9 with Codex CLI 0.152.0.

Run `./install.sh` again after updates. `./uninstall.sh` removes the applet while
retaining its settings.
Expand Down
29 changes: 22 additions & 7 deletions applet.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ const CODEX_CLOUD_URL = "https://chatgpt.com/codex/cloud";
const ANALYTICS_URL = "https://chatgpt.com/codex/cloud/settings/analytics#usage";
const CHATGPT_LINUX_INSTALL_URL = "https://learn.chatgpt.com/docs/linux/linux-app";
const CODEX_CLI_INSTALL_URL = "https://learn.chatgpt.com/docs/codex/cli#getting-started";
const CHATGPT_RELEASE_VERSION = "26.825.51511";
const CHATGPT_RELEASE_DATE = "30.08.2026";
const CODEX_RELEASE_VERSION = "codex-cli 0.152.0";
const CODEX_RELEASE_DATE = "01.09.2026";
const PANEL_FONT_SCALE = 0.95;
Expand Down Expand Up @@ -1048,6 +1046,7 @@ class ChatGptUsageApplet extends Applet.Applet {
const codexPath = this._resolveCodexPath();
const codexCommand = this._codexTerminalCommand(codexPath);
const chatGptVersion = this._chatGptAppVersion(chatGptApp);
const chatGptInstallDate = this._chatGptAppInstallDate(chatGptApp);
const codexVersion = this._commandVersion(codexPath);
const item = new PopupMenu.PopupBaseMenuItem({
reactive: false,
Expand Down Expand Up @@ -1111,11 +1110,7 @@ class ChatGptUsageApplet extends Applet.Applet {
Boolean(chatGptApp),
chatGptVersion,
"chatgpt",
this._knownReleaseDate(
chatGptVersion,
CHATGPT_RELEASE_VERSION,
CHATGPT_RELEASE_DATE
)
chatGptInstallDate
)
);
this._codexButton = this._createLaunchButton(
Expand Down Expand Up @@ -1477,6 +1472,26 @@ class ChatGptUsageApplet extends Applet.Applet {
return version === knownVersion ? releaseDate : null;
}

_chatGptAppInstallDate(appInfo) {
if (!appInfo) return null;
try {
const executable = appInfo.get_executable();
const executablePath = GLib.find_program_in_path(executable);
if (!executablePath) return null;
const fileInfo = Gio.File.new_for_path(executablePath).query_info(
"time::modified",
Gio.FileQueryInfoFlags.NONE,
null
);
return UsageFormat.formatLocalDate(
fileInfo.get_attribute_uint64("time::modified")
);
} catch (error) {
global.logWarning(`${UUID}: could not inspect ChatGPT package date: ${error}`);
return null;
}
}

_chatGptAppVersion(appInfo) {
if (!appInfo) return null;
try {
Expand Down
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "A tiny Cinnamon companion that keeps ChatGPT Work and Codex usage beautifully in view.",
"comments": "Made with love by Claudiu & Codex. 🩷\n\nhttps://github.com/oss-singularity/cinnamon-chatgpt-usage",
"contributors": "OSS Singularity — open-source home of the project,Claudiu Schuster — creator and maintainer,OpenAI Codex — design and engineering collaborator",
"version": "0.3.3",
"version": "0.3.4",
"author": "OSS Singularity",
"max-instances": 1,
"cinnamon-version": ["5.8", "6.0", "6.2", "6.4", "6.6"],
Expand Down
15 changes: 15 additions & 0 deletions tests/test-usage-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,21 @@ assertEqual(
"chatgpt 26.825.51511 — 30.08.2026",
"Installed ChatGPT tooltip includes release date"
);
assertEqual(
UsageFormat.formatAppTooltip(true, "26.831.20005", "chatgpt", "01.09.2026"),
"chatgpt 26.831.20005 — 01.09.2026",
"Updated ChatGPT tooltip includes current release date"
);
assertEqual(
UsageFormat.formatLocalDate(1788250825),
"01.09.2026",
"Application package timestamp formats as a local date"
);
assertEqual(
UsageFormat.formatLocalDate(0),
null,
"Invalid application package timestamp has no date"
);
assertEqual(
UsageFormat.formatAppTooltip(true, "codex-cli 0.152.0", "", "01.09.2026"),
"codex-cli 0.152.0 — 01.09.2026",
Expand Down
8 changes: 8 additions & 0 deletions usage-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,13 @@ function formatTimestamp(epochSeconds, use24Hour) {
return dateTime.format(`%x ${timeFormat}`);
}

function formatLocalDate(epochSeconds) {
const seconds = Number(epochSeconds);
if (!Number.isFinite(seconds) || seconds <= 0) return null;
const dateTime = GLib.DateTime.new_from_unix_local(Math.floor(seconds));
return dateTime.format("%d.%m.%Y");
}

function formatRelativeTime(epochSeconds, nowSeconds = null) {
const updatedSeconds = Number(epochSeconds);
const currentSeconds = nowSeconds === null
Expand Down Expand Up @@ -573,6 +580,7 @@ module.exports = {
formatActivityBucketTooltip,
formatAccessibleTooltip,
formatTimestamp,
formatLocalDate,
formatRelativeTime,
formatAppTooltip
};