Compare commits

...
4 Commits
Author SHA1 Message Date
LogiFlow af1e3d8aae build: numéro de release 2.0.0.1 injecté au packaging (#9)
build: numéro de release 2.0.0.1 injecté au packaging (electron-builder exige un semver)
2026-09-03 17:47:50 +02:00
Claude 2471add00b build: four-part releaseVersion (2.0.0.1) injected at packaging time
electron-builder refuses a non-semver package.json version, so the published
number lives in package.json releaseVersion and scripts/dist.mjs passes it as
extraMetadata.version (plus the hotfix digit as Windows build number). The
workflow tags and names the release from the same field.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn5VX9HNbJ7N54hR24u9Y
2026-09-03 15:47:32 +00:00
LogiFlow 35437e2d51 chore: version 2.0.0.1 et télémétrie sans fausses valeurs (#8)
chore: version 2.0.0.1 (schéma correctif à quatre chiffres) et télémétrie sans fausses valeurs
2026-09-03 17:43:37 +02:00
Claude e2c67a5770 chore: hotfix versioning 2.0.0.1 and honest telemetry placeholders when the bridge is missing
- Version numbers gain a fourth hotfix component (2.0.0.1); the workflow maps it to the
  Windows file build number.
- The system panel shows dashes instead of 0% until real measurements arrive from the
  main process.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn5VX9HNbJ7N54hR24u9Y
2026-09-03 15:43:19 +00:00
6 changed files with 34 additions and 11 deletions

No files matched your search

+5 -2
View File
@@ -43,8 +43,10 @@ jobs:
id: ver id: ver
shell: bash shell: bash
run: | run: |
version=$(node -p "require('./package.json').version") version=$(node -p "const p=require('./package.json'); p.releaseVersion || p.version")
echo "version=$version" >> "$GITHUB_OUTPUT" echo "version=$version" >> "$GITHUB_OUTPUT"
# Fourth component (hotfix number, e.g. 2.0.0.1) becomes the Windows file build number.
echo "build=$(echo "$version" | cut -d. -f4)" >> "$GITHUB_OUTPUT"
if git ls-remote --exit-code --tags origin "refs/tags/v$version" >/dev/null 2>&1; then if git ls-remote --exit-code --tags origin "refs/tags/v$version" >/dev/null 2>&1; then
echo "released=true" >> "$GITHUB_OUTPUT" echo "released=true" >> "$GITHUB_OUTPUT"
else else
@@ -52,9 +54,10 @@ jobs:
fi fi
- run: npm run build - run: npm run build
- name: Package Windows EXE - name: Package Windows EXE
run: npx electron-builder --win --publish never run: npm run dist -- --win --publish never
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_NUMBER: ${{ steps.ver.outputs.build }}
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: EveFlow-Windows-v${{ steps.ver.outputs.version }} name: EveFlow-Windows-v${{ steps.ver.outputs.version }}
+2 -2
View File
@@ -96,13 +96,13 @@ npm run typecheck # renderer + main process
Sans Electron, `npm run dev` puis `http://127.0.0.1:5173/` (ou `?mode=compact`) permet de travailler l'interface dans un navigateur ; les appels réseau passent alors directement par `fetch` (CORS requis côté serveur). Sans Electron, `npm run dev` puis `http://127.0.0.1:5173/` (ou `?mode=compact`) permet de travailler l'interface dans un navigateur ; les appels réseau passent alors directement par `fetch` (CORS requis côté serveur).
## Packaging Windows ## Packaging Windows et versions
```bash ```bash
npm run dist npm run dist
``` ```
L'installateur NSIS est produit dans `out/`. Le workflow GitHub Actions construit l'exécutable sur chaque tag `v*`. L'installateur NSIS est produit dans `out/`. Le numéro de version publié est `releaseVersion` dans `package.json` (quatre chiffres, ex. `2.0.0.1` : le quatrième chiffre sert aux petits correctifs). `version` reste la base à trois chiffres exigée par electron-builder. À chaque fusion sur master, le workflow GitHub Actions crée le tag et la release Windows si ce numéro n'a pas encore été publié.
--- ---
+3 -2
View File
@@ -1,6 +1,7 @@
{ {
"name": "eveflow", "name": "eveflow",
"version": "2.0.2", "version": "2.0.0",
"releaseVersion": "2.0.0.1",
"description": "JARVIS-style desktop HUD for Hermes Agent: voice, streaming runs, scheduled jobs, skills and telemetry", "description": "JARVIS-style desktop HUD for Hermes Agent: voice, streaming runs, scheduled jobs, skills and telemetry",
"main": "dist-electron/main.js", "main": "dist-electron/main.js",
"private": true, "private": true,
@@ -16,7 +17,7 @@
"electron": "electron .", "electron": "electron .",
"start": "npm run build:electron && concurrently -k -s first \"npm run dev\" \"wait-on http://127.0.0.1:5173 && cross-env NODE_ENV=development VITE_DEV_SERVER_URL=http://127.0.0.1:5173 electron .\"", "start": "npm run build:electron && concurrently -k -s first \"npm run dev\" \"wait-on http://127.0.0.1:5173 && cross-env NODE_ENV=development VITE_DEV_SERVER_URL=http://127.0.0.1:5173 electron .\"",
"preview": "vite preview", "preview": "vite preview",
"dist": "npm run build && electron-builder --win --publish never", "dist": "node scripts/dist.mjs",
"typecheck:electron": "tsc -p tsconfig.electron.json --noEmit" "typecheck:electron": "tsc -p tsconfig.electron.json --noEmit"
}, },
"build": { "build": {
+16
View File
@@ -0,0 +1,16 @@
// Packages the app with electron-builder using the four-part release version
// (package.json "releaseVersion", e.g. 2.0.0.1). package.json "version" must stay semver.
import { spawnSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
const release = pkg.releaseVersion || pkg.version;
const build = release.split('.')[3] ?? '0';
const args = process.argv.slice(2);
if (!args.some((a) => a.startsWith('--win') || a.startsWith('--linux') || a.startsWith('--mac'))) args.unshift('--win');
const result = spawnSync('npx', ['electron-builder', ...args, `--config.extraMetadata.version=${release}`], {
stdio: 'inherit',
shell: process.platform === 'win32',
env: { ...process.env, BUILD_NUMBER: process.env.BUILD_NUMBER ?? build }
});
process.exit(result.status ?? 1);
+3 -3
View File
@@ -28,11 +28,11 @@ export function Telemetry() {
<Activity size={14} /> <Activity size={14} />
<span>Système</span> <span>Système</span>
<span className="spacer" /> <span className="spacer" />
<span className="chip">{m.hostname}</span> <span className="chip">{m.live ? m.hostname : 'HORS PONT'}</span>
</header> </header>
<div className="telemetry"> <div className="telemetry">
<Gauge value={m.cpuLoad} max={100} label="CPU" display={`${Math.round(m.cpuLoad)}%`} warn={90} /> <Gauge value={m.cpuLoad} max={100} label="CPU" display={m.live ? `${Math.round(m.cpuLoad)}%` : '—'} warn={90} />
<Gauge value={m.memUsedPct} max={100} label="RAM" display={`${Math.round(m.memUsedPct)}%`} warn={92} /> <Gauge value={m.memUsedPct} max={100} label="RAM" display={m.live ? `${Math.round(m.memUsedPct)}%` : '—'} warn={92} />
<Gauge value={m.fps} max={60} label="FPS" display={`${m.fps}`} /> <Gauge value={m.fps} max={60} label="FPS" display={`${m.fps}`} />
<Gauge value={m.cpuFreqMhz} max={5500} label="GHz" display={m.cpuFreqMhz ? (m.cpuFreqMhz / 1000).toFixed(1) : '—'} /> <Gauge value={m.cpuFreqMhz} max={5500} label="GHz" display={m.cpuFreqMhz ? (m.cpuFreqMhz / 1000).toFixed(1) : '—'} />
</div> </div>
+5 -2
View File
@@ -4,6 +4,8 @@ import { bridge } from '../lib/bridge';
export interface LiveMetrics extends SystemMetrics { export interface LiveMetrics extends SystemMetrics {
fps: number; fps: number;
/** false until the main process delivered real measurements */
live: boolean;
} }
const EMPTY: LiveMetrics = { const EMPTY: LiveMetrics = {
@@ -16,7 +18,8 @@ const EMPTY: LiveMetrics = {
memUsedPct: 0, memUsedPct: 0,
memTotalGb: 0, memTotalGb: 0,
uptimeSec: 0, uptimeSec: 0,
fps: 60 fps: 60,
live: false
}; };
export function useMetrics(enabled = true, intervalMs = 2000): LiveMetrics { export function useMetrics(enabled = true, intervalMs = 2000): LiveMetrics {
@@ -43,7 +46,7 @@ export function useMetrics(enabled = true, intervalMs = 2000): LiveMetrics {
const api = bridge(); const api = bridge();
const poll = () => { const poll = () => {
if (!api) return; if (!api) return;
api.system.metrics().then((m) => setMetrics((prev) => ({ ...prev, ...m }))).catch(() => undefined); api.system.metrics().then((m) => setMetrics((prev) => ({ ...prev, ...m, live: true }))).catch(() => undefined);
}; };
poll(); poll();
const timer = setInterval(poll, intervalMs); const timer = setInterval(poll, intervalMs);