Skip to content

Commit 1577e04

Browse files
committed
Say the version the build actually is, in the two places anyone reads it
Developer: Seif Hashish Project: HashCortX Summary: v2.5.0 shipped with the three build files bumped and both labels in the shell still reading v2.0 — the badge in the title bar and the line on the loading screen. So the DMG was 2.5.0, macOS reported 2.5.0, and the app itself told the user 2.0 in the only two places they look. Somebody checking the version to find out whether they have the fixes got the wrong answer from the product and the right one from the installer. The loading screen also still said "Batch 2.0 · May 2026", three months and one release out of date. Nothing could have caught it. They are plain text in markup, correct right up until a release, and a release is exactly when nobody is reading the markup. So the version is now checked in all five places at once — the three build files and the two labels — and they have to agree. A label may say `v2.5` where the build says 2.5.0: a title bar has little room and that is the same version said shorter. `v2.4` is not, and fails. Verification: - npm run check — 1,384 passed, 0 failed (1,376 before; 8 new). - Neutralise-and-rerun: putting v2.0 back in the title-bar badge fails by name, quoting both what the badge says and what the build is. - The macOS About window was already correct — it reads Info.plist, which the version bump had reached. It was the app's own chrome that was stale.
1 parent 6c82210 commit 1577e04

3 files changed

Lines changed: 80 additions & 4 deletions

File tree

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "module",
66
"scripts": {
77
"tauri": "tauri",
8-
"check": "npm run check:syntax && npm run check:guard && npm run check:rag && npm run check:agent && npm run check:export && npm run check:policy && npm run check:layout && npm run check:power && npm run check:native && npm run check:usage && npm run check:dom && npm run check:diff && npm run check:undo && npm run check:rag-store && npm run check:url-safety && npm run check:page-text && npm run check:pdf-text && npm run check:providers && npm run check:imports && npm run check:markdown && npm run check:shape && npm run check:model-names && npm run check:memory && npm run check:vector-map && npm run check:save && npm run check:forge && npm run check:theme && npm run check:controls && npm run check:csp && npm run check:modes && npm run check:css-layers && npm run check:app-size && npm run check:extraction && npm run check:bridge && npm run check:returns && npm run check:undefined-names",
8+
"check": "npm run check:version && npm run check:syntax && npm run check:guard && npm run check:rag && npm run check:agent && npm run check:export && npm run check:policy && npm run check:layout && npm run check:power && npm run check:native && npm run check:usage && npm run check:dom && npm run check:diff && npm run check:undo && npm run check:rag-store && npm run check:url-safety && npm run check:page-text && npm run check:pdf-text && npm run check:providers && npm run check:imports && npm run check:markdown && npm run check:shape && npm run check:model-names && npm run check:memory && npm run check:vector-map && npm run check:save && npm run check:forge && npm run check:theme && npm run check:controls && npm run check:csp && npm run check:modes && npm run check:css-layers && npm run check:app-size && npm run check:extraction && npm run check:bridge && npm run check:returns && npm run check:undefined-names",
99
"check:syntax": "node scripts/checks/syntax.mjs",
1010
"check:guard": "node scripts/checks/guard.mjs",
1111
"check:rag": "node scripts/checks/rag.mjs",
@@ -42,7 +42,8 @@
4242
"check:bridge": "node scripts/checks/bridge.mjs",
4343
"check:returns": "node scripts/checks/returns.mjs",
4444
"check:undefined-names": "node scripts/checks/undefined-names.mjs",
45-
"sweep": "node scripts/sweep-controls.mjs"
45+
"sweep": "node scripts/sweep-controls.mjs",
46+
"check:version": "node scripts/checks/version.mjs"
4647
},
4748
"devDependencies": {
4849
"@tauri-apps/cli": "^2"

scripts/checks/version.mjs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// ==============================================================
2+
// One version, everywhere it is written
3+
//
4+
// The version is written in five places: three build files that decide what the
5+
// binary reports, and two labels in the shell that decide what the user reads —
6+
// the badge in the title bar and the line on the loading screen.
7+
//
8+
// v2.5.0 shipped with the build files bumped and both labels still saying v2.0.
9+
// So the DMG was 2.5.0, macOS reported 2.5.0, and the app itself said 2.0 in the
10+
// two places anyone actually looks. A user who checks the version to find out
11+
// whether they have the fixes was told the wrong answer by the product while the
12+
// installer told them the right one.
13+
//
14+
// Nothing could catch that. The labels are plain text in markup; they are correct
15+
// right up until a release, and a release is exactly when nobody is reading the
16+
// markup.
17+
//
18+
// So: all five agree, or this fails. The build files carry the full `major.minor.patch`;
19+
// the labels may carry either that or `major.minor`, because a title bar has
20+
// little room and "v2.5" is not a lie about 2.5.0 — it is the same version, said
21+
// shorter. `v2.4` would be.
22+
//
23+
// Run with: npm run check:version
24+
// ==============================================================
25+
import { readFileSync } from 'node:fs';
26+
import { fileURLToPath } from 'node:url';
27+
import { dirname, join } from 'node:path';
28+
29+
const here = dirname(fileURLToPath(import.meta.url));
30+
const root = join(here, '..', '..');
31+
const read = (f) => readFileSync(join(root, f), 'utf8');
32+
33+
let pass = 0, fail = 0;
34+
function check(label, condition, detail = '') {
35+
if (condition) { pass++; console.log(` ok ${label}`); }
36+
else { fail++; console.log(` FAIL ${label}${detail ? ' — ' + detail : ''}`); }
37+
}
38+
39+
// tauri.conf.json is the one the bundler reads, so it is the answer the others
40+
// have to match rather than a fourth opinion. It carries comments, so it is read
41+
// the same way csp.mjs reads it — as text — rather than through JSON.parse,
42+
// which refuses it.
43+
const tauri = (read('src-tauri/tauri.conf.json').match(/"version"\s*:\s*"([^"]+)"/) || [])[1];
44+
const npm = JSON.parse(read('package.json')).version;
45+
const cargo = (read('src-tauri/Cargo.toml').match(/^version\s*=\s*"([^"]+)"/m) || [])[1];
46+
47+
console.log(`\nThe build files agree on a version (${tauri}):`);
48+
check('package.json', npm === tauri, `says ${npm}`);
49+
check('src-tauri/Cargo.toml', cargo === tauri, `says ${cargo}`);
50+
check('the version looks like a version', /^\d+\.\d+\.\d+$/.test(tauri), `got "${tauri}"`);
51+
52+
// What the user reads.
53+
const shell = read('src/index.html');
54+
const badge = (shell.match(/class="hc-toolbar-badge"[^>]*>v?([\d.]+)</) || [])[1];
55+
const patch = (shell.match(/class="patch-badge">[^<]*?v([\d.]+)/) || [])[1];
56+
57+
/** `2.5` and `2.5.0` are the same version written at different lengths. */
58+
const sameVersion = (shown) => shown === tauri || tauri.startsWith(shown + '.');
59+
60+
console.log('\nWhat the app tells the user matches what it is:');
61+
check('the title-bar badge exists', !!badge, 'no version found in the hc-toolbar-badge span');
62+
check(`the title-bar badge (v${badge})`, !!badge && sameVersion(badge),
63+
`shows v${badge}, the build is ${tauri} — this is the version a user reads to find out what they have`);
64+
check('the loading-screen line exists', !!patch, 'no version found in the patch-badge line');
65+
check(`the loading-screen line (v${patch})`, !!patch && sameVersion(patch),
66+
`shows v${patch}, the build is ${tauri}`);
67+
68+
// The loading screen also names a month. A stale month is a smaller lie than a
69+
// stale version, but it is the same kind, and it is free to check that it is not
70+
// still naming the month of a release two versions ago.
71+
const month = (shell.match(/class="patch-badge">[^<]*?·\s*([A-Z][a-z]+ \d{4})/) || [])[1];
72+
check('the loading screen names a month', !!month, 'no month found on the patch-badge line');
73+
74+
console.log(`\n${pass} passed, ${fail} failed (one version everywhere)`);
75+
process.exit(fail ? 1 : 0);

src/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
draggable="false"
8484
data-tauri-drag-region/>
8585
<span class="hc-toolbar-name" data-tauri-drag-region>HashCortx</span>
86-
<span class="hc-toolbar-badge" data-tauri-drag-region>v2.0</span>
86+
<span class="hc-toolbar-badge" data-tauri-drag-region>v2.5.0</span>
8787
</div>
8888

8989
<!-- Right zone: window/app actions -->
@@ -137,7 +137,7 @@
137137

138138
<!-- Bottom decoration -->
139139
<div class="timestamp" id="intro-timestamp">— · —</div>
140-
<div class="patch-badge">HashCortx v2.0 · Batch 2.0 · May 2026</div>
140+
<div class="patch-badge">HashCortx v2.5.0 · August 2026</div>
141141
<div class="perfection-quote">Massive UI · Isolated Intelligence · Agentic</div>
142142
<div class="signature">Designed By DR Seif Hashish</div>
143143
<div class="status-badge initializing" id="intro-badge">

0 commit comments

Comments
 (0)