cursedbelt 5.76.0 → 5.77.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.
@@ -35,7 +35,8 @@ import './buildFreshness.css';
35
35
  export interface UseBuildFreshnessOptions {
36
36
  /**
37
37
  * Where the serving build identifies itself. Any JSON answering
38
- * `{ build: { commitFull } }` — every satellite's health route does.
38
+ * `{ build: { commitFull } }` — every satellite's health route does — or a client build
39
+ * stamp's `{ commit }` (`/build.json`, `forge-client stamp`).
39
40
  */
40
41
  probeUrl?: string;
41
42
  /** Poll interval for a visible tab, in ms. */
@@ -1 +1 @@
1
- {"version":3,"file":"BuildFreshness.d.ts","sourceRoot":"","sources":["../../../src/react/components/BuildFreshness.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,sBAAsB,CAAC;AAgB9B,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,KAAK,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAeD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAqB,EACrB,UAAoB,EACpB,OAAc,GACf,GAAE,wBAA6B,GAAG,cAAc,CAoDhD;AAED,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,QAAqB,EACrB,QAAQ,EACR,GAAG,OAAO,EACX,GAAE,yBAA8B,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CA+BrD"}
1
+ {"version":3,"file":"BuildFreshness.d.ts","sourceRoot":"","sources":["../../../src/react/components/BuildFreshness.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,sBAAsB,CAAC;AAgB9B,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,KAAK,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAuBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAqB,EACrB,UAAoB,EACpB,OAAc,GACf,GAAE,wBAA6B,GAAG,cAAc,CAoDhD;AAED,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,QAAqB,EACrB,QAAQ,EACR,GAAG,OAAO,EACX,GAAE,yBAA8B,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CA+BrD"}
@@ -14,13 +14,20 @@ const POLL_MS = 5 * 60_000;
14
14
  * fast as the events land.
15
15
  */
16
16
  const MIN_GAP_MS = 30_000;
17
- /** The one shape read out of a health payload, defensively. */
17
+ /**
18
+ * The commit out of a health payload or a client build stamp, defensively.
19
+ *
20
+ * Two shapes, one identity: a satellite's `/healthz` nests it (`{ build: { commitFull } }`), and
21
+ * the CLIENT's own stamp — `forge-client stamp`'s `dist/build.json` (cursedops `stagedClient.ts`)
22
+ * — carries it at the top (`{ commit }`). The stamp is the better probe for an app whose health
23
+ * route answers for a server that ships on its own clock (roms' `/healthz` is its Mac's): it is a
24
+ * static file of the very build this tab loaded (forge 2026-10-10, task 3022).
25
+ */
18
26
  function commitOf(payload) {
19
27
  if (typeof payload !== 'object' || payload === null)
20
28
  return null;
21
- const build = payload.build;
22
- if (typeof build !== 'object' || build === null)
23
- return null;
29
+ const nested = payload.build;
30
+ const build = typeof nested === 'object' && nested !== null ? nested : payload;
24
31
  const full = build.commitFull;
25
32
  const short = build.commit;
26
33
  const value = typeof full === 'string' && full ? full : typeof short === 'string' ? short : '';
@@ -1 +1 @@
1
- {"version":3,"file":"BuildFreshness.js","sourceRoot":"","sources":["../../../src/react/components/BuildFreshness.tsx"],"names":[],"mappings":";AAiCA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,0DAA0D;AAC1D,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC;AAE3B;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,MAAM,CAAC;AAuB1B,+DAA+D;AAC/D,SAAS,QAAQ,CAAC,OAAgB;IAChC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,KAAK,GAAI,OAA+B,CAAC,KAAK,CAAC;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7D,MAAM,IAAI,GAAI,KAAkC,CAAC,UAAU,CAAC;IAC5D,MAAM,KAAK,GAAI,KAA8B,CAAC,MAAM,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,2FAA2F;IAC3F,wFAAwF;IACxF,OAAO,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,QAAQ,GAAG,UAAU,EACrB,UAAU,GAAG,OAAO,EACpB,OAAO,GAAG,IAAI,MACc,EAAE;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QACtD,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;YACtC,IAAI,SAAS,IAAI,QAAQ,CAAC,eAAe,KAAK,QAAQ;gBAAE,OAAO;YAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,8EAA8E;YAC9E,+EAA+E;YAC/E,iFAAiF;YACjF,uEAAuE;YACvE,IAAI,GAAG,GAAG,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC;gBAAE,OAAO;YACzE,WAAW,CAAC,OAAO,GAAG,GAAG,CAAC;YAC1B,IAAI,CAAC;gBACH,mFAAmF;gBACnF,8EAA8E;gBAC9E,qEAAqE;gBACrE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC1F,IAAI,CAAC,QAAQ,CAAC,EAAE;oBAAE,OAAO;gBACzB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/C,IAAI,SAAS,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACjC,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBACzB,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI;oBAAE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;qBAChD,IAAI,MAAM,CAAC,OAAO,KAAK,MAAM;oBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrD,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;gBACjF,iFAAiF;YACnF,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,KAAK,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC;QAClC,wFAAwF;QACxF,4EAA4E;QAC5E,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzC,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;YACjB,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;YACzD,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEpC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;AAChE,CAAC;AASD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,QAAQ,GAAG,UAAU,EACrB,QAAQ,EACR,GAAG,OAAO,KACmB,EAAE;IAC/B,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,IAAI,QAAQ;YAAE,QAAQ,EAAE,CAAC;;YACpB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAChC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,IAAI,CAAC,KAAK,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAErC,OAAO,CACL,eAAK,SAAS,EAAC,UAAU,EAAC,IAAI,EAAC,QAAQ,eAAW,QAAQ,aACxD,eAAM,SAAS,EAAC,UAAU,iBAAa,MAAM,GAAG,EAChD,gBAAM,SAAS,EAAC,WAAW,aACxB,QAAQ,qEACJ,EACP,KAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAC,uCAAuC,uBAEzE,EACT,KAAC,UAAU,IACT,KAAK,EAAC,SAAS,EACf,OAAO,EAAC,iCAAiC,EACzC,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,YAEjC,KAAC,CAAC,IAAC,SAAS,EAAC,QAAQ,GAAG,GACb,IACT,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"BuildFreshness.js","sourceRoot":"","sources":["../../../src/react/components/BuildFreshness.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.76.0",
3
+ "version": "5.77.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -62,6 +62,16 @@ describe('BuildFreshnessNotice', () => {
62
62
  expect(screen.getByRole('button', { name: /Reload/i })).toBeDefined();
63
63
  });
64
64
 
65
+ test('🔴 speaks off a CLIENT build stamp too — `/build.json`\'s top-level `{ commit }`', async () => {
66
+ // `forge-client stamp` writes the client's own commit at the top of `dist/build.json`. roms
67
+ // probes it (its `/healthz` is its Mac's), and a TV tab kept the old build for 84 minutes
68
+ // after a fast-lane ship because nothing read it twice (forge task 3022, 2026-10-10).
69
+ const stamp = (commit: string) => ({ commit, dirty: false });
70
+ healthzServing([stamp('a'.repeat(40)), stamp('b'.repeat(40))]);
71
+ render(<BuildFreshnessNotice intervalMs={5} probeUrl='/build.json' appLabel='ROMs' />);
72
+ await waitFor(() => expect(screen.queryByText(/ROMs was updated/i)).not.toBeNull(), { timeout: 2_000 });
73
+ });
74
+
65
75
  test('stays silent when the probe fails — offline, or a 502 mid-deploy', async () => {
66
76
  healthzServing([build('aaaaaaaaaaaa'), new TypeError('Failed to fetch')]);
67
77
  render(<BuildFreshnessNotice intervalMs={5} />);
@@ -52,7 +52,8 @@ const MIN_GAP_MS = 30_000;
52
52
  export interface UseBuildFreshnessOptions {
53
53
  /**
54
54
  * Where the serving build identifies itself. Any JSON answering
55
- * `{ build: { commitFull } }` — every satellite's health route does.
55
+ * `{ build: { commitFull } }` — every satellite's health route does — or a client build
56
+ * stamp's `{ commit }` (`/build.json`, `forge-client stamp`).
56
57
  */
57
58
  probeUrl?: string;
58
59
  /** Poll interval for a visible tab, in ms. */
@@ -70,11 +71,19 @@ export interface BuildFreshness {
70
71
  servingCommit: string | null;
71
72
  }
72
73
 
73
- /** The one shape read out of a health payload, defensively. */
74
+ /**
75
+ * The commit out of a health payload or a client build stamp, defensively.
76
+ *
77
+ * Two shapes, one identity: a satellite's `/healthz` nests it (`{ build: { commitFull } }`), and
78
+ * the CLIENT's own stamp — `forge-client stamp`'s `dist/build.json` (cursedops `stagedClient.ts`)
79
+ * — carries it at the top (`{ commit }`). The stamp is the better probe for an app whose health
80
+ * route answers for a server that ships on its own clock (roms' `/healthz` is its Mac's): it is a
81
+ * static file of the very build this tab loaded (forge 2026-10-10, task 3022).
82
+ */
74
83
  function commitOf(payload: unknown): string | null {
75
84
  if (typeof payload !== 'object' || payload === null) return null;
76
- const build = (payload as { build?: unknown }).build;
77
- if (typeof build !== 'object' || build === null) return null;
85
+ const nested = (payload as { build?: unknown }).build;
86
+ const build = typeof nested === 'object' && nested !== null ? nested : payload;
78
87
  const full = (build as { commitFull?: unknown }).commitFull;
79
88
  const short = (build as { commit?: unknown }).commit;
80
89
  const value = typeof full === 'string' && full ? full : typeof short === 'string' ? short : '';