@pleri/olam-cli 0.1.85 → 0.1.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  {
2
- "auth": "sha256:ee6b1d1046933c76acc8d28cd83ac3871bc69057d2401014252872dc5ec42db7",
3
- "devbox": "sha256:0b7a8ed93e55bec3cd12351689a6213daa87a9fc7531b9dfcfb0513ba62add61",
4
- "host-cp": "sha256:c83cf8649893661b42266bc5bba9110e2067395c27dd02713179a3717a389cf3",
2
+ "auth": "sha256:acd77f9b4b2764841207e6e749e0bd5044843458f789eb5548cb4363d02fb985",
3
+ "devbox": "sha256:edda28d8b75bd1d6aaa599100b97d83260bae05b3e81949c95b2f9192b1cfa04",
4
+ "host-cp": "sha256:6bd8927957fb2ee1aeaf372738814953e49c247c38663ea372c570e2c0795c58",
5
5
  "mcp-auth": "sha256:e47169ad3fbc9cab216248fecbc56874343a5daab84b1f18d67529b7d415cf95",
6
6
  "$schema_version": 1,
7
- "$published_version": "0.1.85",
7
+ "$published_version": "0.1.87",
8
8
  "$registry": "ghcr.io/pleri"
9
9
  }
@@ -120,6 +120,45 @@ export async function fetchAuthServiceSha(authServiceUrl) {
120
120
  }
121
121
  }
122
122
 
123
+ /**
124
+ * Inspect a locally-tagged docker image (by reference such as
125
+ * `ghcr.io/pleri/olam-host-cp:latest`) and extract its baked
126
+ * OLAM_BUILD_SHA env. Returns 'unknown' if the image isn't pulled,
127
+ * the docker socket is unreachable, or the env is missing.
128
+ *
129
+ * Used as the "what's the latest published image we'd swap to?"
130
+ * signal for the upgrade comparator — replaces the prior
131
+ * `operatorHead` (operator's local git HEAD) which over-reports
132
+ * upgradeAvailable whenever an SPA-only PR merges between releases.
133
+ *
134
+ * @param {string} dockerApiBase
135
+ * @param {string} imageRef e.g. "ghcr.io/pleri/olam-host-cp:latest"
136
+ * @returns {Promise<string>}
137
+ */
138
+ export async function fetchLatestImageSha(dockerApiBase, imageRef) {
139
+ try {
140
+ const res = await fetch(
141
+ `${dockerApiBase}/images/${encodeURIComponent(imageRef)}/json`,
142
+ { signal: AbortSignal.timeout(5000) },
143
+ );
144
+ if (!res.ok) return 'unknown';
145
+ const image = /** @type {unknown} */ (await res.json());
146
+ if (!image || typeof image !== 'object') return 'unknown';
147
+ const config = /** @type {Record<string, unknown>} */ (image)['Config'];
148
+ if (!config || typeof config !== 'object') return 'unknown';
149
+ const env = /** @type {Record<string, unknown>} */ (config)['Env'];
150
+ if (!Array.isArray(env)) return 'unknown';
151
+ for (const e of env) {
152
+ if (typeof e === 'string' && e.startsWith('OLAM_BUILD_SHA=')) {
153
+ return e.slice('OLAM_BUILD_SHA='.length);
154
+ }
155
+ }
156
+ return 'unknown';
157
+ } catch {
158
+ return 'unknown';
159
+ }
160
+ }
161
+
123
162
  /**
124
163
  * Fetch the devbox image SHA. We check the running devbox container's
125
164
  * OLAM_BUILD_SHA env var via the docker socket proxy (inspect endpoint).
@@ -181,13 +220,30 @@ export async function fetchDevboxImageSha(dockerApiBase) {
181
220
  export async function buildVersionSnapshot({ authServiceUrl, dockerApiBase }) {
182
221
  const operatorHead = readOperatorHead();
183
222
 
184
- const [authSha, devboxSha] = await Promise.all([
185
- fetchAuthServiceSha(authServiceUrl),
186
- fetchDevboxImageSha(dockerApiBase),
187
- ]);
223
+ // Inspect locally-pulled `:latest` image tags to get the actual
224
+ // published baked SHA — what `olam upgrade` would swap us to next.
225
+ // Fall back to operatorHead when the image isn't pulled (first-run
226
+ // or stack never upgraded) so the banner still surfaces SOMETHING.
227
+ const [authSha, devboxSha, hostCpLatestPublished, authLatestPublished, devboxLatestPublished] =
228
+ await Promise.all([
229
+ fetchAuthServiceSha(authServiceUrl),
230
+ fetchDevboxImageSha(dockerApiBase),
231
+ fetchLatestImageSha(dockerApiBase, 'ghcr.io/pleri/olam-host-cp:latest'),
232
+ fetchLatestImageSha(dockerApiBase, 'ghcr.io/pleri/olam-auth-service:latest'),
233
+ fetchLatestImageSha(dockerApiBase, 'ghcr.io/pleri/olam-devbox:latest'),
234
+ ]);
188
235
 
189
236
  const hostCpRunning = process.env.OLAM_BUILD_SHA ?? 'unknown';
190
237
 
238
+ // Pick "latest" per component: use the published image SHA when we
239
+ // can read it (truthful — that's what would swap in), else fall back
240
+ // to operatorHead (legacy behaviour, may over-report between SPA-only
241
+ // PR merges and the next image rebuild — but still informative when
242
+ // the operator hasn't yet pulled `:latest`).
243
+ const hostCpLatest = pickLatest(hostCpLatestPublished, operatorHead);
244
+ const authLatest = pickLatest(authLatestPublished, operatorHead);
245
+ const devboxLatest = pickLatest(devboxLatestPublished, operatorHead);
246
+
191
247
  // CLI version is propagated by `olam host-cp start` via the
192
248
  // OLAM_CLI_VERSION env (see packages/cli/src/commands/host-cp.ts
193
249
  // buildComposeEnv). Falls back to host-cp's own package.json when
@@ -199,18 +255,18 @@ export async function buildVersionSnapshot({ authServiceUrl, dockerApiBase }) {
199
255
  return {
200
256
  hostCp: {
201
257
  running: hostCpRunning,
202
- latest: operatorHead,
203
- upgradeAvailable: isUpgradeAvailable(hostCpRunning, operatorHead),
258
+ latest: hostCpLatest,
259
+ upgradeAvailable: isUpgradeAvailable(hostCpRunning, hostCpLatest),
204
260
  },
205
261
  authService: {
206
262
  running: authSha,
207
- latest: operatorHead,
208
- upgradeAvailable: isUpgradeAvailable(authSha, operatorHead),
263
+ latest: authLatest,
264
+ upgradeAvailable: isUpgradeAvailable(authSha, authLatest),
209
265
  },
210
266
  devbox: {
211
267
  running: devboxSha,
212
- latest: operatorHead,
213
- upgradeAvailable: isUpgradeAvailable(devboxSha, operatorHead),
268
+ latest: devboxLatest,
269
+ upgradeAvailable: isUpgradeAvailable(devboxSha, devboxLatest),
214
270
  },
215
271
  operatorHead,
216
272
  checkedAt: new Date().toISOString(),
@@ -218,6 +274,21 @@ export async function buildVersionSnapshot({ authServiceUrl, dockerApiBase }) {
218
274
  };
219
275
  }
220
276
 
277
+ /**
278
+ * Prefer the published-image SHA (truthful "would swap to") over the
279
+ * operator's local git HEAD (over-reports when SPA-only PRs land
280
+ * between image rebuilds). Falls back to operatorHead when the image
281
+ * isn't pulled (e.g. cold-start before first `olam upgrade`).
282
+ *
283
+ * @param {string} publishedImageSha
284
+ * @param {string} operatorHead
285
+ * @returns {string}
286
+ */
287
+ export function pickLatest(publishedImageSha, operatorHead) {
288
+ if (publishedImageSha && publishedImageSha !== 'unknown') return publishedImageSha;
289
+ return operatorHead;
290
+ }
291
+
221
292
  /**
222
293
  * Read host-cp's bundled package.json version as the CLI-version
223
294
  * fallback when OLAM_CLI_VERSION isn't propagated. The container
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"