@legioncodeinc/hive 0.3.1 → 0.5.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.
Files changed (87) hide show
  1. package/README.md +1 -1
  2. package/dist/daemon/dashboard/app.js +11 -11
  3. package/dist/daemon/gate.d.ts +10 -6
  4. package/dist/daemon/gate.js +20 -8
  5. package/dist/daemon/gate.js.map +1 -1
  6. package/dist/daemon/installer/config.d.ts +2 -0
  7. package/dist/daemon/installer/config.js +5 -3
  8. package/dist/daemon/installer/config.js.map +1 -1
  9. package/dist/daemon/installer/funnel-telemetry.d.ts +17 -2
  10. package/dist/daemon/installer/funnel-telemetry.js +34 -3
  11. package/dist/daemon/installer/funnel-telemetry.js.map +1 -1
  12. package/dist/daemon/installer/routes.js +6 -2
  13. package/dist/daemon/installer/routes.js.map +1 -1
  14. package/dist/daemon/installer/security.d.ts +9 -2
  15. package/dist/daemon/installer/security.js +8 -0
  16. package/dist/daemon/installer/security.js.map +1 -1
  17. package/dist/daemon/installer/token.d.ts +8 -7
  18. package/dist/daemon/installer/token.js +40 -18
  19. package/dist/daemon/installer/token.js.map +1 -1
  20. package/dist/daemon/registry.d.ts +6 -0
  21. package/dist/daemon/registry.js +15 -17
  22. package/dist/daemon/registry.js.map +1 -1
  23. package/dist/daemon/server.d.ts +14 -0
  24. package/dist/daemon/server.js +19 -0
  25. package/dist/daemon/server.js.map +1 -1
  26. package/dist/daemon/setup-tenancy.d.ts +18 -0
  27. package/dist/daemon/setup-tenancy.js +37 -0
  28. package/dist/daemon/setup-tenancy.js.map +1 -0
  29. package/dist/dashboard/web/active-tenancy-display.d.ts +34 -0
  30. package/dist/dashboard/web/active-tenancy-display.js +84 -0
  31. package/dist/dashboard/web/active-tenancy-display.js.map +1 -0
  32. package/dist/dashboard/web/app.js +6 -2
  33. package/dist/dashboard/web/app.js.map +1 -1
  34. package/dist/dashboard/web/onboarding/contracts.d.ts +1 -1
  35. package/dist/dashboard/web/onboarding/contracts.js +9 -1
  36. package/dist/dashboard/web/onboarding/contracts.js.map +1 -1
  37. package/dist/dashboard/web/onboarding/login-step.d.ts +3 -4
  38. package/dist/dashboard/web/onboarding/login-step.js +12 -18
  39. package/dist/dashboard/web/onboarding/login-step.js.map +1 -1
  40. package/dist/dashboard/web/onboarding/onboarding-screen.d.ts +8 -4
  41. package/dist/dashboard/web/onboarding/onboarding-screen.js +90 -13
  42. package/dist/dashboard/web/onboarding/onboarding-screen.js.map +1 -1
  43. package/dist/dashboard/web/onboarding/tenancy-client.d.ts +19 -0
  44. package/dist/dashboard/web/onboarding/tenancy-client.js +84 -0
  45. package/dist/dashboard/web/onboarding/tenancy-client.js.map +1 -0
  46. package/dist/dashboard/web/onboarding/tenancy-contracts.d.ts +119 -0
  47. package/dist/dashboard/web/onboarding/tenancy-contracts.js +79 -0
  48. package/dist/dashboard/web/onboarding/tenancy-contracts.js.map +1 -0
  49. package/dist/dashboard/web/onboarding/tenancy-step.d.ts +32 -0
  50. package/dist/dashboard/web/onboarding/tenancy-step.js +223 -0
  51. package/dist/dashboard/web/onboarding/tenancy-step.js.map +1 -0
  52. package/dist/dashboard/web/pages/hive-graph.js +138 -43
  53. package/dist/dashboard/web/pages/hive-graph.js.map +1 -1
  54. package/dist/dashboard/web/wire.d.ts +111 -14
  55. package/dist/dashboard/web/wire.js +105 -0
  56. package/dist/dashboard/web/wire.js.map +1 -1
  57. package/dist/install/registry.d.ts +2 -2
  58. package/dist/install/registry.js +14 -7
  59. package/dist/install/registry.js.map +1 -1
  60. package/dist/lock.d.ts +5 -2
  61. package/dist/lock.js +36 -1
  62. package/dist/lock.js.map +1 -1
  63. package/dist/service/index.d.ts +5 -0
  64. package/dist/service/index.js +9 -1
  65. package/dist/service/index.js.map +1 -1
  66. package/dist/service/templates.d.ts +22 -3
  67. package/dist/service/templates.js +47 -10
  68. package/dist/service/templates.js.map +1 -1
  69. package/dist/shared/apiary-root.d.ts +28 -0
  70. package/dist/shared/apiary-root.js +71 -0
  71. package/dist/shared/apiary-root.js.map +1 -0
  72. package/dist/shared/constants.d.ts +0 -1
  73. package/dist/shared/constants.js +3 -5
  74. package/dist/shared/constants.js.map +1 -1
  75. package/dist/shared/legacy-paths.d.ts +22 -0
  76. package/dist/shared/legacy-paths.js +48 -0
  77. package/dist/shared/legacy-paths.js.map +1 -0
  78. package/dist/shared/registry-paths.d.ts +19 -0
  79. package/dist/shared/registry-paths.js +52 -0
  80. package/dist/shared/registry-paths.js.map +1 -0
  81. package/dist/shared/state-migration.d.ts +13 -0
  82. package/dist/shared/state-migration.js +92 -0
  83. package/dist/shared/state-migration.js.map +1 -0
  84. package/dist/telemetry/emit.d.ts +27 -14
  85. package/dist/telemetry/emit.js +20 -4
  86. package/dist/telemetry/emit.js.map +1 -1
  87. package/package.json +1 -1
@@ -24,6 +24,9 @@
24
24
  import { z } from "zod";
25
25
  import { type RoiTrendView, type RoiView } from "../contracts.js";
26
26
  import { type ProjectionDerivedEntry, type ProjectionFileEntry } from "./hive-graph-projection.js";
27
+ import { UNSELECTED_SETUP_TENANCY, type SetupTenancyWire } from "./onboarding/tenancy-contracts.js";
28
+ export type { SetupTenancyWire };
29
+ export { UNSELECTED_SETUP_TENANCY };
27
30
  /** The diagnostics view-model endpoints (served under `/api/diagnostics/*` + `/api/graph`). */
28
31
  export declare const ENDPOINTS: Readonly<{
29
32
  readonly kpis: "/api/diagnostics/kpis";
@@ -37,6 +40,8 @@ export declare const ENDPOINTS: Readonly<{
37
40
  readonly hiveGraphStatus: "/api/hive-graph/status";
38
41
  readonly hiveGraphProjection: "/api/hive-graph/projection";
39
42
  readonly hiveGraphBuild: "/api/hive-graph/build";
43
+ readonly hiveGraphProjects: "/api/hive-graph/projects";
44
+ readonly hiveGraphBrooding: "/api/hive-graph/projects/brooding";
40
45
  readonly memoryGraph: "/api/diagnostics/memory-graph";
41
46
  readonly recall: "/api/memories/recall";
42
47
  readonly memories: "/api/memories";
@@ -59,6 +64,7 @@ export declare const ENDPOINTS: Readonly<{
59
64
  readonly setupLogin: "/setup/login";
60
65
  readonly setupMigrate: "/setup/migrate-from-hivemind";
61
66
  readonly setupMigrateRollback: "/setup/migrate-from-hivemind/rollback";
67
+ readonly setupTenancy: "/setup/tenancy";
62
68
  readonly scopeOrgs: "/api/diagnostics/scope/orgs";
63
69
  readonly scopeWorkspaces: "/api/diagnostics/scope/workspaces";
64
70
  readonly scopeProjects: "/api/diagnostics/scope/projects";
@@ -194,18 +200,18 @@ export declare const SkillsSchema: z.ZodObject<{
194
200
  export type SkillRowWire = z.infer<typeof SkillRowSchema>;
195
201
  /** The per-section status discriminant → {@link import("../contracts.js").RoiSectionStatus}. */
196
202
  export declare const RoiSectionStatusSchema: z.ZodCatch<z.ZodEnum<{
203
+ absent: "absent";
197
204
  ok: "ok";
198
205
  unreachable: "unreachable";
199
206
  partial: "partial";
200
- absent: "absent";
201
207
  unauthenticated: "unauthenticated";
202
208
  }>>;
203
209
  /** The status default for a BILLING-backed line — `unreachable` (couldn't read), not `absent` (no data). */
204
210
  export declare const RoiBillingStatusSchema: z.ZodCatch<z.ZodEnum<{
211
+ absent: "absent";
205
212
  ok: "ok";
206
213
  unreachable: "unreachable";
207
214
  partial: "partial";
208
- absent: "absent";
209
215
  unauthenticated: "unauthenticated";
210
216
  }>>;
211
217
  /** The cost-basis tag → {@link import("../contracts.js").RoiCostBasisTag}. */
@@ -223,10 +229,10 @@ export declare const RoiAssumptionSchema: z.ZodObject<{
223
229
  /** The savings section (e-AC-3) → {@link import("../contracts.js").RoiSavingsSection}. */
224
230
  export declare const RoiSavingsSectionSchema: z.ZodObject<{
225
231
  status: z.ZodCatch<z.ZodEnum<{
232
+ absent: "absent";
226
233
  ok: "ok";
227
234
  unreachable: "unreachable";
228
235
  partial: "partial";
229
- absent: "absent";
230
236
  unauthenticated: "unauthenticated";
231
237
  }>>;
232
238
  measuredCents: z.ZodCatch<z.ZodNumber>;
@@ -241,10 +247,10 @@ export declare const RoiSavingsSectionSchema: z.ZodObject<{
241
247
  /** The infra cost section (e-AC-6) → {@link import("../contracts.js").RoiInfraSection}. */
242
248
  export declare const RoiInfraSectionSchema: z.ZodObject<{
243
249
  status: z.ZodCatch<z.ZodEnum<{
250
+ absent: "absent";
244
251
  ok: "ok";
245
252
  unreachable: "unreachable";
246
253
  partial: "partial";
247
- absent: "absent";
248
254
  unauthenticated: "unauthenticated";
249
255
  }>>;
250
256
  cents: z.ZodCatch<z.ZodNumber>;
@@ -262,10 +268,10 @@ export declare const RoiPollinationLineSchema: z.ZodObject<{
262
268
  /** The pollination cost section (e-AC-6) → {@link import("../contracts.js").RoiPollinationSection}. */
263
269
  export declare const RoiPollinationSectionSchema: z.ZodObject<{
264
270
  status: z.ZodCatch<z.ZodEnum<{
271
+ absent: "absent";
265
272
  ok: "ok";
266
273
  unreachable: "unreachable";
267
274
  partial: "partial";
268
- absent: "absent";
269
275
  unauthenticated: "unauthenticated";
270
276
  }>>;
271
277
  cents: z.ZodCatch<z.ZodNumber>;
@@ -277,10 +283,10 @@ export declare const RoiPollinationSectionSchema: z.ZodObject<{
277
283
  /** The net-ROI section (e-AC-6) → {@link import("../contracts.js").RoiNetSection}. */
278
284
  export declare const RoiNetSectionSchema: z.ZodObject<{
279
285
  status: z.ZodCatch<z.ZodEnum<{
286
+ absent: "absent";
280
287
  ok: "ok";
281
288
  unreachable: "unreachable";
282
289
  partial: "partial";
283
- absent: "absent";
284
290
  unauthenticated: "unauthenticated";
285
291
  }>>;
286
292
  computed: z.ZodCatch<z.ZodBoolean>;
@@ -333,10 +339,10 @@ export declare const RoiRollupSchema: z.ZodObject<{
333
339
  export declare const RoiViewSchema: z.ZodObject<{
334
340
  savings: z.ZodCatch<z.ZodObject<{
335
341
  status: z.ZodCatch<z.ZodEnum<{
342
+ absent: "absent";
336
343
  ok: "ok";
337
344
  unreachable: "unreachable";
338
345
  partial: "partial";
339
- absent: "absent";
340
346
  unauthenticated: "unauthenticated";
341
347
  }>>;
342
348
  measuredCents: z.ZodCatch<z.ZodNumber>;
@@ -350,10 +356,10 @@ export declare const RoiViewSchema: z.ZodObject<{
350
356
  }, z.core.$strip>>;
351
357
  infra: z.ZodCatch<z.ZodObject<{
352
358
  status: z.ZodCatch<z.ZodEnum<{
359
+ absent: "absent";
353
360
  ok: "ok";
354
361
  unreachable: "unreachable";
355
362
  partial: "partial";
356
- absent: "absent";
357
363
  unauthenticated: "unauthenticated";
358
364
  }>>;
359
365
  cents: z.ZodCatch<z.ZodNumber>;
@@ -365,10 +371,10 @@ export declare const RoiViewSchema: z.ZodObject<{
365
371
  }, z.core.$strip>>;
366
372
  pollination: z.ZodCatch<z.ZodObject<{
367
373
  status: z.ZodCatch<z.ZodEnum<{
374
+ absent: "absent";
368
375
  ok: "ok";
369
376
  unreachable: "unreachable";
370
377
  partial: "partial";
371
- absent: "absent";
372
378
  unauthenticated: "unauthenticated";
373
379
  }>>;
374
380
  cents: z.ZodCatch<z.ZodNumber>;
@@ -379,10 +385,10 @@ export declare const RoiViewSchema: z.ZodObject<{
379
385
  }, z.core.$strip>>;
380
386
  net: z.ZodCatch<z.ZodObject<{
381
387
  status: z.ZodCatch<z.ZodEnum<{
388
+ absent: "absent";
382
389
  ok: "ok";
383
390
  unreachable: "unreachable";
384
391
  partial: "partial";
385
- absent: "absent";
386
392
  unauthenticated: "unauthenticated";
387
393
  }>>;
388
394
  computed: z.ZodCatch<z.ZodBoolean>;
@@ -438,10 +444,10 @@ export declare const RoiTrendSeriesSchema: z.ZodObject<{
438
444
  /** `GET /api/diagnostics/roi/trend` → {@link import("../contracts.js").RoiTrendView}. */
439
445
  export declare const RoiTrendViewSchema: z.ZodObject<{
440
446
  status: z.ZodCatch<z.ZodEnum<{
447
+ absent: "absent";
441
448
  ok: "ok";
442
449
  unreachable: "unreachable";
443
450
  partial: "partial";
444
- absent: "absent";
445
451
  unauthenticated: "unauthenticated";
446
452
  }>>;
447
453
  series: z.ZodCatch<z.ZodArray<z.ZodObject<{
@@ -1099,6 +1105,79 @@ export interface HiveGraphStatusResultWire extends HiveGraphStatusWire {
1099
1105
  export interface HiveGraphSearchResultWire extends HiveGraphSearchWire {
1100
1106
  readonly unreachable: boolean;
1101
1107
  }
1108
+ /** Per-project effective brooding state returned by nectar's `GET /api/hive-graph/projects`. */
1109
+ export declare const NectarProjectBroodingSchema: z.ZodEnum<{
1110
+ active: "active";
1111
+ paused: "paused";
1112
+ "global-paused": "global-paused";
1113
+ }>;
1114
+ export declare const NectarProjectCountsSchema: z.ZodCatch<z.ZodObject<{
1115
+ described: z.ZodCatch<z.ZodNumber>;
1116
+ pending: z.ZodCatch<z.ZodNumber>;
1117
+ }, z.core.$strip>>;
1118
+ /** One active nectar project row (019b `GET /projects`). */
1119
+ export declare const NectarProjectRowSchema: z.ZodObject<{
1120
+ projectId: z.ZodCatch<z.ZodString>;
1121
+ name: z.ZodCatch<z.ZodString>;
1122
+ path: z.ZodCatch<z.ZodString>;
1123
+ brooding: z.ZodCatch<z.ZodEnum<{
1124
+ active: "active";
1125
+ paused: "paused";
1126
+ "global-paused": "global-paused";
1127
+ }>>;
1128
+ watcher: z.ZodCatch<z.ZodString>;
1129
+ counts: z.ZodCatch<z.ZodObject<{
1130
+ described: z.ZodCatch<z.ZodNumber>;
1131
+ pending: z.ZodCatch<z.ZodNumber>;
1132
+ }, z.core.$strip>>;
1133
+ }, z.core.$strip>;
1134
+ export type NectarProjectRowWire = z.infer<typeof NectarProjectRowSchema>;
1135
+ export declare const NectarProjectsBodySchema: z.ZodObject<{
1136
+ globalBrooding: z.ZodCatch<z.ZodEnum<{
1137
+ paused: "paused";
1138
+ on: "on";
1139
+ }>>;
1140
+ projects: z.ZodCatch<z.ZodArray<z.ZodObject<{
1141
+ projectId: z.ZodCatch<z.ZodString>;
1142
+ name: z.ZodCatch<z.ZodString>;
1143
+ path: z.ZodCatch<z.ZodString>;
1144
+ brooding: z.ZodCatch<z.ZodEnum<{
1145
+ active: "active";
1146
+ paused: "paused";
1147
+ "global-paused": "global-paused";
1148
+ }>>;
1149
+ watcher: z.ZodCatch<z.ZodString>;
1150
+ counts: z.ZodCatch<z.ZodObject<{
1151
+ described: z.ZodCatch<z.ZodNumber>;
1152
+ pending: z.ZodCatch<z.ZodNumber>;
1153
+ }, z.core.$strip>>;
1154
+ }, z.core.$strip>>>;
1155
+ tenancyOrgName: z.ZodOptional<z.ZodString>;
1156
+ tenancyWorkspaceName: z.ZodOptional<z.ZodString>;
1157
+ tenancyOrgId: z.ZodOptional<z.ZodString>;
1158
+ tenancyWorkspaceId: z.ZodOptional<z.ZodString>;
1159
+ }, z.core.$strip>;
1160
+ export type NectarProjectsBodyWire = z.infer<typeof NectarProjectsBodySchema>;
1161
+ /** The nectar projects read-model the Hive Graph page polls (fail-soft `unreachable` flag). */
1162
+ export interface NectarProjectsWire extends NectarProjectsBodyWire {
1163
+ readonly unreachable: boolean;
1164
+ }
1165
+ export declare const EMPTY_NECTAR_PROJECTS: NectarProjectsWire;
1166
+ export declare const UNREACHABLE_NECTAR_PROJECTS: NectarProjectsWire;
1167
+ /** Body for `POST /api/hive-graph/projects/brooding` (per-project or global). */
1168
+ export type SetNectarBroodingBody = {
1169
+ readonly projectId: string;
1170
+ readonly brooding: "on" | "off";
1171
+ } | {
1172
+ readonly global: "on" | "paused";
1173
+ };
1174
+ /** The brooding toggle ack mirrors the persisted projects read-model (019b). */
1175
+ export type NectarBroodingAckWire = NectarProjectsWire;
1176
+ /** PRD-011: tenancy read with fail-soft unreachable flag (tv-AC-4). */
1177
+ export interface SetupTenancyResultWire extends SetupTenancyWire {
1178
+ readonly unreachable: boolean;
1179
+ }
1180
+ export declare const UNREACHABLE_SETUP_TENANCY: SetupTenancyResultWire;
1102
1181
  /**
1103
1182
  * The generous client-side timeout (ms) for `buildGraph()`. The build parses the WHOLE repo with
1104
1183
  * tree-sitter and can take many seconds to tens of seconds; a short default fetch timeout would abort
@@ -1274,8 +1353,8 @@ export declare const AuthStatusSchema: z.ZodObject<{
1274
1353
  agentId: z.ZodCatch<z.ZodString>;
1275
1354
  source: z.ZodCatch<z.ZodEnum<{
1276
1355
  file: "file";
1277
- none: "none";
1278
1356
  env: "env";
1357
+ none: "none";
1279
1358
  }>>;
1280
1359
  savedAt: z.ZodCatch<z.ZodString>;
1281
1360
  expiresAt: z.ZodOptional<z.ZodNumber>;
@@ -1311,17 +1390,17 @@ export declare const SetupStateSchema: z.ZodObject<{
1311
1390
  hivemind: z.ZodCatch<z.ZodBoolean>;
1312
1391
  }, z.core.$strip>>;
1313
1392
  phase: z.ZodCatch<z.ZodEnum<{
1393
+ migrated: "migrated";
1314
1394
  linking: "linking";
1315
1395
  installed: "installed";
1316
1396
  fresh: "fresh";
1317
1397
  linked: "linked";
1318
1398
  migrating: "migrating";
1319
- migrated: "migrated";
1320
1399
  }>>;
1321
1400
  priorTool: z.ZodCatch<z.ZodObject<{
1322
1401
  hivemind: z.ZodCatch<z.ZodEnum<{
1323
- absent: "absent";
1324
1402
  migrated: "migrated";
1403
+ absent: "absent";
1325
1404
  present: "present";
1326
1405
  }>>;
1327
1406
  }, z.core.$strip>>;
@@ -1800,6 +1879,17 @@ export interface WireClient {
1800
1879
  * 409 already_running, and success honestly — never throws into React.
1801
1880
  */
1802
1881
  hiveGraphBuild(): Promise<HiveGraphBuildAck>;
1882
+ /**
1883
+ * PRD-019c — read nectar's active-project set with brooding state (`GET /api/hive-graph/projects`).
1884
+ * Degrades to {@link UNREACHABLE_NECTAR_PROJECTS} when nectar is down (never throws).
1885
+ */
1886
+ nectarProjects(): Promise<NectarProjectsWire>;
1887
+ /**
1888
+ * PRD-019c — set per-project or global brooding (`POST /api/hive-graph/projects/brooding`).
1889
+ * Returns the persisted read-model on success; degrades to {@link UNREACHABLE_NECTAR_PROJECTS} on failure.
1890
+ * The caller re-lists after a successful write so the UI reflects nectar's truth, never optimistic-only.
1891
+ */
1892
+ setNectarBrooding(body: SetNectarBroodingBody): Promise<NectarBroodingAckWire>;
1803
1893
  /** PRD-032c — read the vault `setting` class + the provider→model catalog (`GET /api/settings`). */
1804
1894
  vaultSettings(): Promise<VaultSettingsWire>;
1805
1895
  /**
@@ -1880,6 +1970,13 @@ export interface WireClient {
1880
1970
  * The response carries NO token (the schema has no token field by construction — c-AC-4).
1881
1971
  */
1882
1972
  setupLogin(): Promise<SetupLoginWire | null>;
1973
+ /**
1974
+ * PRD-011: read explicit tenancy selection state (`GET /setup/tenancy`). Degrades to
1975
+ * {@link UNREACHABLE_SETUP_TENANCY} on failure; never throws. No token in the body. This is the
1976
+ * ONLY tenancy method on WireClient (the tv-AC-4 display read); the onboarding step's
1977
+ * enumerate/select/create surface lives in `onboarding/tenancy-client.ts` (ts-AC-11).
1978
+ */
1979
+ setupTenancy(): Promise<SetupTenancyResultWire>;
1883
1980
  /**
1884
1981
  * PRD-050d — "Proceed with Honeycomb": run the Hivemind→Honeycomb migration (`POST
1885
1982
  * /setup/migrate-from-hivemind`). The daemon backs up + uninstalls Hivemind idempotently, then
@@ -24,6 +24,11 @@
24
24
  import { z } from "zod";
25
25
  import { EMPTY_ROI_TREND, EMPTY_ROI_VIEW } from "../contracts.js";
26
26
  import { projectionToGraphWire } from "./hive-graph-projection.js";
27
+ // PRD-011: only the `GET /setup/tenancy` read lives on WireClient (the display surfaces, tv-AC-4).
28
+ // The onboarding step's enumerate/select/create calls go through `onboarding/tenancy-client.ts`
29
+ // exclusively (ts-AC-11), deliberately NOT duplicated here, so the two clients cannot drift.
30
+ import { SetupTenancySchema, UNSELECTED_SETUP_TENANCY } from "./onboarding/tenancy-contracts.js";
31
+ export { UNSELECTED_SETUP_TENANCY };
27
32
  // ─────────────────────────────────────────────────────────────────────────────
28
33
  // Endpoint paths (single source — the host serves these under the daemon origin).
29
34
  // ─────────────────────────────────────────────────────────────────────────────
@@ -44,6 +49,9 @@ export const ENDPOINTS = Object.freeze({
44
49
  hiveGraphStatus: "/api/hive-graph/status",
45
50
  hiveGraphProjection: "/api/hive-graph/projection",
46
51
  hiveGraphBuild: "/api/hive-graph/build",
52
+ // PRD-019b/c — nectar active-project set + brooding control (proxied to nectar :3854).
53
+ hiveGraphProjects: "/api/hive-graph/projects",
54
+ hiveGraphBrooding: "/api/hive-graph/projects/brooding",
47
55
  // PRD-041b — the memory-graph view-model (the knowledge graph of memories/entities). Served off
48
56
  // the diagnostics group (`/api/diagnostics/memory-graph`), mirroring `/api/graph`. Returns the SAME
49
57
  // `GraphView` shape so the existing `GraphCanvas` renders it unchanged; `built:false` until PRD-008
@@ -97,6 +105,9 @@ export const ENDPOINTS = Object.freeze({
97
105
  // crash-recovery "Roll back" affordance (d-AC-7).
98
106
  setupMigrate: "/setup/migrate-from-hivemind",
99
107
  setupMigrateRollback: "/setup/migrate-from-hivemind/rollback",
108
+ // PRD-011: the explicit-tenancy read (proxied to honeycomb `/setup/tenancy`). The onboarding
109
+ // step's enumerate/select/create endpoints live in `onboarding/tenancy-client.ts` only.
110
+ setupTenancy: "/setup/tenancy",
100
111
  // PRD-049e — the dashboard scope-switcher enumeration reads (local-mode-only loopback). The
101
112
  // switcher hydrates its Org→Workspace→Project dropdowns from these. `scopeOrgs`/`scopeWorkspaces`
102
113
  // are privilege-scoped by the daemon's token (`GET /organizations` / `GET /workspaces`);
@@ -761,6 +772,48 @@ export const FAILED_HIVE_GRAPH_BUILD_ACK = Object.freeze({
761
772
  state: "failed",
762
773
  message: "Build failed",
763
774
  });
775
+ // ─────────────────────────────────────────────────────────────────────────────
776
+ // PRD-019b/c — nectar projects + brooding wire shapes (`GET/POST .../projects*`).
777
+ // ─────────────────────────────────────────────────────────────────────────────
778
+ /** Per-project effective brooding state returned by nectar's `GET /api/hive-graph/projects`. */
779
+ export const NectarProjectBroodingSchema = z.enum(["active", "paused", "global-paused"]);
780
+ export const NectarProjectCountsSchema = z
781
+ .object({
782
+ described: z.number().catch(0),
783
+ pending: z.number().catch(0),
784
+ })
785
+ .catch({ described: 0, pending: 0 });
786
+ /** One active nectar project row (019b `GET /projects`). */
787
+ export const NectarProjectRowSchema = z.object({
788
+ projectId: z.string().catch(""),
789
+ name: z.string().catch(""),
790
+ path: z.string().catch(""),
791
+ brooding: NectarProjectBroodingSchema.catch("active"),
792
+ watcher: z.string().catch(""),
793
+ counts: NectarProjectCountsSchema,
794
+ });
795
+ export const NectarProjectsBodySchema = z.object({
796
+ globalBrooding: z.enum(["on", "paused"]).catch("on"),
797
+ projects: z.array(NectarProjectRowSchema).catch([]),
798
+ tenancyOrgName: z.string().optional(),
799
+ tenancyWorkspaceName: z.string().optional(),
800
+ tenancyOrgId: z.string().optional(),
801
+ tenancyWorkspaceId: z.string().optional(),
802
+ });
803
+ export const EMPTY_NECTAR_PROJECTS = Object.freeze({
804
+ globalBrooding: "on",
805
+ projects: [],
806
+ unreachable: false,
807
+ });
808
+ export const UNREACHABLE_NECTAR_PROJECTS = Object.freeze({
809
+ globalBrooding: "on",
810
+ projects: [],
811
+ unreachable: true,
812
+ });
813
+ export const UNREACHABLE_SETUP_TENANCY = Object.freeze({
814
+ ...UNSELECTED_SETUP_TENANCY,
815
+ unreachable: true,
816
+ });
764
817
  /**
765
818
  * The generous client-side timeout (ms) for `buildGraph()`. The build parses the WHOLE repo with
766
819
  * tree-sitter and can take many seconds to tens of seconds; a short default fetch timeout would abort
@@ -1791,6 +1844,40 @@ export function createWireClient(options = {}) {
1791
1844
  clearTimeout(timer);
1792
1845
  }
1793
1846
  },
1847
+ async nectarProjects() {
1848
+ try {
1849
+ const res = await fetchImpl(url(ENDPOINTS.hiveGraphProjects), {
1850
+ headers: { accept: "application/json", ...DASHBOARD_SESSION_HEADERS },
1851
+ });
1852
+ if (!res.ok)
1853
+ return UNREACHABLE_NECTAR_PROJECTS;
1854
+ const parsed = NectarProjectsBodySchema.safeParse(await res.json());
1855
+ if (!parsed.success)
1856
+ return UNREACHABLE_NECTAR_PROJECTS;
1857
+ return { ...parsed.data, unreachable: false };
1858
+ }
1859
+ catch {
1860
+ return UNREACHABLE_NECTAR_PROJECTS;
1861
+ }
1862
+ },
1863
+ async setNectarBrooding(body) {
1864
+ try {
1865
+ const res = await fetchImpl(url(ENDPOINTS.hiveGraphBrooding), {
1866
+ method: "POST",
1867
+ headers: { "content-type": "application/json", accept: "application/json", ...DASHBOARD_SESSION_HEADERS },
1868
+ body: JSON.stringify(body),
1869
+ });
1870
+ if (!res.ok)
1871
+ return UNREACHABLE_NECTAR_PROJECTS;
1872
+ const parsed = NectarProjectsBodySchema.safeParse(await res.json());
1873
+ if (!parsed.success)
1874
+ return UNREACHABLE_NECTAR_PROJECTS;
1875
+ return { ...parsed.data, unreachable: false };
1876
+ }
1877
+ catch {
1878
+ return UNREACHABLE_NECTAR_PROJECTS;
1879
+ }
1880
+ },
1794
1881
  async vaultSettings() {
1795
1882
  // GET the `setting` class + catalog; a malformed/absent body degrades to the empty
1796
1883
  // view (nothing selected, no catalog) so the panel renders its empty state, never throws.
@@ -1885,6 +1972,24 @@ export function createWireClient(options = {}) {
1885
1972
  // a network failure → null (the button shows an honest error). The body carries NO token.
1886
1973
  return postJson(fetchImpl, url(ENDPOINTS.setupLogin), {}, SetupLoginSchema);
1887
1974
  },
1975
+ async setupTenancy() {
1976
+ // GET the explicit-tenancy state (PRD-011b tv-AC-4). A non-2xx / network / malformed
1977
+ // body degrades to the honest unreachable state (never a fabricated tenancy, never a
1978
+ // throw). The onboarding step's enumerate/select/create calls do NOT live here; they
1979
+ // go through `onboarding/tenancy-client.ts` exclusively (ts-AC-11, no drift).
1980
+ try {
1981
+ const res = await fetchImpl(url(ENDPOINTS.setupTenancy), { headers: { accept: "application/json" } });
1982
+ if (!res.ok)
1983
+ return UNREACHABLE_SETUP_TENANCY;
1984
+ const parsed = SetupTenancySchema.safeParse(await res.json());
1985
+ if (!parsed.success)
1986
+ return UNREACHABLE_SETUP_TENANCY;
1987
+ return { ...parsed.data, unreachable: false };
1988
+ }
1989
+ catch {
1990
+ return UNREACHABLE_SETUP_TENANCY;
1991
+ }
1992
+ },
1888
1993
  async migrateFromHivemind() {
1889
1994
  // POST the migration trigger; the daemon runs the guarded backup->uninstall->adopt transaction
1890
1995
  // and returns the terminal phase + message + backup path (+ needsLogin/migrated flags). A non-2xx