@gotcos/glasses-server 6.27.13 → 6.29.0

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.
@@ -61,6 +61,14 @@ import { getMeetingFinalizationSnapshot } from '../lib/meeting-finalization-jobs
61
61
  import { resolveMeetingLibrary } from '../lib/cos-operations-meetings.js'
62
62
  import { videoUploadV2Capability } from '../lib/video-upload-v2.js'
63
63
  import { MAX_MODEL_IMAGE_INPUTS } from '../lib/query-attachments.js'
64
+ // Continue-vs-Fork is decided before a thread is named, so it cannot be
65
+ // discovered from the per-thread attachability probe. ABSENT MEANS DISABLED on
66
+ // all three fields: an older server omits them and every client must read that as
67
+ // off. The rule, and the only sanctioned reader of it, live in the module.
68
+ import {
69
+ threadAttachCapability,
70
+ threadAttachHealthFields,
71
+ } from '../lib/thread-attach-capability.js'
64
72
 
65
73
  export const healthRouter = Router()
66
74
 
@@ -275,9 +283,19 @@ healthRouter.get('/health', async (_req, res) => {
275
283
  })),
276
284
  }
277
285
  const meetingLibrary = resolveMeetingLibrary()
286
+ // Read per request. In production this is the same answer the bindings router
287
+ // resolved at boot — server/bootstrap.js populates process.env before either
288
+ // module is imported — so the two cannot disagree.
289
+ //
290
+ // NAMED GAP: route registration IS resolved once, at wiring time. Something
291
+ // mutating process.env after boot would make this field lead the routes. The
292
+ // blast radius is a Continue button that 404s, never a write: the attach route
293
+ // is its own gate and an unregistered route cannot be talked into running.
294
+ const threadAttach = threadAttachCapability()
278
295
  res.json({
279
296
  ...checks,
280
297
  server_version: managedServerVersion(),
298
+ ...threadAttachHealthFields(threadAttach),
281
299
  server_instance_id: getServerInstanceId(),
282
300
  boot_id: serverMetrics.bootId,
283
301
  generation_id: getServerGenerationId(),
@@ -370,8 +388,14 @@ healthRouter.get('/models', async (req, res) => {
370
388
  const richMedia = await getRichMediaProcessingCapabilities()
371
389
  const videoUploadV2 = videoUploadV2Capability(richMedia.video)
372
390
  const cursorOptions = cursorCatalog.options.filter(option => !!option.id)
391
+ // Same helper and the same three key names as /api/health, for the reason
392
+ // liveCues carries three lines below: the companion's 15s liveness poll reads
393
+ // THIS surface and Main.ts states outright that /api/health alone is not used,
394
+ // so a capability published only there is invisible to the phone.
395
+ const threadAttach = threadAttachCapability()
373
396
  res.json({
374
397
  ...catalog,
398
+ ...threadAttachHealthFields(threadAttach),
375
399
  options: [
376
400
  ...(catalog.options ?? []),
377
401
  ...cursorOptions,