@legioncodeinc/hive 0.6.3 → 0.6.4

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.
@@ -10,6 +10,7 @@ const UNREACHABLE_RESPONSE = {
10
10
  const FleetHealthSchema = z.enum(["ok", "degraded", "unreachable", "unknown"]);
11
11
  const FleetDaemonSchema = z.object({
12
12
  name: z.string().min(1),
13
+ kind: z.enum(["daemon", "supervisor"]).optional(),
13
14
  health: FleetHealthSchema,
14
15
  escalation: z.unknown().nullable().optional()
15
16
  });
@@ -18,6 +19,20 @@ const DoctorStatusSchema = z.object({
18
19
  daemons: z.array(FleetDaemonSchema).optional().default([]),
19
20
  asOf: z.string().min(1)
20
21
  });
22
+ const DOCTOR_SUPERVISOR_NAME = "doctor";
23
+ function withDoctorSupervisorEntry(daemons, supervisorHealth) {
24
+ const normalized = daemons.map((daemon) => ({
25
+ name: daemon.name,
26
+ kind: daemon.kind,
27
+ health: daemon.health,
28
+ escalation: daemon.escalation ?? null
29
+ }));
30
+ const doctorNameMatch = (name) => name.toLowerCase() === DOCTOR_SUPERVISOR_NAME;
31
+ if (normalized.some((daemon) => doctorNameMatch(daemon.name))) {
32
+ return normalized.map((daemon) => (doctorNameMatch(daemon.name) ? { ...daemon, kind: "supervisor" } : daemon));
33
+ }
34
+ return [...normalized, { name: DOCTOR_SUPERVISOR_NAME, kind: "supervisor", health: supervisorHealth, escalation: null }];
35
+ }
21
36
  export async function fetchFleetStatus(fetchImpl = fetch, url = DOCTOR_STATUS_URL) {
22
37
  if (!isLoopbackBaseUrl(url)) {
23
38
  return UNREACHABLE_RESPONSE;
@@ -41,11 +56,7 @@ export async function fetchFleetStatus(fetchImpl = fetch, url = DOCTOR_STATUS_UR
41
56
  return {
42
57
  supervisor: "reachable",
43
58
  health: parsed.data.health,
44
- daemons: parsed.data.daemons.map((daemon) => ({
45
- name: daemon.name,
46
- health: daemon.health,
47
- escalation: daemon.escalation ?? null
48
- })),
59
+ daemons: withDoctorSupervisorEntry(parsed.data.daemons, parsed.data.health),
49
60
  asOf: parsed.data.asOf
50
61
  };
51
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fleet-status.js","sourceRoot":"","sources":["../../src/daemon/fleet-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,YAAY,EACZ,iBAAiB,EAIlB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAE3C,MAAM,oBAAoB,GAAG;IAC3B,UAAU,EAAE,aAAa;IACzB,OAAO,EAAE,EAAE;CAC2B,CAAC;AAEzC,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AAE/E,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,iBAAiB;IACzB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,iBAAiB;IACzB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAC;AAYH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,YAAuB,KAAK,EAC5B,MAAc,iBAAiB;IAE/B,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,IAAI,UAAmB,CAAC;QACxB,IAAI,CAAC;YACH,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,UAAU,EAAE,WAAW;YACvB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC1B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC5C,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;aACtC,CAAC,CAAC;YACH,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;SACvB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,oBAAoB,CAAC;IAC9B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"fleet-status.js","sourceRoot":"","sources":["../../src/daemon/fleet-status.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,16 @@
1
1
  /**
2
2
  * PRD-011a tenancy wire client: same-origin `/setup/tenancy/*` via hive's BFF proxy (no onboarding
3
3
  * token). Mirrors `onboarding-client.ts` fail-soft discipline; lives beside it in the onboarding folder.
4
+ *
5
+ * Client robustness (operator-reported incident): a stalled `/setup/tenancy*` request used to leave
6
+ * the tenancy step's `await` pending forever, an infinite spinner with no way out ("Back to
7
+ * organizations" never returning). Every call below is now bounded by
8
+ * {@link TENANCY_REQUEST_TIMEOUT_MS} via `AbortController` (generous for a slow gateway, never
9
+ * unbounded), and still fails SOFT (never throws into React): a timeout, a network error, a
10
+ * non-2xx status, or a malformed body all degrade to the same typed default the caller already
11
+ * expects, but MARKED via {@link isTenancyRequestFailure} so the step can tell a genuine empty or
12
+ * unselected read apart from a failed one and render an honest, retryable state rather than a
13
+ * misleading "nothing here" message.
4
14
  */
5
15
  import { type SetupTenancyWire, type TenancyCreateResponseWire, type TenancyOrgsWire, type TenancySelectResponseWire, type TenancyWorkspacesWire } from "./tenancy-contracts.js";
6
16
  type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
@@ -15,5 +25,17 @@ export interface TenancyClient {
15
25
  selectTenancy(orgId: string, workspaceId: string): Promise<TenancySelectResponseWire | null>;
16
26
  createWorkspace(org: string, name: string): Promise<TenancyCreateResponseWire | null>;
17
27
  }
28
+ /**
29
+ * The generous client-side bound (ms) for every `/setup/tenancy*` call. A slow gateway is normal
30
+ * and must not abort a legitimate in-flight read; a genuinely hung request is not, and must never
31
+ * leave the tenancy step's loading state spinning forever.
32
+ */
33
+ export declare const TENANCY_REQUEST_TIMEOUT_MS: 15000;
34
+ /**
35
+ * True iff `value` was returned via {@link markRequestFailed}: a timeout, network error, non-2xx
36
+ * status, or malformed body, never a genuine read. Callers use this to render an honest, retryable
37
+ * failure state instead of treating the fail-soft default (e.g. zero orgs) as the real answer.
38
+ */
39
+ export declare function isTenancyRequestFailure(value: unknown): boolean;
18
40
  export declare function createTenancyClient(options?: TenancyClientOptions): TenancyClient;
19
41
  export {};
@@ -1,58 +1,113 @@
1
1
  /**
2
2
  * PRD-011a tenancy wire client: same-origin `/setup/tenancy/*` via hive's BFF proxy (no onboarding
3
3
  * token). Mirrors `onboarding-client.ts` fail-soft discipline; lives beside it in the onboarding folder.
4
+ *
5
+ * Client robustness (operator-reported incident): a stalled `/setup/tenancy*` request used to leave
6
+ * the tenancy step's `await` pending forever, an infinite spinner with no way out ("Back to
7
+ * organizations" never returning). Every call below is now bounded by
8
+ * {@link TENANCY_REQUEST_TIMEOUT_MS} via `AbortController` (generous for a slow gateway, never
9
+ * unbounded), and still fails SOFT (never throws into React): a timeout, a network error, a
10
+ * non-2xx status, or a malformed body all degrade to the same typed default the caller already
11
+ * expects, but MARKED via {@link isTenancyRequestFailure} so the step can tell a genuine empty or
12
+ * unselected read apart from a failed one and render an honest, retryable state rather than a
13
+ * misleading "nothing here" message.
4
14
  */
5
15
  import { EMPTY_TENANCY_ORGS, EMPTY_TENANCY_WORKSPACES, SetupTenancySchema, TenancyCreateResponseSchema, TenancyOrgsSchema, TenancySelectResponseSchema, TenancyWorkspacesSchema, UNSELECTED_SETUP_TENANCY, } from "./tenancy-contracts.js";
16
+ /**
17
+ * The generous client-side bound (ms) for every `/setup/tenancy*` call. A slow gateway is normal
18
+ * and must not abort a legitimate in-flight read; a genuinely hung request is not, and must never
19
+ * leave the tenancy step's loading state spinning forever.
20
+ */
21
+ export const TENANCY_REQUEST_TIMEOUT_MS = 15_000;
22
+ const REQUEST_FAILURE_MARKER = Symbol("tenancyRequestFailure");
23
+ /**
24
+ * Stamp a FRESH copy of a fail-soft default with the failure marker (never mutates a shared
25
+ * singleton like {@link EMPTY_TENANCY_ORGS}: that object is reused across genuinely-empty reads,
26
+ * so mutating it in place would falsely mark every future empty read as failed too).
27
+ */
28
+ function markRequestFailed(value) {
29
+ return Object.defineProperty({ ...value }, REQUEST_FAILURE_MARKER, { value: true, enumerable: false });
30
+ }
31
+ /**
32
+ * True iff `value` was returned via {@link markRequestFailed}: a timeout, network error, non-2xx
33
+ * status, or malformed body, never a genuine read. Callers use this to render an honest, retryable
34
+ * failure state instead of treating the fail-soft default (e.g. zero orgs) as the real answer.
35
+ */
36
+ export function isTenancyRequestFailure(value) {
37
+ return typeof value === "object" && value !== null && value[REQUEST_FAILURE_MARKER] === true;
38
+ }
6
39
  export function createTenancyClient(options = {}) {
7
40
  const origin = options.origin ?? "";
8
41
  const fetchImpl = options.fetchImpl ?? fetch;
9
42
  const url = (path) => `${origin}${path}`;
10
43
  return {
11
44
  async setupTenancy() {
45
+ const ac = new AbortController();
46
+ const timer = setTimeout(() => ac.abort(), TENANCY_REQUEST_TIMEOUT_MS);
12
47
  try {
13
- const res = await fetchImpl(url("/setup/tenancy"), { headers: { accept: "application/json" } });
48
+ const res = await fetchImpl(url("/setup/tenancy"), { headers: { accept: "application/json" }, signal: ac.signal });
14
49
  if (!res.ok)
15
- return UNSELECTED_SETUP_TENANCY;
50
+ return markRequestFailed(UNSELECTED_SETUP_TENANCY);
16
51
  const parsed = SetupTenancySchema.safeParse(await res.json());
17
- return parsed.success ? parsed.data : UNSELECTED_SETUP_TENANCY;
52
+ return parsed.success ? parsed.data : markRequestFailed(UNSELECTED_SETUP_TENANCY);
18
53
  }
19
54
  catch {
20
- return UNSELECTED_SETUP_TENANCY;
55
+ // A timeout/abort, network error, or non-JSON body all degrade to the same fail-soft
56
+ // default, marked so the caller can tell this apart from an honest "not selected" read.
57
+ return markRequestFailed(UNSELECTED_SETUP_TENANCY);
58
+ }
59
+ finally {
60
+ clearTimeout(timer);
21
61
  }
22
62
  },
23
63
  async listOrgs() {
64
+ const ac = new AbortController();
65
+ const timer = setTimeout(() => ac.abort(), TENANCY_REQUEST_TIMEOUT_MS);
24
66
  try {
25
- const res = await fetchImpl(url("/setup/tenancy/orgs"), { headers: { accept: "application/json" } });
67
+ const res = await fetchImpl(url("/setup/tenancy/orgs"), { headers: { accept: "application/json" }, signal: ac.signal });
26
68
  if (!res.ok)
27
- return EMPTY_TENANCY_ORGS;
69
+ return markRequestFailed(EMPTY_TENANCY_ORGS);
28
70
  const parsed = TenancyOrgsSchema.safeParse(await res.json());
29
- return parsed.success ? parsed.data : EMPTY_TENANCY_ORGS;
71
+ return parsed.success ? parsed.data : markRequestFailed(EMPTY_TENANCY_ORGS);
30
72
  }
31
73
  catch {
32
- return EMPTY_TENANCY_ORGS;
74
+ return markRequestFailed(EMPTY_TENANCY_ORGS);
75
+ }
76
+ finally {
77
+ clearTimeout(timer);
33
78
  }
34
79
  },
35
80
  async listWorkspaces(orgId) {
81
+ const ac = new AbortController();
82
+ const timer = setTimeout(() => ac.abort(), TENANCY_REQUEST_TIMEOUT_MS);
83
+ const fallback = { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
36
84
  try {
37
85
  const qs = `?org=${encodeURIComponent(orgId)}`;
38
86
  const res = await fetchImpl(url(`/setup/tenancy/workspaces${qs}`), {
39
87
  headers: { accept: "application/json" },
88
+ signal: ac.signal,
40
89
  });
41
90
  if (!res.ok)
42
- return { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
91
+ return markRequestFailed(fallback);
43
92
  const parsed = TenancyWorkspacesSchema.safeParse(await res.json());
44
- return parsed.success ? parsed.data : { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
93
+ return parsed.success ? parsed.data : markRequestFailed(fallback);
45
94
  }
46
95
  catch {
47
- return { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
96
+ return markRequestFailed(fallback);
97
+ }
98
+ finally {
99
+ clearTimeout(timer);
48
100
  }
49
101
  },
50
102
  async selectTenancy(orgId, workspaceId) {
103
+ const ac = new AbortController();
104
+ const timer = setTimeout(() => ac.abort(), TENANCY_REQUEST_TIMEOUT_MS);
51
105
  try {
52
106
  const res = await fetchImpl(url("/setup/tenancy/select"), {
53
107
  method: "POST",
54
108
  headers: { "content-type": "application/json", accept: "application/json" },
55
109
  body: JSON.stringify({ orgId, workspaceId }),
110
+ signal: ac.signal,
56
111
  });
57
112
  if (!res.ok)
58
113
  return null;
@@ -60,15 +115,24 @@ export function createTenancyClient(options = {}) {
60
115
  return parsed.success ? parsed.data : null;
61
116
  }
62
117
  catch {
118
+ // A timeout/abort or network error is indistinguishable from any other soft failure
119
+ // here: `null` is already the client's typed "could not confirm" signal (the step
120
+ // renders "Selection could not be saved. Retry." and re-issues the same request).
63
121
  return null;
64
122
  }
123
+ finally {
124
+ clearTimeout(timer);
125
+ }
65
126
  },
66
127
  async createWorkspace(org, name) {
128
+ const ac = new AbortController();
129
+ const timer = setTimeout(() => ac.abort(), TENANCY_REQUEST_TIMEOUT_MS);
67
130
  try {
68
131
  const res = await fetchImpl(url("/setup/tenancy/workspaces"), {
69
132
  method: "POST",
70
133
  headers: { "content-type": "application/json", accept: "application/json" },
71
134
  body: JSON.stringify({ org, name }),
135
+ signal: ac.signal,
72
136
  });
73
137
  if (!res.ok)
74
138
  return null;
@@ -78,6 +142,9 @@ export function createTenancyClient(options = {}) {
78
142
  catch {
79
143
  return null;
80
144
  }
145
+ finally {
146
+ clearTimeout(timer);
147
+ }
81
148
  },
82
149
  };
83
150
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tenancy-client.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenancy-client.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-client.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
5
5
  */
6
6
  import React from "react";
7
7
  import { Button } from "../primitives.js";
8
- import { createTenancyClient } from "./tenancy-client.js";
8
+ import { createTenancyClient, isTenancyRequestFailure } from "./tenancy-client.js";
9
9
  /**
10
10
  * W-4 loop-breaker: how many CONSECUTIVE automatic short-circuits (hydrate reads `selected: true`
11
11
  * and the step auto-navigates to `/`) are allowed before the step stops reloading and renders a
@@ -69,6 +69,9 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
69
69
  const [view, setView] = React.useState({ kind: "loading" });
70
70
  const [busy, setBusy] = React.useState(false);
71
71
  const [selectError, setSelectError] = React.useState(null);
72
+ // The bounded action (select or create) that produced `selectError`, so the Retry affordance
73
+ // below ACTUALLY re-issues the failed request rather than merely dismissing the message.
74
+ const [selectErrorRetry, setSelectErrorRetry] = React.useState(null);
72
75
  const [createName, setCreateName] = React.useState("");
73
76
  const [showCreate, setShowCreate] = React.useState(false);
74
77
  const shownEventRef = React.useRef(false);
@@ -89,8 +92,13 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
89
92
  const loadOrgs = React.useCallback(async () => {
90
93
  setView({ kind: "loading" });
91
94
  setSelectError(null);
95
+ setSelectErrorRetry(null);
96
+ // Bounded by TENANCY_REQUEST_TIMEOUT_MS inside the client (AbortController): this await
97
+ // always settles, so "Loading your organizations…" can never spin forever, even on a
98
+ // stalled gateway. A failed/timed-out read degrades to the fail-soft default (selected:
99
+ // false), which correctly falls through to the org list attempt below.
92
100
  const status = await tenancy.setupTenancy();
93
- if (status.selected) {
101
+ if (!isTenancyRequestFailure(status) && status.selected) {
94
102
  // W-4: bound the automatic short-circuit. Each auto-navigation consumes one lap of the
95
103
  // per-tab allowance; past the limit the step stops reloading and renders the terminal
96
104
  // manual state instead, breaking the split-brain reload loop deterministically.
@@ -105,11 +113,22 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
105
113
  // bound, so a later legitimate pass through this step starts from a clean counter.
106
114
  resetTenancyAutoComplete();
107
115
  const orgsBody = await tenancy.listOrgs();
116
+ if (isTenancyRequestFailure(orgsBody)) {
117
+ // A timeout or network failure, never a genuine "zero orgs" read: an honest, clearly
118
+ // retryable state instead of the misleading "no organizations" message below.
119
+ setView({
120
+ kind: "error",
121
+ message: "Could not load your organizations. Check your connection and retry.",
122
+ onRetry: () => void loadOrgs(),
123
+ });
124
+ return;
125
+ }
108
126
  orgCountRef.current = orgsBody.orgs.length;
109
127
  if (orgsBody.orgs.length === 0) {
110
128
  setView({
111
129
  kind: "error",
112
130
  message: "No organizations are available for this account. Check your Deeplake credential and retry.",
131
+ onRetry: () => void loadOrgs(),
113
132
  });
114
133
  return;
115
134
  }
@@ -132,25 +151,42 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
132
151
  const openWorkspaces = React.useCallback(async (org) => {
133
152
  setBusy(true);
134
153
  setSelectError(null);
154
+ setSelectErrorRetry(null);
135
155
  setShowCreate(false);
136
156
  setCreateName("");
157
+ // Bounded by TENANCY_REQUEST_TIMEOUT_MS: this await always settles, so the workspace
158
+ // load can never leave the picker busy forever.
137
159
  const ws = await tenancy.listWorkspaces(org.id);
138
160
  setBusy(false);
161
+ if (isTenancyRequestFailure(ws)) {
162
+ setView({
163
+ kind: "error",
164
+ message: "Could not load workspaces for this organization. Check your connection and retry.",
165
+ onRetry: () => void openWorkspaces(org),
166
+ onBack: () => void loadOrgs(),
167
+ });
168
+ return;
169
+ }
139
170
  setView({
140
171
  kind: "workspace-list",
141
172
  org,
142
173
  workspaces: ws.workspaces,
143
174
  canCreate: ws.canCreate,
144
175
  });
145
- }, [tenancy]);
176
+ }, [tenancy, loadOrgs]);
146
177
  const persistSelection = React.useCallback(async (org, workspace) => {
147
178
  setBusy(true);
148
179
  setSelectError(null);
180
+ setSelectErrorRetry(null);
181
+ // Bounded by TENANCY_REQUEST_TIMEOUT_MS: this await always settles (a stalled select
182
+ // call can never leave the picker busy forever).
149
183
  const ack = await tenancy.selectTenancy(org.id, workspace.id);
150
184
  setBusy(false);
151
185
  if (ack === null || ack.selected === false) {
152
186
  const message = ack !== null && ack.selected === false ? ack.error : "Selection could not be saved. Retry.";
153
187
  setSelectError(message);
188
+ // The Retry affordance below re-issues THIS exact select call, not just dismisses.
189
+ setSelectErrorRetry(() => () => void persistSelection(org, workspace));
154
190
  return;
155
191
  }
156
192
  // An explicit acknowledged selection resets the W-4 loop counter: if the gate still
@@ -171,10 +207,14 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
171
207
  return;
172
208
  setBusy(true);
173
209
  setSelectError(null);
210
+ setSelectErrorRetry(null);
211
+ // Bounded by TENANCY_REQUEST_TIMEOUT_MS: this await always settles.
174
212
  const ack = await tenancy.createWorkspace(view.org.id, trimmed);
175
213
  if (ack === null || ack.created === false) {
176
214
  setBusy(false);
177
215
  setSelectError(ack !== null && ack.created === false ? ack.error : "Workspace could not be created. Retry.");
216
+ // The Retry affordance below re-issues THIS exact create call.
217
+ setSelectErrorRetry(() => () => void onCreateWorkspace());
178
218
  return;
179
219
  }
180
220
  onboardingClient.sendEvent("workspace_created");
@@ -196,7 +236,7 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
196
236
  return (_jsx("div", { "data-testid": "onboarding-tenancy-step", style: shellStyle, children: _jsx("p", { style: { fontFamily: "var(--font-mono)", fontSize: "var(--text-xs)", color: "var(--text-tertiary)" }, children: "Loading your organizations\u2026" }) }));
197
237
  }
198
238
  if (view.kind === "error") {
199
- return (_jsxs("div", { "data-testid": "onboarding-tenancy-step", style: shellStyle, children: [_jsx("p", { "data-testid": "onboarding-tenancy-error", style: { fontSize: "var(--text-sm)", color: "var(--severity-critical)", margin: 0 }, children: view.message }), _jsx(Button, { variant: "secondary", "data-testid": "onboarding-tenancy-retry", onClick: () => void loadOrgs(), children: "Retry" })] }));
239
+ return (_jsxs("div", { "data-testid": "onboarding-tenancy-step", style: shellStyle, children: [_jsx("p", { "data-testid": "onboarding-tenancy-error", style: { fontSize: "var(--text-sm)", color: "var(--severity-critical)", margin: 0 }, children: view.message }), _jsx(Button, { variant: "secondary", "data-testid": "onboarding-tenancy-retry", onClick: () => view.onRetry(), children: "Retry" }), view.onBack !== undefined && (_jsx(Button, { variant: "ghost", "data-testid": "onboarding-tenancy-error-back", onClick: () => view.onBack?.(), children: "Back to organizations" }))] }));
200
240
  }
201
241
  // W-4: the terminal state past the auto short-circuit bound. No automatic reload happens from
202
242
  // here; every further attempt is an explicit operator action.
@@ -218,6 +258,14 @@ export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride,
218
258
  color: "var(--text-primary)",
219
259
  fontFamily: "var(--font-sans)",
220
260
  fontSize: "var(--text-sm)",
221
- } }), _jsx(Button, { variant: "primary", "data-testid": "onboarding-tenancy-create-submit", disabled: busy || createName.trim() === "", onClick: () => void onCreateWorkspace(), children: "Create and select" })] })) })), view.workspaces.length > 0 && orgCountRef.current > 1 && (_jsx(Button, { variant: "ghost", "data-testid": "onboarding-tenancy-back-orgs", disabled: busy, onClick: () => void loadOrgs(), children: "Back to organizations" }))] }))] })), selectError !== null && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, alignItems: "center" }, children: [_jsx("p", { "data-testid": "onboarding-tenancy-select-error", style: { fontSize: "var(--text-sm)", color: "var(--severity-critical)", margin: 0 }, children: selectError }), _jsx(Button, { variant: "secondary", size: "sm", "data-testid": "onboarding-tenancy-select-retry", onClick: () => setSelectError(null), children: "Dismiss" })] }))] }));
261
+ } }), _jsx(Button, { variant: "primary", "data-testid": "onboarding-tenancy-create-submit", disabled: busy || createName.trim() === "", onClick: () => void onCreateWorkspace(), children: "Create and select" })] })) })), view.workspaces.length > 0 && orgCountRef.current > 1 && (_jsx(Button, { variant: "ghost", "data-testid": "onboarding-tenancy-back-orgs", disabled: busy, onClick: () => void loadOrgs(), children: "Back to organizations" }))] }))] })), selectError !== null && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, alignItems: "center" }, children: [_jsx("p", { "data-testid": "onboarding-tenancy-select-error", style: { fontSize: "var(--text-sm)", color: "var(--severity-critical)", margin: 0 }, children: selectError }), _jsx(Button, { variant: "secondary", size: "sm", "data-testid": "onboarding-tenancy-select-retry", disabled: busy, onClick: () => {
262
+ // Re-issue the exact request that failed when one is known (bounded by the
263
+ // client's own timeout, so this can never hang); otherwise just clear the
264
+ // message so the picker is usable again.
265
+ if (selectErrorRetry !== null)
266
+ selectErrorRetry();
267
+ else
268
+ setSelectError(null);
269
+ }, children: "Retry" })] }))] }));
222
270
  }
223
271
  //# sourceMappingURL=tenancy-step.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenancy-step.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-step.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenancy-step.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-step.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAsB,MAAM,qBAAqB,CAAC;AAmBvG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAU,CAAC;AAEtD,oGAAoG;AACpG,MAAM,uBAAuB,GAAG,2CAAoD,CAAC;AAErF,SAAS,qBAAqB;IAC7B,IAAI,CAAC;QACJ,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE,OAAO,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,CAAC,CAAC;IACV,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa;IAC5C,IAAI,CAAC;QACJ,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE,OAAO;QAClD,IAAI,KAAK,IAAI,CAAC;YAAE,cAAc,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;;YAC9D,cAAc,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACR,wFAAwF;QACxF,4BAA4B;IAC7B,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B;IACzC,MAAM,IAAI,GAAG,qBAAqB,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,IAAI,GAAG,2BAA2B;QAAE,OAAO,KAAK,CAAC;IACrD,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,wBAAwB;IACvC,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAQD,SAAS,WAAW,CAAC,MAAyB;IAC7C,OAAO,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAoB;IAC7G,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAgB,GAAG,EAAE,CAAC,eAAe,IAAI,mBAAmB,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEhH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1E,6FAA6F;IAC7F,yFAAyF;IACzF,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAsB,IAAI,CAAC,CAAC;IAC1F,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1D,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEpC,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,GAAS,EAAE;QACjD,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAChD,KAAK,CAAC,KAAK,IAAmB,EAAE;YAC/B,MAAM,gBAAgB,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC9B,UAAU,EAAE,CAAC;gBACb,OAAO;YACR,CAAC;YACD,IAAI,OAAO,MAAM,KAAK,WAAW;gBAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,CAAC,CAAC,EAAE,CAAC;IACN,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC;IAEnC,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAmB,EAAE;QAC5D,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7B,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,wFAAwF;QACxF,qFAAqF;QACrF,wFAAwF;QACxF,uEAAuE;QACvE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzD,uFAAuF;YACvF,sFAAsF;YACtF,gFAAgF;YAChF,IAAI,CAAC,0BAA0B,EAAE,EAAE,CAAC;gBACnC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBACjC,OAAO;YACR,CAAC;YACD,YAAY,EAAE,CAAC;YACf,OAAO;QACR,CAAC;QACD,wFAAwF;QACxF,mFAAmF;QACnF,wBAAwB,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1C,IAAI,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,qFAAqF;YACrF,8EAA8E;YAC9E,OAAO,CAAC;gBACP,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,qEAAqE;gBAC9E,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE;aAC9B,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QACD,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3C,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC;gBACP,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,4FAA4F;gBACrG,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE;aAC9B,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QACD,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;YACnC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;YACzD,OAAO;QACR,CAAC;QACD,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE5B,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,aAAa,CAAC,OAAO;YAAE,OAAO;QAClC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;QAC7B,gBAAgB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC7C,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,KAAK,QAAQ,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACvC,KAAK,EAAE,GAAsB,EAAiB,EAAE;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,qFAAqF;QACrF,gDAAgD;QAChD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,IAAI,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC;gBACP,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,mFAAmF;gBAC5F,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,GAAG,CAAC;gBACvC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE;aAC7B,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QACD,OAAO,CAAC;YACP,IAAI,EAAE,gBAAgB;YACtB,GAAG;YACH,UAAU,EAAE,EAAE,CAAC,UAAU;YACzB,SAAS,EAAE,EAAE,CAAC,SAAS;SACvB,CAAC,CAAC;IACJ,CAAC,EACD,CAAC,OAAO,EAAE,QAAQ,CAAC,CACnB,CAAC;IAEF,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CACzC,KAAK,EAAE,GAAsB,EAAE,SAA4B,EAAiB,EAAE;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,qFAAqF;QACrF,iDAAiD;QACjD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,sCAAsC,CAAC;YAC5G,cAAc,CAAC,OAAO,CAAC,CAAC;YACxB,mFAAmF;YACnF,mBAAmB,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;YACvE,OAAO;QACR,CAAC;QACD,oFAAoF;QACpF,oFAAoF;QACpF,wBAAwB,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/F,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,EAAE;YAC9C,QAAQ,EAAE,MAAM;YAChB,gBAAgB,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;SAChE,CAAC,CAAC;QACH,YAAY,EAAE,CAAC;IAChB,CAAC,EACD,CAAC,OAAO,EAAE,gBAAgB,EAAE,YAAY,CAAC,CACzC,CAAC;IAEF,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAmB,EAAE;QACrE,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB;YAAE,OAAO;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,oEAAoE;QACpE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,cAAc,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC;YAC7G,+DAA+D;YAC/D,mBAAmB,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,iBAAiB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACR,CAAC;QACD,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEpE,MAAM,UAAU,GAAwB;QACvC,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;QACxB,GAAG,EAAE,EAAE;QACP,SAAS,EAAE,OAAO;QAClB,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,kBAAkB;QAC9B,SAAS,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CACN,6BAAiB,yBAAyB,EAAC,KAAK,EAAE,UAAU,YAC3D,YAAG,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,sBAAsB,EAAE,iDAEnG,GACC,CACN,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,CACN,8BAAiB,yBAAyB,EAAC,KAAK,EAAE,UAAU,aAC3D,2BAAe,0BAA0B,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,CAAC,EAAE,YAC3H,IAAI,CAAC,OAAO,GACV,EACJ,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,iBAAa,0BAA0B,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,sBAEvF,EACR,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAC7B,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,iBAAa,+BAA+B,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,sCAEzF,CACT,IACI,CACN,CAAC;IACH,CAAC;IAED,8FAA8F;IAC9F,8DAA8D;IAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACjC,OAAO,CACN,6BAAiB,yBAAyB,EAAC,KAAK,EAAE,UAAU,YAC3D,8BAAiB,gCAAgC,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAC5H,aAAI,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,oDAExH,EACL,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,mPAIhG,EACJ,KAAC,MAAM,IACN,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,iBACG,yCAAyC,EACrD,OAAO,EAAE,GAAG,EAAE;4BACb,wBAAwB,EAAE,CAAC;4BAC3B,YAAY,EAAE,CAAC;wBAChB,CAAC,gCAGO,EACT,KAAC,MAAM,IACN,OAAO,EAAC,WAAW,iBACP,sCAAsC,EAClD,OAAO,EAAE,GAAG,EAAE;4BACb,wBAAwB,EAAE,CAAC;4BAC3B,KAAK,QAAQ,EAAE,CAAC;wBACjB,CAAC,0BAGO,IACJ,GACD,CACN,CAAC;IACH,CAAC;IAED,OAAO,CACN,8BAAiB,yBAAyB,EAAC,KAAK,EAAE,UAAU,aAC3D,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,aAC9E,aAAI,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,4CAExH,EACL,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,oHAEhG,IACC,EAEL,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,CAC5B,6BAAiB,6BAA6B,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YACvI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACvB,KAAC,MAAM,IAEN,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,IAAI,iBACG,+BAA+B,iBAC9B,GAAG,CAAC,EAAE,EACnB,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,GAAG,CAAC,YAEtC,WAAW,CAAC,GAAG,CAAC,IARZ,GAAG,CAAC,EAAE,CASH,CACT,CAAC,GACG,CACN,EAEA,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,CAC/B,8BAAiB,gCAAgC,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAC5H,YAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,EAAE,4FAE/E,EACJ,gBAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,cAAc,EAAE,aAChG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAI,IAAI,CAAC,GAAG,CAAC,EAAE,SAC/B,EACP,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,iBAAa,oCAAoC,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,qCAExI,IACJ,CACN,EAEA,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAClC,8BAAiB,mCAAmC,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,aAC9I,aAAG,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,CAAC,EAAE,+BAClE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IACjC,EACH,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAClD,8BACC,2BAAe,kCAAkC,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,EAAE,kEAE9H,EACJ,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,iBAAa,8BAA8B,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,sCAE5G,IACP,CACH,CAAC,CAAC,CAAC,CACH,8BACE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAC5B,KAAC,MAAM,IAEN,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,IAAI,iBACG,qCAAqC,uBAC9B,EAAE,CAAC,EAAE,EACxB,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,YAEjD,WAAW,CAAC,EAAE,CAAC,IARX,EAAE,CAAC,EAAE,CASF,CACT,CAAC,EACD,IAAI,CAAC,SAAS,IAAI,CAClB,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAC5E,CAAC,UAAU,CAAC,CAAC,CAAC,CACd,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,iBAAa,kCAAkC,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,uCAEhH,CACT,CAAC,CAAC,CAAC,CACH,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,aAC/D,+BACa,iCAAiC,EAC7C,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,UAAU,EACjB,WAAW,EAAC,oBAAoB,EAChC,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC9C,KAAK,EAAE;gDACN,MAAM,EAAE,EAAE;gDACV,OAAO,EAAE,QAAQ;gDACjB,UAAU,EAAE,mBAAmB;gDAC/B,MAAM,EAAE,iCAAiC;gDACzC,YAAY,EAAE,kBAAkB;gDAChC,KAAK,EAAE,qBAAqB;gDAC5B,UAAU,EAAE,kBAAkB;gDAC9B,QAAQ,EAAE,gBAAgB;6CAC1B,GACA,EACF,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,iBAAa,kCAAkC,EAAC,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,iBAAiB,EAAE,kCAEnJ,IACJ,CACN,GACI,CACN,EACA,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,GAAG,CAAC,IAAI,CACzD,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,iBAAa,8BAA8B,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,sCAExG,CACT,IACC,CACH,IACI,CACN,EAEA,WAAW,KAAK,IAAI,IAAI,CACxB,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,aACrF,2BAAe,iCAAiC,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,EAAE,CAAC,EAAE,YAClI,WAAW,GACT,EACJ,KAAC,MAAM,IACN,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,IAAI,iBACG,iCAAiC,EAC7C,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,GAAG,EAAE;4BACb,2EAA2E;4BAC3E,0EAA0E;4BAC1E,yCAAyC;4BACzC,IAAI,gBAAgB,KAAK,IAAI;gCAAE,gBAAgB,EAAE,CAAC;;gCAC7C,cAAc,CAAC,IAAI,CAAC,CAAC;wBAC3B,CAAC,sBAGO,IACJ,CACN,IACI,CACN,CAAC;AACH,CAAC"}
@@ -22,6 +22,13 @@
22
22
  * Memory-bounded (parent index constraint, lg-AC-6): `logs` is a capped ring buffer
23
23
  * ({@link LOG_RING_BUFFER_CAP}), oldest-dropped; `services` holds only CURRENT per-service state,
24
24
  * never a history series (hr-AC-7).
25
+ *
26
+ * Client robustness (operator-reported incident): a single transient/empty `/api/fleet-status`
27
+ * poll (a momentary gateway hiccup, or a race during a route transition) must never collapse an
28
+ * already-populated tile grid to "every service not started". {@link applyRestFallback} keeps the
29
+ * LAST-KNOWN per-service views whenever a "reachable" snapshot reports zero daemons while prior
30
+ * runtime state exists, surfacing a `reconnecting` flag on the returned view instead of wiping the
31
+ * grid; only a poll with genuinely no prior data renders the honest empty state.
25
32
  */
26
33
  import { type FleetDeeplakeStats, type FleetLogEntry, type FleetTelemetryEvent, type ServiceMetrics, type TelemetryFaultReason } from "../../shared/fleet-telemetry.js";
27
34
  import type { FleetHealth, FleetStatusResponse } from "../../shared/fleet-readiness.js";
@@ -48,6 +55,13 @@ export interface FleetTelemetryView {
48
55
  readonly logs: readonly FleetLogEntry[];
49
56
  readonly source: TelemetrySource;
50
57
  readonly asOf: string | null;
58
+ /**
59
+ * True while the REST fallback is quietly retrying after an unreachable-supervisor or
60
+ * suspicious-empty snapshot (see {@link applyRestFallback}) WITHOUT losing the last-known
61
+ * service views. A consumer may use this to render a subtle "reconnecting" affordance; the
62
+ * hook itself never blanks the grid on this alone.
63
+ */
64
+ readonly reconnecting: boolean;
51
65
  }
52
66
  export declare const EMPTY_FLEET_TELEMETRY_VIEW: FleetTelemetryView;
53
67
  interface ServiceRuntime {
@@ -63,6 +77,8 @@ export interface TelemetryState {
63
77
  readonly logs: readonly FleetLogEntry[];
64
78
  readonly source: TelemetrySource;
65
79
  readonly asOf: string | null;
80
+ /** See {@link FleetTelemetryView.reconnecting}. */
81
+ readonly reconnecting: boolean;
66
82
  }
67
83
  /** The initial, empty state before any registration/telemetry has arrived. */
68
84
  export declare function createInitialTelemetryState(registeredNames?: readonly string[]): TelemetryState;
@@ -86,6 +102,17 @@ export declare function applySseEvent(state: TelemetryState, event: FleetTelemet
86
102
  * a daemon missing from a later response loses its stale `signal`/`firstActiveAt` and falls back
87
103
  * to the registered-but-silent derivation (`starting`) instead of staying `active`/`degraded`
88
104
  * forever. Its NAME is still retained via `registeredNames`, so the row never disappears.
105
+ *
106
+ * Two ambiguous snapshot shapes are treated as a TRANSIENT fault rather than authoritative,
107
+ * because the REST fallback carries no `lastSeen`/staleness of its own to tell a momentary blip
108
+ * apart from a genuine mass outage (operator-reported incident: a single bad poll during a route
109
+ * transition briefly rendered every service as "not started"):
110
+ * - `supervisor: "unreachable"`: always kept as-is (unchanged from before).
111
+ * - `supervisor: "reachable"` but `daemons: []` while prior runtime state exists: a snapshot
112
+ * this suspicious never wipes an already-populated grid. Only a poll with genuinely no prior
113
+ * data (a fresh mount, `state.services.size === 0`) falls through to the honest empty render.
114
+ * Both set `reconnecting: true` so a consumer MAY render a subtle affordance without the hook ever
115
+ * blanking the grid on its own.
89
116
  */
90
117
  export declare function applyRestFallback(state: TelemetryState, status: FleetStatusResponse, now: number): TelemetryState;
91
118
  /** Build the rendered per-service views for every KNOWN name, in first-seen order (never omitted, sd-AC-2/bz-AC-2). */
@@ -22,6 +22,13 @@
22
22
  * Memory-bounded (parent index constraint, lg-AC-6): `logs` is a capped ring buffer
23
23
  * ({@link LOG_RING_BUFFER_CAP}), oldest-dropped; `services` holds only CURRENT per-service state,
24
24
  * never a history series (hr-AC-7).
25
+ *
26
+ * Client robustness (operator-reported incident): a single transient/empty `/api/fleet-status`
27
+ * poll (a momentary gateway hiccup, or a race during a route transition) must never collapse an
28
+ * already-populated tile grid to "every service not started". {@link applyRestFallback} keeps the
29
+ * LAST-KNOWN per-service views whenever a "reachable" snapshot reports zero daemons while prior
30
+ * runtime state exists, surfacing a `reconnecting` flag on the returned view instead of wiping the
31
+ * grid; only a poll with genuinely no prior data renders the honest empty state.
25
32
  */
26
33
  import React from "react";
27
34
  import { FLEET_TELEMETRY_EVENT_NAME, parseFleetTelemetryEvent, } from "../../shared/fleet-telemetry.js";
@@ -36,10 +43,10 @@ const FLEET_STATUS_ENDPOINT = "/api/fleet-status";
36
43
  const DEFAULT_REST_POLL_MS = 2000;
37
44
  /** The bounded log ring-buffer cap (lg-AC-6/lg-AC-8): older lines drop rather than accumulate. */
38
45
  export const LOG_RING_BUFFER_CAP = 500;
39
- export const EMPTY_FLEET_TELEMETRY_VIEW = { services: [], logs: [], source: "none", asOf: null };
46
+ export const EMPTY_FLEET_TELEMETRY_VIEW = { services: [], logs: [], source: "none", asOf: null, reconnecting: false };
40
47
  /** The initial, empty state before any registration/telemetry has arrived. */
41
48
  export function createInitialTelemetryState(registeredNames = []) {
42
- return { registeredNames, services: new Map(), logs: [], source: "none", asOf: null };
49
+ return { registeredNames, services: new Map(), logs: [], source: "none", asOf: null, reconnecting: false };
43
50
  }
44
51
  /** Union a freshly-observed name into the tracked registered set, preserving first-seen order. */
45
52
  function withKnownName(names, name) {
@@ -84,6 +91,7 @@ export function applySseEvent(state, event, now) {
84
91
  logs: appendLogs(state.logs, event.logs),
85
92
  source: "sse",
86
93
  asOf: event.asOf,
94
+ reconnecting: false,
87
95
  };
88
96
  }
89
97
  /**
@@ -96,12 +104,28 @@ export function applySseEvent(state, event, now) {
96
104
  * a daemon missing from a later response loses its stale `signal`/`firstActiveAt` and falls back
97
105
  * to the registered-but-silent derivation (`starting`) instead of staying `active`/`degraded`
98
106
  * forever. Its NAME is still retained via `registeredNames`, so the row never disappears.
107
+ *
108
+ * Two ambiguous snapshot shapes are treated as a TRANSIENT fault rather than authoritative,
109
+ * because the REST fallback carries no `lastSeen`/staleness of its own to tell a momentary blip
110
+ * apart from a genuine mass outage (operator-reported incident: a single bad poll during a route
111
+ * transition briefly rendered every service as "not started"):
112
+ * - `supervisor: "unreachable"`: always kept as-is (unchanged from before).
113
+ * - `supervisor: "reachable"` but `daemons: []` while prior runtime state exists: a snapshot
114
+ * this suspicious never wipes an already-populated grid. Only a poll with genuinely no prior
115
+ * data (a fresh mount, `state.services.size === 0`) falls through to the honest empty render.
116
+ * Both set `reconnecting: true` so a consumer MAY render a subtle affordance without the hook ever
117
+ * blanking the grid on its own.
99
118
  */
100
119
  export function applyRestFallback(state, status, now) {
101
120
  if (status.supervisor !== "reachable") {
102
121
  // Supervisor itself unreachable: no per-service signal to apply, but the source flips so
103
122
  // consumers can show a "telemetry unavailable" fail-soft state rather than a stale "sse" label.
104
- return { ...state, source: "rest" };
123
+ return { ...state, source: "rest", reconnecting: true };
124
+ }
125
+ if (status.daemons.length === 0 && state.services.size > 0) {
126
+ // A "reachable" snapshot with zero daemons while we already track live services reads as a
127
+ // transient blip, not "every service just vanished"; keep the last-known views intact.
128
+ return { ...state, source: "rest", asOf: status.asOf, reconnecting: true };
105
129
  }
106
130
  let names = state.registeredNames;
107
131
  const services = new Map();
@@ -116,7 +140,7 @@ export function applyRestFallback(state, status, now) {
116
140
  firstActiveAt: nextFirstActiveAt(daemon.health, previous?.firstActiveAt ?? null, now),
117
141
  });
118
142
  }
119
- return { registeredNames: names, services, logs: state.logs, source: "rest", asOf: status.asOf };
143
+ return { registeredNames: names, services, logs: state.logs, source: "rest", asOf: status.asOf, reconnecting: false };
120
144
  }
121
145
  /** Build the rendered per-service views for every KNOWN name, in first-seen order (never omitted, sd-AC-2/bz-AC-2). */
122
146
  export function deriveServiceViews(state, now) {
@@ -140,7 +164,13 @@ export function deriveServiceViews(state, now) {
140
164
  }
141
165
  /** Project internal {@link TelemetryState} into the public {@link FleetTelemetryView}. */
142
166
  export function toFleetTelemetryView(state, now) {
143
- return { services: deriveServiceViews(state, now), logs: state.logs, source: state.source, asOf: state.asOf };
167
+ return {
168
+ services: deriveServiceViews(state, now),
169
+ logs: state.logs,
170
+ source: state.source,
171
+ asOf: state.asOf,
172
+ reconnecting: state.reconnecting,
173
+ };
144
174
  }
145
175
  /**
146
176
  * The shared fleet-telemetry hook (see module doc for the sourcing precedence). Every consumer
@@ -199,6 +229,8 @@ export function useFleetTelemetry(options = {}) {
199
229
  const tick = async () => {
200
230
  try {
201
231
  const response = await fetch(FLEET_STATUS_ENDPOINT);
232
+ if (!response.ok)
233
+ return; // Keep the last-known view; the next tick retries.
202
234
  const body = (await response.json());
203
235
  if (!alive)
204
236
  return;