diff --git a/CHANGELOG.md b/CHANGELOG.md index b925e734..6dbd45ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* **fleet:** fix version detection returning stale value from `generated/version.ts` instead of the authoritative `package.json`. This caused remote nodes to show "unknown" version and false "Update available" badges when both nodes were on the same version. `resolveVersion()` now reads the root `package.json` first and only falls back to the build-time constant if the walk fails. * **fleet:** fix permanently stuck "Timed out" / "Failed" badges after node update attempts. The in-memory update tracker now supports clearing via a new DELETE endpoint, and terminal states are automatically clearable through the Recheck button. * **fleet:** fix update completion detection for remote nodes that cannot report their version. The gateway now uses three completion signals: version change, process restart detection (`startedAt`), and offline/online detection (node went unreachable during update and came back). This eliminates false timeouts on nodes running older Sencho versions. * **fleet:** fix 409 race condition where retrying a timed-out update was rejected because the tracker still showed "updating". The POST trigger now detects expired timeouts and allows re-triggering. diff --git a/backend/src/services/CapabilityRegistry.ts b/backend/src/services/CapabilityRegistry.ts index 2a1435c5..760d8245 100644 --- a/backend/src/services/CapabilityRegistry.ts +++ b/backend/src/services/CapabilityRegistry.ts @@ -43,9 +43,9 @@ export function isValidVersion(v: string | null | undefined): v is string { // Resolved once per process at import time, then cached. function resolveVersion(): string | null { - if (SENCHO_VERSION !== '0.0.0-dev') return SENCHO_VERSION; - - // Fallback for manual ts-node runs without the predev hook. + // Primary: walk up to find the root package.json (always authoritative). + // The generated SENCHO_VERSION constant can be stale when a branch falls + // behind a release-please version bump, so we prefer the live value. let dir = __dirname; for (let i = 0; i < 5; i++) { const candidate = path.join(dir, 'package.json'); @@ -55,6 +55,8 @@ function resolveVersion(): string | null { } catch { /* not found, keep walking */ } dir = path.dirname(dir); } + // Fallback: build-time constant (may be stale in dev, but correct in Docker) + if (SENCHO_VERSION !== '0.0.0-dev') return SENCHO_VERSION; console.warn('[CapabilityRegistry] Could not resolve Sencho version from any source'); return null; } diff --git a/docs/images/fleet-view/fleet-node-updates.png b/docs/images/fleet-view/fleet-node-updates.png index 2435e8d7..07a2ae52 100644 Binary files a/docs/images/fleet-view/fleet-node-updates.png and b/docs/images/fleet-view/fleet-node-updates.png differ diff --git a/docs/operations/troubleshooting.mdx b/docs/operations/troubleshooting.mdx index 370d6123..4b7501b4 100644 --- a/docs/operations/troubleshooting.mdx +++ b/docs/operations/troubleshooting.mdx @@ -389,6 +389,20 @@ docker compose pull && docker compose up -d --- +## Remote node version shows "unknown" + +**Symptom:** A remote node appears online in the Fleet View but its version badge is missing or the Node Updates modal shows "unknown" in the current version column. + +**Common causes:** + +1. **Network issue:** The gateway cannot reach the remote node's `/api/meta` endpoint. Check that the API URL configured for the node is correct and accessible from the gateway host. +2. **Old Sencho version:** Nodes running Sencho versions older than v0.39.0 do not report a version in their metadata. Update the remote node manually to resolve this. +3. **Development build:** If running from source, ensure you have run `npm install` in the backend directory so the `predev` hook regenerates the version file. + +**To verify:** Open your browser's developer tools and check the response from `GET /api/fleet/update-status`. Each node's `version` field should contain a semver string (e.g., `"0.39.4"`). If it shows `null`, the gateway could not determine the remote's version. + +--- + ## Stack labels are not visible in the sidebar **Symptom:** You assigned labels to stacks but no label pills appear in the sidebar.