@legioncodeinc/hive 0.4.0 → 0.5.1
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.
- package/README.md +1 -1
- package/dist/daemon/dashboard/app.js +12 -12
- package/dist/daemon/gate.d.ts +10 -6
- package/dist/daemon/gate.js +20 -8
- package/dist/daemon/gate.js.map +1 -1
- package/dist/daemon/installer/funnel-telemetry.d.ts +17 -2
- package/dist/daemon/installer/funnel-telemetry.js +34 -3
- package/dist/daemon/installer/funnel-telemetry.js.map +1 -1
- package/dist/daemon/installer/manifest-snapshot.json +5 -5
- package/dist/daemon/installer/routes.js +6 -2
- package/dist/daemon/installer/routes.js.map +1 -1
- package/dist/daemon/installer/security.d.ts +9 -2
- package/dist/daemon/installer/security.js +8 -0
- package/dist/daemon/installer/security.js.map +1 -1
- package/dist/daemon/server.d.ts +3 -0
- package/dist/daemon/server.js +1 -0
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/setup-tenancy.d.ts +18 -0
- package/dist/daemon/setup-tenancy.js +37 -0
- package/dist/daemon/setup-tenancy.js.map +1 -0
- package/dist/dashboard/web/active-tenancy-display.d.ts +34 -0
- package/dist/dashboard/web/active-tenancy-display.js +84 -0
- package/dist/dashboard/web/active-tenancy-display.js.map +1 -0
- package/dist/dashboard/web/app.js +6 -2
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/onboarding/contracts.d.ts +1 -1
- package/dist/dashboard/web/onboarding/contracts.js +9 -1
- package/dist/dashboard/web/onboarding/contracts.js.map +1 -1
- package/dist/dashboard/web/onboarding/login-step.d.ts +3 -4
- package/dist/dashboard/web/onboarding/login-step.js +37 -31
- package/dist/dashboard/web/onboarding/login-step.js.map +1 -1
- package/dist/dashboard/web/onboarding/onboarding-screen.d.ts +8 -4
- package/dist/dashboard/web/onboarding/onboarding-screen.js +90 -13
- package/dist/dashboard/web/onboarding/onboarding-screen.js.map +1 -1
- package/dist/dashboard/web/onboarding/tenancy-client.d.ts +19 -0
- package/dist/dashboard/web/onboarding/tenancy-client.js +84 -0
- package/dist/dashboard/web/onboarding/tenancy-client.js.map +1 -0
- package/dist/dashboard/web/onboarding/tenancy-contracts.d.ts +119 -0
- package/dist/dashboard/web/onboarding/tenancy-contracts.js +79 -0
- package/dist/dashboard/web/onboarding/tenancy-contracts.js.map +1 -0
- package/dist/dashboard/web/onboarding/tenancy-step.d.ts +32 -0
- package/dist/dashboard/web/onboarding/tenancy-step.js +223 -0
- package/dist/dashboard/web/onboarding/tenancy-step.js.map +1 -0
- package/dist/dashboard/web/pages/hive-graph.js +16 -7
- package/dist/dashboard/web/pages/hive-graph.js.map +1 -1
- package/dist/dashboard/web/setup-gate.js +11 -1
- package/dist/dashboard/web/setup-gate.js.map +1 -1
- package/dist/dashboard/web/wire.d.ts +20 -0
- package/dist/dashboard/web/wire.js +34 -0
- package/dist/dashboard/web/wire.js.map +1 -1
- package/dist/shared/fleet-readiness.js +13 -2
- package/dist/shared/fleet-readiness.js.map +1 -1
- package/dist/telemetry/emit.d.ts +17 -4
- package/dist/telemetry/emit.js +8 -1
- package/dist/telemetry/emit.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-011a tenancy wire client: same-origin `/setup/tenancy/*` via hive's BFF proxy (no onboarding
|
|
3
|
+
* token). Mirrors `onboarding-client.ts` fail-soft discipline; lives beside it in the onboarding folder.
|
|
4
|
+
*/
|
|
5
|
+
import { EMPTY_TENANCY_ORGS, EMPTY_TENANCY_WORKSPACES, SetupTenancySchema, TenancyCreateResponseSchema, TenancyOrgsSchema, TenancySelectResponseSchema, TenancyWorkspacesSchema, UNSELECTED_SETUP_TENANCY, } from "./tenancy-contracts.js";
|
|
6
|
+
export function createTenancyClient(options = {}) {
|
|
7
|
+
const origin = options.origin ?? "";
|
|
8
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
9
|
+
const url = (path) => `${origin}${path}`;
|
|
10
|
+
return {
|
|
11
|
+
async setupTenancy() {
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetchImpl(url("/setup/tenancy"), { headers: { accept: "application/json" } });
|
|
14
|
+
if (!res.ok)
|
|
15
|
+
return UNSELECTED_SETUP_TENANCY;
|
|
16
|
+
const parsed = SetupTenancySchema.safeParse(await res.json());
|
|
17
|
+
return parsed.success ? parsed.data : UNSELECTED_SETUP_TENANCY;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return UNSELECTED_SETUP_TENANCY;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
async listOrgs() {
|
|
24
|
+
try {
|
|
25
|
+
const res = await fetchImpl(url("/setup/tenancy/orgs"), { headers: { accept: "application/json" } });
|
|
26
|
+
if (!res.ok)
|
|
27
|
+
return EMPTY_TENANCY_ORGS;
|
|
28
|
+
const parsed = TenancyOrgsSchema.safeParse(await res.json());
|
|
29
|
+
return parsed.success ? parsed.data : EMPTY_TENANCY_ORGS;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return EMPTY_TENANCY_ORGS;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async listWorkspaces(orgId) {
|
|
36
|
+
try {
|
|
37
|
+
const qs = `?org=${encodeURIComponent(orgId)}`;
|
|
38
|
+
const res = await fetchImpl(url(`/setup/tenancy/workspaces${qs}`), {
|
|
39
|
+
headers: { accept: "application/json" },
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
return { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
|
|
43
|
+
const parsed = TenancyWorkspacesSchema.safeParse(await res.json());
|
|
44
|
+
return parsed.success ? parsed.data : { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { ...EMPTY_TENANCY_WORKSPACES, org: orgId };
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
async selectTenancy(orgId, workspaceId) {
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetchImpl(url("/setup/tenancy/select"), {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
55
|
+
body: JSON.stringify({ orgId, workspaceId }),
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok)
|
|
58
|
+
return null;
|
|
59
|
+
const parsed = TenancySelectResponseSchema.safeParse(await res.json());
|
|
60
|
+
return parsed.success ? parsed.data : null;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
async createWorkspace(org, name) {
|
|
67
|
+
try {
|
|
68
|
+
const res = await fetchImpl(url("/setup/tenancy/workspaces"), {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
71
|
+
body: JSON.stringify({ org, name }),
|
|
72
|
+
});
|
|
73
|
+
if (!res.ok)
|
|
74
|
+
return null;
|
|
75
|
+
const parsed = TenancyCreateResponseSchema.safeParse(await res.json());
|
|
76
|
+
return parsed.success ? parsed.data : null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=tenancy-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenancy-client.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-011a tenancy wire contract: mirrors the honeycomb PRD-073c `/setup/tenancy` family
|
|
3
|
+
* field-for-field (pinned at implementation). Same discipline as `contracts.ts` for PRD-009b:
|
|
4
|
+
* local types at the onboarding boundary, zod with `.catch()` defaults, never throw into React.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
/** `{ id, name }` pair returned by org/workspace enumeration and select acks. */
|
|
8
|
+
export declare const TenancyEntitySchema: z.ZodObject<{
|
|
9
|
+
id: z.ZodCatch<z.ZodString>;
|
|
10
|
+
name: z.ZodCatch<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export type TenancyEntityWire = z.infer<typeof TenancyEntitySchema>;
|
|
13
|
+
/**
|
|
14
|
+
* `GET /setup/tenancy`: the durable selected marker and current org/workspace read.
|
|
15
|
+
* `selected` is true ONLY after the daemon has persisted a confirmation. Reconciled against the
|
|
16
|
+
* honeycomb implementation (2026-07-04): the earlier proposed `autoSelected` field was REMOVED
|
|
17
|
+
* from the daemon contract (an auto-selection persists immediately and reads as `selected: true`,
|
|
18
|
+
* so no GET ever carries it); `confirmedBy` was ADDED and reports how the confirmation happened
|
|
19
|
+
* (`selection` = an explicit POST /setup/tenancy/select; `grandfathered` = a pre-PRD-073 credential
|
|
20
|
+
* whose existing tenancy was carried forward).
|
|
21
|
+
*/
|
|
22
|
+
export declare const SetupTenancySchema: z.ZodObject<{
|
|
23
|
+
pending: z.ZodCatch<z.ZodBoolean>;
|
|
24
|
+
selected: z.ZodCatch<z.ZodBoolean>;
|
|
25
|
+
authenticated: z.ZodCatch<z.ZodBoolean>;
|
|
26
|
+
org: z.ZodCatch<z.ZodNullable<z.ZodObject<{
|
|
27
|
+
id: z.ZodCatch<z.ZodString>;
|
|
28
|
+
name: z.ZodCatch<z.ZodString>;
|
|
29
|
+
}, z.core.$strip>>>;
|
|
30
|
+
workspace: z.ZodCatch<z.ZodNullable<z.ZodObject<{
|
|
31
|
+
id: z.ZodCatch<z.ZodString>;
|
|
32
|
+
name: z.ZodCatch<z.ZodString>;
|
|
33
|
+
}, z.core.$strip>>>;
|
|
34
|
+
confirmedBy: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
selection: "selection";
|
|
36
|
+
grandfathered: "grandfathered";
|
|
37
|
+
}>>>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export type SetupTenancyWire = z.infer<typeof SetupTenancySchema>;
|
|
40
|
+
/** Honest default when the tenancy read fails or the body is malformed. */
|
|
41
|
+
export declare const UNSELECTED_SETUP_TENANCY: SetupTenancyWire;
|
|
42
|
+
/** `GET /setup/tenancy/orgs` body. */
|
|
43
|
+
export declare const TenancyOrgsSchema: z.ZodObject<{
|
|
44
|
+
orgs: z.ZodCatch<z.ZodArray<z.ZodObject<{
|
|
45
|
+
id: z.ZodCatch<z.ZodString>;
|
|
46
|
+
name: z.ZodCatch<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>>>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
export type TenancyOrgsWire = z.infer<typeof TenancyOrgsSchema>;
|
|
50
|
+
export declare const EMPTY_TENANCY_ORGS: TenancyOrgsWire;
|
|
51
|
+
/** `GET /setup/tenancy/workspaces?org=` body. */
|
|
52
|
+
export declare const TenancyWorkspacesSchema: z.ZodObject<{
|
|
53
|
+
org: z.ZodCatch<z.ZodString>;
|
|
54
|
+
workspaces: z.ZodCatch<z.ZodArray<z.ZodObject<{
|
|
55
|
+
id: z.ZodCatch<z.ZodString>;
|
|
56
|
+
name: z.ZodCatch<z.ZodString>;
|
|
57
|
+
}, z.core.$strip>>>;
|
|
58
|
+
canCreate: z.ZodCatch<z.ZodBoolean>;
|
|
59
|
+
}, z.core.$strip>;
|
|
60
|
+
export type TenancyWorkspacesWire = z.infer<typeof TenancyWorkspacesSchema>;
|
|
61
|
+
export declare const EMPTY_TENANCY_WORKSPACES: TenancyWorkspacesWire;
|
|
62
|
+
/** Successful `POST /setup/tenancy/select` ack. */
|
|
63
|
+
export declare const TenancySelectOkSchema: z.ZodObject<{
|
|
64
|
+
selected: z.ZodLiteral<true>;
|
|
65
|
+
org: z.ZodObject<{
|
|
66
|
+
id: z.ZodCatch<z.ZodString>;
|
|
67
|
+
name: z.ZodCatch<z.ZodString>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
workspace: z.ZodObject<{
|
|
70
|
+
id: z.ZodCatch<z.ZodString>;
|
|
71
|
+
name: z.ZodCatch<z.ZodString>;
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
reminted: z.ZodCatch<z.ZodBoolean>;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
/** Failed `POST /setup/tenancy/select` ack (redacted reason, no token). */
|
|
76
|
+
export declare const TenancySelectErrSchema: z.ZodObject<{
|
|
77
|
+
selected: z.ZodLiteral<false>;
|
|
78
|
+
error: z.ZodCatch<z.ZodString>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
export declare const TenancySelectResponseSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
81
|
+
selected: z.ZodLiteral<true>;
|
|
82
|
+
org: z.ZodObject<{
|
|
83
|
+
id: z.ZodCatch<z.ZodString>;
|
|
84
|
+
name: z.ZodCatch<z.ZodString>;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
workspace: z.ZodObject<{
|
|
87
|
+
id: z.ZodCatch<z.ZodString>;
|
|
88
|
+
name: z.ZodCatch<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
reminted: z.ZodCatch<z.ZodBoolean>;
|
|
91
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
92
|
+
selected: z.ZodLiteral<false>;
|
|
93
|
+
error: z.ZodCatch<z.ZodString>;
|
|
94
|
+
}, z.core.$strip>]>;
|
|
95
|
+
export type TenancySelectResponseWire = z.infer<typeof TenancySelectResponseSchema>;
|
|
96
|
+
/** Successful `POST /setup/tenancy/workspaces` ack. */
|
|
97
|
+
export declare const TenancyCreateOkSchema: z.ZodObject<{
|
|
98
|
+
created: z.ZodLiteral<true>;
|
|
99
|
+
workspace: z.ZodObject<{
|
|
100
|
+
id: z.ZodCatch<z.ZodString>;
|
|
101
|
+
name: z.ZodCatch<z.ZodString>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
/** Failed `POST /setup/tenancy/workspaces` ack. */
|
|
105
|
+
export declare const TenancyCreateErrSchema: z.ZodObject<{
|
|
106
|
+
created: z.ZodLiteral<false>;
|
|
107
|
+
error: z.ZodCatch<z.ZodString>;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
export declare const TenancyCreateResponseSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
110
|
+
created: z.ZodLiteral<true>;
|
|
111
|
+
workspace: z.ZodObject<{
|
|
112
|
+
id: z.ZodCatch<z.ZodString>;
|
|
113
|
+
name: z.ZodCatch<z.ZodString>;
|
|
114
|
+
}, z.core.$strip>;
|
|
115
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
116
|
+
created: z.ZodLiteral<false>;
|
|
117
|
+
error: z.ZodCatch<z.ZodString>;
|
|
118
|
+
}, z.core.$strip>]>;
|
|
119
|
+
export type TenancyCreateResponseWire = z.infer<typeof TenancyCreateResponseSchema>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-011a tenancy wire contract: mirrors the honeycomb PRD-073c `/setup/tenancy` family
|
|
3
|
+
* field-for-field (pinned at implementation). Same discipline as `contracts.ts` for PRD-009b:
|
|
4
|
+
* local types at the onboarding boundary, zod with `.catch()` defaults, never throw into React.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
/** `{ id, name }` pair returned by org/workspace enumeration and select acks. */
|
|
8
|
+
export const TenancyEntitySchema = z.object({
|
|
9
|
+
id: z.string().catch(""),
|
|
10
|
+
name: z.string().catch(""),
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* `GET /setup/tenancy`: the durable selected marker and current org/workspace read.
|
|
14
|
+
* `selected` is true ONLY after the daemon has persisted a confirmation. Reconciled against the
|
|
15
|
+
* honeycomb implementation (2026-07-04): the earlier proposed `autoSelected` field was REMOVED
|
|
16
|
+
* from the daemon contract (an auto-selection persists immediately and reads as `selected: true`,
|
|
17
|
+
* so no GET ever carries it); `confirmedBy` was ADDED and reports how the confirmation happened
|
|
18
|
+
* (`selection` = an explicit POST /setup/tenancy/select; `grandfathered` = a pre-PRD-073 credential
|
|
19
|
+
* whose existing tenancy was carried forward).
|
|
20
|
+
*/
|
|
21
|
+
export const SetupTenancySchema = z.object({
|
|
22
|
+
pending: z.boolean().catch(true),
|
|
23
|
+
selected: z.boolean().catch(false),
|
|
24
|
+
authenticated: z.boolean().catch(false),
|
|
25
|
+
org: TenancyEntitySchema.nullable().catch(null),
|
|
26
|
+
workspace: TenancyEntitySchema.nullable().catch(null),
|
|
27
|
+
// `.catch(undefined)` keeps the module's fail-soft rule: a malformed confirmedBy value must
|
|
28
|
+
// degrade to "absent" (the field is cosmetic), never fail the whole tenancy read.
|
|
29
|
+
confirmedBy: z.enum(["selection", "grandfathered"]).optional().catch(undefined),
|
|
30
|
+
});
|
|
31
|
+
/** Honest default when the tenancy read fails or the body is malformed. */
|
|
32
|
+
export const UNSELECTED_SETUP_TENANCY = Object.freeze({
|
|
33
|
+
pending: true,
|
|
34
|
+
selected: false,
|
|
35
|
+
authenticated: false,
|
|
36
|
+
org: null,
|
|
37
|
+
workspace: null,
|
|
38
|
+
});
|
|
39
|
+
/** `GET /setup/tenancy/orgs` body. */
|
|
40
|
+
export const TenancyOrgsSchema = z.object({
|
|
41
|
+
orgs: z.array(TenancyEntitySchema).catch([]),
|
|
42
|
+
});
|
|
43
|
+
export const EMPTY_TENANCY_ORGS = Object.freeze({ orgs: [] });
|
|
44
|
+
/** `GET /setup/tenancy/workspaces?org=` body. */
|
|
45
|
+
export const TenancyWorkspacesSchema = z.object({
|
|
46
|
+
org: z.string().catch(""),
|
|
47
|
+
workspaces: z.array(TenancyEntitySchema).catch([]),
|
|
48
|
+
canCreate: z.boolean().catch(false),
|
|
49
|
+
});
|
|
50
|
+
export const EMPTY_TENANCY_WORKSPACES = Object.freeze({
|
|
51
|
+
org: "",
|
|
52
|
+
workspaces: [],
|
|
53
|
+
canCreate: false,
|
|
54
|
+
});
|
|
55
|
+
/** Successful `POST /setup/tenancy/select` ack. */
|
|
56
|
+
export const TenancySelectOkSchema = z.object({
|
|
57
|
+
selected: z.literal(true),
|
|
58
|
+
org: TenancyEntitySchema,
|
|
59
|
+
workspace: TenancyEntitySchema,
|
|
60
|
+
reminted: z.boolean().catch(false),
|
|
61
|
+
});
|
|
62
|
+
/** Failed `POST /setup/tenancy/select` ack (redacted reason, no token). */
|
|
63
|
+
export const TenancySelectErrSchema = z.object({
|
|
64
|
+
selected: z.literal(false),
|
|
65
|
+
error: z.string().catch("Selection could not be saved."),
|
|
66
|
+
});
|
|
67
|
+
export const TenancySelectResponseSchema = z.union([TenancySelectOkSchema, TenancySelectErrSchema]);
|
|
68
|
+
/** Successful `POST /setup/tenancy/workspaces` ack. */
|
|
69
|
+
export const TenancyCreateOkSchema = z.object({
|
|
70
|
+
created: z.literal(true),
|
|
71
|
+
workspace: TenancyEntitySchema,
|
|
72
|
+
});
|
|
73
|
+
/** Failed `POST /setup/tenancy/workspaces` ack. */
|
|
74
|
+
export const TenancyCreateErrSchema = z.object({
|
|
75
|
+
created: z.literal(false),
|
|
76
|
+
error: z.string().catch("Workspace could not be created."),
|
|
77
|
+
});
|
|
78
|
+
export const TenancyCreateResponseSchema = z.union([TenancyCreateOkSchema, TenancyCreateErrSchema]);
|
|
79
|
+
//# sourceMappingURL=tenancy-contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenancy-contracts.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-011a: the mandatory org + workspace selection step in the onboarding flow.
|
|
3
|
+
* Enters after device-code login succeeds; terminal handoff runs only after `selected: true`.
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { OnboardingClient } from "./onboarding-client.js";
|
|
7
|
+
import { type TenancyClient } from "./tenancy-client.js";
|
|
8
|
+
/**
|
|
9
|
+
* W-4 loop-breaker: how many CONSECUTIVE automatic short-circuits (hydrate reads `selected: true`
|
|
10
|
+
* and the step auto-navigates to `/`) are allowed before the step stops reloading and renders a
|
|
11
|
+
* terminal manual state. In the split-brain fault (the browser's proxied tenancy read says
|
|
12
|
+
* selected while the gate's server-side read persistently fails), each auto-navigation bounces
|
|
13
|
+
* off the gate straight back here; without a bound that is an infinite reload loop re-firing
|
|
14
|
+
* `dashboard_reached` and `POST /api/onboarding/complete` every lap.
|
|
15
|
+
*/
|
|
16
|
+
export declare const TENANCY_AUTO_COMPLETE_LIMIT: 2;
|
|
17
|
+
/**
|
|
18
|
+
* Consume one lap of the bounded auto short-circuit allowance. Returns true (and records the lap)
|
|
19
|
+
* while within {@link TENANCY_AUTO_COMPLETE_LIMIT}; returns false once exceeded, at which point
|
|
20
|
+
* the caller must stop auto-navigating and surface the terminal split-brain state. Shared with
|
|
21
|
+
* the tokenless resume probe in `onboarding-screen.tsx`, the other automatic navigator on the
|
|
22
|
+
* split-brain lap.
|
|
23
|
+
*/
|
|
24
|
+
export declare function consumeTenancyAutoComplete(): boolean;
|
|
25
|
+
/** Reset the auto short-circuit counter (a live picker flow or an explicit operator action). */
|
|
26
|
+
export declare function resetTenancyAutoComplete(): void;
|
|
27
|
+
export interface TenancyStepProps {
|
|
28
|
+
readonly onboardingClient: OnboardingClient;
|
|
29
|
+
readonly tenancyClient?: TenancyClient;
|
|
30
|
+
readonly onComplete?: () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride, onComplete }: TenancyStepProps): React.JSX.Element;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* PRD-011a: the mandatory org + workspace selection step in the onboarding flow.
|
|
4
|
+
* Enters after device-code login succeeds; terminal handoff runs only after `selected: true`.
|
|
5
|
+
*/
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { Button } from "../primitives.js";
|
|
8
|
+
import { createTenancyClient } from "./tenancy-client.js";
|
|
9
|
+
/**
|
|
10
|
+
* W-4 loop-breaker: how many CONSECUTIVE automatic short-circuits (hydrate reads `selected: true`
|
|
11
|
+
* and the step auto-navigates to `/`) are allowed before the step stops reloading and renders a
|
|
12
|
+
* terminal manual state. In the split-brain fault (the browser's proxied tenancy read says
|
|
13
|
+
* selected while the gate's server-side read persistently fails), each auto-navigation bounces
|
|
14
|
+
* off the gate straight back here; without a bound that is an infinite reload loop re-firing
|
|
15
|
+
* `dashboard_reached` and `POST /api/onboarding/complete` every lap.
|
|
16
|
+
*/
|
|
17
|
+
export const TENANCY_AUTO_COMPLETE_LIMIT = 2;
|
|
18
|
+
/** Session-scoped (per-tab) counter key; survives the full page navigations each loop lap makes. */
|
|
19
|
+
const AUTO_COMPLETE_COUNT_KEY = "hive.onboarding.tenancy.autoCompleteCount";
|
|
20
|
+
function readAutoCompleteCount() {
|
|
21
|
+
try {
|
|
22
|
+
if (typeof sessionStorage === "undefined")
|
|
23
|
+
return 0;
|
|
24
|
+
const raw = sessionStorage.getItem(AUTO_COMPLETE_COUNT_KEY);
|
|
25
|
+
const parsed = raw === null ? 0 : Number.parseInt(raw, 10);
|
|
26
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function writeAutoCompleteCount(count) {
|
|
33
|
+
try {
|
|
34
|
+
if (typeof sessionStorage === "undefined")
|
|
35
|
+
return;
|
|
36
|
+
if (count <= 0)
|
|
37
|
+
sessionStorage.removeItem(AUTO_COMPLETE_COUNT_KEY);
|
|
38
|
+
else
|
|
39
|
+
sessionStorage.setItem(AUTO_COMPLETE_COUNT_KEY, String(count));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Storage unavailable (private mode / quota): the bound degrades to per-mount behavior;
|
|
43
|
+
// never a throw into React.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Consume one lap of the bounded auto short-circuit allowance. Returns true (and records the lap)
|
|
48
|
+
* while within {@link TENANCY_AUTO_COMPLETE_LIMIT}; returns false once exceeded, at which point
|
|
49
|
+
* the caller must stop auto-navigating and surface the terminal split-brain state. Shared with
|
|
50
|
+
* the tokenless resume probe in `onboarding-screen.tsx`, the other automatic navigator on the
|
|
51
|
+
* split-brain lap.
|
|
52
|
+
*/
|
|
53
|
+
export function consumeTenancyAutoComplete() {
|
|
54
|
+
const laps = readAutoCompleteCount() + 1;
|
|
55
|
+
if (laps > TENANCY_AUTO_COMPLETE_LIMIT)
|
|
56
|
+
return false;
|
|
57
|
+
writeAutoCompleteCount(laps);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
/** Reset the auto short-circuit counter (a live picker flow or an explicit operator action). */
|
|
61
|
+
export function resetTenancyAutoComplete() {
|
|
62
|
+
writeAutoCompleteCount(0);
|
|
63
|
+
}
|
|
64
|
+
function entityLabel(entity) {
|
|
65
|
+
return entity.name !== "" ? entity.name : entity.id;
|
|
66
|
+
}
|
|
67
|
+
export function TenancyStep({ onboardingClient, tenancyClient: tenancyOverride, onComplete }) {
|
|
68
|
+
const tenancy = React.useMemo(() => tenancyOverride ?? createTenancyClient(), [tenancyOverride]);
|
|
69
|
+
const [view, setView] = React.useState({ kind: "loading" });
|
|
70
|
+
const [busy, setBusy] = React.useState(false);
|
|
71
|
+
const [selectError, setSelectError] = React.useState(null);
|
|
72
|
+
const [createName, setCreateName] = React.useState("");
|
|
73
|
+
const [showCreate, setShowCreate] = React.useState(false);
|
|
74
|
+
const shownEventRef = React.useRef(false);
|
|
75
|
+
const singleOrgConfirmRef = React.useRef(false);
|
|
76
|
+
const orgCountRef = React.useRef(0);
|
|
77
|
+
const completeFlow = React.useCallback(() => {
|
|
78
|
+
onboardingClient.sendEvent("dashboard_reached");
|
|
79
|
+
void (async () => {
|
|
80
|
+
await onboardingClient.complete();
|
|
81
|
+
if (onComplete !== undefined) {
|
|
82
|
+
onComplete();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (typeof window !== "undefined")
|
|
86
|
+
window.location.assign("/");
|
|
87
|
+
})();
|
|
88
|
+
}, [onboardingClient, onComplete]);
|
|
89
|
+
const loadOrgs = React.useCallback(async () => {
|
|
90
|
+
setView({ kind: "loading" });
|
|
91
|
+
setSelectError(null);
|
|
92
|
+
const status = await tenancy.setupTenancy();
|
|
93
|
+
if (status.selected) {
|
|
94
|
+
// W-4: bound the automatic short-circuit. Each auto-navigation consumes one lap of the
|
|
95
|
+
// per-tab allowance; past the limit the step stops reloading and renders the terminal
|
|
96
|
+
// manual state instead, breaking the split-brain reload loop deterministically.
|
|
97
|
+
if (!consumeTenancyAutoComplete()) {
|
|
98
|
+
setView({ kind: "split-brain" });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
completeFlow();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// The normal picker flow is live: only CONSECUTIVE auto short-circuits count toward the
|
|
105
|
+
// bound, so a later legitimate pass through this step starts from a clean counter.
|
|
106
|
+
resetTenancyAutoComplete();
|
|
107
|
+
const orgsBody = await tenancy.listOrgs();
|
|
108
|
+
orgCountRef.current = orgsBody.orgs.length;
|
|
109
|
+
if (orgsBody.orgs.length === 0) {
|
|
110
|
+
setView({
|
|
111
|
+
kind: "error",
|
|
112
|
+
message: "No organizations are available for this account. Check your Deeplake credential and retry.",
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (orgsBody.orgs.length === 1) {
|
|
117
|
+
singleOrgConfirmRef.current = true;
|
|
118
|
+
setView({ kind: "org-confirm", org: orgsBody.orgs[0] });
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
setView({ kind: "org-list", orgs: orgsBody.orgs });
|
|
122
|
+
}, [tenancy, completeFlow]);
|
|
123
|
+
React.useEffect(() => {
|
|
124
|
+
if (shownEventRef.current)
|
|
125
|
+
return;
|
|
126
|
+
shownEventRef.current = true;
|
|
127
|
+
onboardingClient.sendEvent("tenancy_shown");
|
|
128
|
+
}, [onboardingClient]);
|
|
129
|
+
React.useEffect(() => {
|
|
130
|
+
void loadOrgs();
|
|
131
|
+
}, [loadOrgs]);
|
|
132
|
+
const openWorkspaces = React.useCallback(async (org) => {
|
|
133
|
+
setBusy(true);
|
|
134
|
+
setSelectError(null);
|
|
135
|
+
setShowCreate(false);
|
|
136
|
+
setCreateName("");
|
|
137
|
+
const ws = await tenancy.listWorkspaces(org.id);
|
|
138
|
+
setBusy(false);
|
|
139
|
+
setView({
|
|
140
|
+
kind: "workspace-list",
|
|
141
|
+
org,
|
|
142
|
+
workspaces: ws.workspaces,
|
|
143
|
+
canCreate: ws.canCreate,
|
|
144
|
+
});
|
|
145
|
+
}, [tenancy]);
|
|
146
|
+
const persistSelection = React.useCallback(async (org, workspace) => {
|
|
147
|
+
setBusy(true);
|
|
148
|
+
setSelectError(null);
|
|
149
|
+
const ack = await tenancy.selectTenancy(org.id, workspace.id);
|
|
150
|
+
setBusy(false);
|
|
151
|
+
if (ack === null || ack.selected === false) {
|
|
152
|
+
const message = ack !== null && ack.selected === false ? ack.error : "Selection could not be saved. Retry.";
|
|
153
|
+
setSelectError(message);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// An explicit acknowledged selection resets the W-4 loop counter: if the gate still
|
|
157
|
+
// bounces after this, the auto short-circuit gets its full bounded allowance again.
|
|
158
|
+
resetTenancyAutoComplete();
|
|
159
|
+
const bucket = orgCountRef.current <= 1 ? "single" : orgCountRef.current <= 3 ? "few" : "many";
|
|
160
|
+
onboardingClient.sendEvent("tenancy_selected", {
|
|
161
|
+
orgCount: bucket,
|
|
162
|
+
singleOrgConfirm: singleOrgConfirmRef.current ? "true" : "false",
|
|
163
|
+
});
|
|
164
|
+
completeFlow();
|
|
165
|
+
}, [tenancy, onboardingClient, completeFlow]);
|
|
166
|
+
const onCreateWorkspace = React.useCallback(async () => {
|
|
167
|
+
if (view.kind !== "workspace-list")
|
|
168
|
+
return;
|
|
169
|
+
const trimmed = createName.trim();
|
|
170
|
+
if (trimmed === "")
|
|
171
|
+
return;
|
|
172
|
+
setBusy(true);
|
|
173
|
+
setSelectError(null);
|
|
174
|
+
const ack = await tenancy.createWorkspace(view.org.id, trimmed);
|
|
175
|
+
if (ack === null || ack.created === false) {
|
|
176
|
+
setBusy(false);
|
|
177
|
+
setSelectError(ack !== null && ack.created === false ? ack.error : "Workspace could not be created. Retry.");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
onboardingClient.sendEvent("workspace_created");
|
|
181
|
+
setBusy(false);
|
|
182
|
+
await persistSelection(view.org, ack.workspace);
|
|
183
|
+
}, [view, createName, tenancy, onboardingClient, persistSelection]);
|
|
184
|
+
const shellStyle = {
|
|
185
|
+
display: "flex",
|
|
186
|
+
flexDirection: "column",
|
|
187
|
+
alignItems: "center",
|
|
188
|
+
justifyContent: "center",
|
|
189
|
+
gap: 18,
|
|
190
|
+
minHeight: "100vh",
|
|
191
|
+
padding: 28,
|
|
192
|
+
background: "var(--bg-canvas)",
|
|
193
|
+
textAlign: "center",
|
|
194
|
+
};
|
|
195
|
+
if (view.kind === "loading") {
|
|
196
|
+
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
|
+
}
|
|
198
|
+
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" })] }));
|
|
200
|
+
}
|
|
201
|
+
// W-4: the terminal state past the auto short-circuit bound. No automatic reload happens from
|
|
202
|
+
// here; every further attempt is an explicit operator action.
|
|
203
|
+
if (view.kind === "split-brain") {
|
|
204
|
+
return (_jsx("div", { "data-testid": "onboarding-tenancy-step", style: shellStyle, children: _jsxs("div", { "data-testid": "onboarding-tenancy-split-brain", style: { display: "flex", flexDirection: "column", gap: 12, maxWidth: 480 }, children: [_jsx("h1", { style: { fontSize: "var(--text-xl)", fontWeight: 700, color: "var(--text-primary)", margin: 0, letterSpacing: "-0.02em" }, children: "The portal keeps returning you here" }), _jsx("p", { style: { fontSize: "var(--text-sm)", color: "var(--text-secondary)", margin: 0, lineHeight: 1.5 }, children: "Your tenancy reads as confirmed in this browser, but the portal cannot verify it and keeps redirecting back to this step. The daemon may be unreachable or out of sync. Check that the honeycomb daemon is running, then continue." }), _jsx(Button, { variant: "primary", size: "lg", "data-testid": "onboarding-tenancy-split-brain-continue", onClick: () => {
|
|
205
|
+
resetTenancyAutoComplete();
|
|
206
|
+
completeFlow();
|
|
207
|
+
}, children: "Go to dashboard" }), _jsx(Button, { variant: "secondary", "data-testid": "onboarding-tenancy-split-brain-retry", onClick: () => {
|
|
208
|
+
resetTenancyAutoComplete();
|
|
209
|
+
void loadOrgs();
|
|
210
|
+
}, children: "Try again" })] }) }));
|
|
211
|
+
}
|
|
212
|
+
return (_jsxs("div", { "data-testid": "onboarding-tenancy-step", style: shellStyle, children: [_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, maxWidth: 520 }, children: [_jsx("h1", { style: { fontSize: "var(--text-xl)", fontWeight: 700, color: "var(--text-primary)", margin: 0, letterSpacing: "-0.02em" }, children: "Choose where capture writes" }), _jsx("p", { style: { fontSize: "var(--text-sm)", color: "var(--text-secondary)", margin: 0, lineHeight: 1.5 }, children: "Select the organization and workspace your fleet will write to. Nothing captures until you confirm." })] }), view.kind === "org-list" && (_jsx("div", { "data-testid": "onboarding-tenancy-org-list", style: { display: "flex", flexDirection: "column", gap: 10, width: "100%", maxWidth: 420 }, children: view.orgs.map((org) => (_jsx(Button, { variant: "secondary", size: "lg", "data-testid": "onboarding-tenancy-org-option", "data-org-id": org.id, disabled: busy, onClick: () => void openWorkspaces(org), children: entityLabel(org) }, org.id))) })), view.kind === "org-confirm" && (_jsxs("div", { "data-testid": "onboarding-tenancy-org-confirm", style: { display: "flex", flexDirection: "column", gap: 12, maxWidth: 420 }, children: [_jsx("p", { style: { fontSize: "var(--text-sm)", color: "var(--text-secondary)", margin: 0 }, children: "Your account has one organization. Confirm you want capture to write under:" }), _jsxs("code", { style: { fontFamily: "var(--font-mono)", fontSize: "var(--text-sm)", color: "var(--honey)" }, children: [entityLabel(view.org), " (", view.org.id, ")"] }), _jsx(Button, { variant: "primary", size: "lg", "data-testid": "onboarding-tenancy-org-confirm-btn", disabled: busy, onClick: () => void openWorkspaces(view.org), children: "Confirm organization" })] })), view.kind === "workspace-list" && (_jsxs("div", { "data-testid": "onboarding-tenancy-workspace-list", style: { display: "flex", flexDirection: "column", gap: 10, width: "100%", maxWidth: 420 }, children: [_jsxs("p", { style: { fontSize: "var(--text-xs)", color: "var(--text-tertiary)", margin: 0 }, children: ["Organization: ", entityLabel(view.org)] }), view.workspaces.length === 0 && !view.canCreate ? (_jsxs(_Fragment, { children: [_jsx("p", { "data-testid": "onboarding-tenancy-no-workspaces", style: { fontSize: "var(--text-sm)", color: "var(--text-secondary)", margin: 0 }, children: "No workspaces are available in this organization." }), _jsx(Button, { variant: "secondary", "data-testid": "onboarding-tenancy-back-orgs", disabled: busy, onClick: () => void loadOrgs(), children: "Back to organizations" })] })) : (_jsxs(_Fragment, { children: [view.workspaces.map((ws) => (_jsx(Button, { variant: "secondary", size: "lg", "data-testid": "onboarding-tenancy-workspace-option", "data-workspace-id": ws.id, disabled: busy, onClick: () => void persistSelection(view.org, ws), children: entityLabel(ws) }, ws.id))), view.canCreate && (_jsx("div", { style: { display: "flex", flexDirection: "column", gap: 8, marginTop: 8 }, children: !showCreate ? (_jsx(Button, { variant: "ghost", "data-testid": "onboarding-tenancy-create-toggle", disabled: busy, onClick: () => setShowCreate(true), children: "Create a new workspace" })) : (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [_jsx("input", { "data-testid": "onboarding-tenancy-create-input", type: "text", value: createName, placeholder: "New workspace name", disabled: busy, onChange: (e) => setCreateName(e.target.value), style: {
|
|
213
|
+
height: 36,
|
|
214
|
+
padding: "0 12px",
|
|
215
|
+
background: "var(--bg-surface)",
|
|
216
|
+
border: "1px solid var(--border-default)",
|
|
217
|
+
borderRadius: "var(--radius-md)",
|
|
218
|
+
color: "var(--text-primary)",
|
|
219
|
+
fontFamily: "var(--font-sans)",
|
|
220
|
+
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" })] }))] }));
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=tenancy-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenancy-step.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/tenancy-step.tsx"],"names":[],"mappings":"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"}
|