@legioncodeinc/hive 0.3.0 → 0.4.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 (94) hide show
  1. package/README.md +1 -1
  2. package/assets/brand/activeloop-full-mark-logo-on-dark.svg +209 -0
  3. package/assets/brand/activeloop-full-mark-logo.svg +208 -0
  4. package/assets/brand/divider-major.svg +1 -0
  5. package/assets/brand/divider-minor.svg +1 -0
  6. package/assets/brand/doctor-mark.svg +1 -0
  7. package/assets/brand/hive-mark.svg +1 -0
  8. package/assets/brand/hive-wordmark-black.svg +1 -0
  9. package/assets/brand/hive-wordmark-on-dark.svg +1 -0
  10. package/assets/brand/legion-logo-dark.svg +16 -0
  11. package/assets/brand/legion-logo-light.svg +16 -0
  12. package/assets/brand/nectar-mark.svg +1 -0
  13. package/assets/logos/fonts/Inter-Italic-VariableFont_opsz_wght.ttf +0 -0
  14. package/assets/logos/fonts/Inter-VariableFont_opsz_wght.ttf +0 -0
  15. package/assets/logos/fonts/JetBrainsMono-Bold.woff2 +0 -0
  16. package/assets/logos/fonts/JetBrainsMono-Medium.woff2 +0 -0
  17. package/assets/logos/fonts/JetBrainsMono-Regular.woff2 +0 -0
  18. package/assets/logos/fonts/JetBrainsMono-SemiBold.woff2 +0 -0
  19. package/assets/logos/honeycomb-memory-cluster.svg +17 -0
  20. package/assets/styles.css +11 -0
  21. package/assets/tokens/base.css +76 -0
  22. package/assets/tokens/colors.css +111 -0
  23. package/assets/tokens/fonts.css +32 -0
  24. package/assets/tokens/spacing.css +48 -0
  25. package/assets/tokens/typography.css +38 -0
  26. package/dist/daemon/dashboard/app.js +12 -12
  27. package/dist/daemon/installer/bin-resolver.js +22 -1
  28. package/dist/daemon/installer/bin-resolver.js.map +1 -1
  29. package/dist/daemon/installer/config.d.ts +2 -0
  30. package/dist/daemon/installer/config.js +5 -3
  31. package/dist/daemon/installer/config.js.map +1 -1
  32. package/dist/daemon/installer/install-state.d.ts +6 -0
  33. package/dist/daemon/installer/install-state.js +18 -1
  34. package/dist/daemon/installer/install-state.js.map +1 -1
  35. package/dist/daemon/installer/spawn.d.ts +1 -0
  36. package/dist/daemon/installer/spawn.js +13 -1
  37. package/dist/daemon/installer/spawn.js.map +1 -1
  38. package/dist/daemon/installer/token.d.ts +8 -7
  39. package/dist/daemon/installer/token.js +40 -18
  40. package/dist/daemon/installer/token.js.map +1 -1
  41. package/dist/daemon/registry.d.ts +6 -0
  42. package/dist/daemon/registry.js +15 -17
  43. package/dist/daemon/registry.js.map +1 -1
  44. package/dist/daemon/server.d.ts +11 -0
  45. package/dist/daemon/server.js +18 -0
  46. package/dist/daemon/server.js.map +1 -1
  47. package/dist/dashboard/web/onboarding/install-card.d.ts +3 -2
  48. package/dist/dashboard/web/onboarding/install-card.js +2 -1
  49. package/dist/dashboard/web/onboarding/install-card.js.map +1 -1
  50. package/dist/dashboard/web/onboarding/onboarding-screen.d.ts +1 -1
  51. package/dist/dashboard/web/onboarding/onboarding-screen.js +34 -2
  52. package/dist/dashboard/web/onboarding/onboarding-screen.js.map +1 -1
  53. package/dist/dashboard/web/onboarding/use-install-dwell.d.ts +12 -7
  54. package/dist/dashboard/web/onboarding/use-install-dwell.js +12 -7
  55. package/dist/dashboard/web/onboarding/use-install-dwell.js.map +1 -1
  56. package/dist/dashboard/web/onboarding/use-onboarding-token.d.ts +7 -2
  57. package/dist/dashboard/web/onboarding/use-onboarding-token.js +10 -3
  58. package/dist/dashboard/web/onboarding/use-onboarding-token.js.map +1 -1
  59. package/dist/dashboard/web/pages/hive-graph.js +128 -42
  60. package/dist/dashboard/web/pages/hive-graph.js.map +1 -1
  61. package/dist/dashboard/web/wire.d.ts +91 -14
  62. package/dist/dashboard/web/wire.js +71 -0
  63. package/dist/dashboard/web/wire.js.map +1 -1
  64. package/dist/install/registry.d.ts +2 -2
  65. package/dist/install/registry.js +14 -7
  66. package/dist/install/registry.js.map +1 -1
  67. package/dist/lock.d.ts +5 -2
  68. package/dist/lock.js +36 -1
  69. package/dist/lock.js.map +1 -1
  70. package/dist/service/index.d.ts +5 -0
  71. package/dist/service/index.js +9 -1
  72. package/dist/service/index.js.map +1 -1
  73. package/dist/service/templates.d.ts +22 -3
  74. package/dist/service/templates.js +47 -10
  75. package/dist/service/templates.js.map +1 -1
  76. package/dist/shared/apiary-root.d.ts +28 -0
  77. package/dist/shared/apiary-root.js +71 -0
  78. package/dist/shared/apiary-root.js.map +1 -0
  79. package/dist/shared/constants.d.ts +0 -1
  80. package/dist/shared/constants.js +3 -5
  81. package/dist/shared/constants.js.map +1 -1
  82. package/dist/shared/legacy-paths.d.ts +22 -0
  83. package/dist/shared/legacy-paths.js +48 -0
  84. package/dist/shared/legacy-paths.js.map +1 -0
  85. package/dist/shared/registry-paths.d.ts +19 -0
  86. package/dist/shared/registry-paths.js +52 -0
  87. package/dist/shared/registry-paths.js.map +1 -0
  88. package/dist/shared/state-migration.d.ts +13 -0
  89. package/dist/shared/state-migration.js +92 -0
  90. package/dist/shared/state-migration.js.map +1 -0
  91. package/dist/telemetry/emit.d.ts +10 -10
  92. package/dist/telemetry/emit.js +12 -3
  93. package/dist/telemetry/emit.js.map +1 -1
  94. package/package.json +6 -2
@@ -37,6 +37,8 @@ export declare const ENDPOINTS: Readonly<{
37
37
  readonly hiveGraphStatus: "/api/hive-graph/status";
38
38
  readonly hiveGraphProjection: "/api/hive-graph/projection";
39
39
  readonly hiveGraphBuild: "/api/hive-graph/build";
40
+ readonly hiveGraphProjects: "/api/hive-graph/projects";
41
+ readonly hiveGraphBrooding: "/api/hive-graph/projects/brooding";
40
42
  readonly memoryGraph: "/api/diagnostics/memory-graph";
41
43
  readonly recall: "/api/memories/recall";
42
44
  readonly memories: "/api/memories";
@@ -194,18 +196,18 @@ export declare const SkillsSchema: z.ZodObject<{
194
196
  export type SkillRowWire = z.infer<typeof SkillRowSchema>;
195
197
  /** The per-section status discriminant → {@link import("../contracts.js").RoiSectionStatus}. */
196
198
  export declare const RoiSectionStatusSchema: z.ZodCatch<z.ZodEnum<{
199
+ absent: "absent";
197
200
  ok: "ok";
198
201
  unreachable: "unreachable";
199
202
  partial: "partial";
200
- absent: "absent";
201
203
  unauthenticated: "unauthenticated";
202
204
  }>>;
203
205
  /** The status default for a BILLING-backed line — `unreachable` (couldn't read), not `absent` (no data). */
204
206
  export declare const RoiBillingStatusSchema: z.ZodCatch<z.ZodEnum<{
207
+ absent: "absent";
205
208
  ok: "ok";
206
209
  unreachable: "unreachable";
207
210
  partial: "partial";
208
- absent: "absent";
209
211
  unauthenticated: "unauthenticated";
210
212
  }>>;
211
213
  /** The cost-basis tag → {@link import("../contracts.js").RoiCostBasisTag}. */
@@ -223,10 +225,10 @@ export declare const RoiAssumptionSchema: z.ZodObject<{
223
225
  /** The savings section (e-AC-3) → {@link import("../contracts.js").RoiSavingsSection}. */
224
226
  export declare const RoiSavingsSectionSchema: z.ZodObject<{
225
227
  status: z.ZodCatch<z.ZodEnum<{
228
+ absent: "absent";
226
229
  ok: "ok";
227
230
  unreachable: "unreachable";
228
231
  partial: "partial";
229
- absent: "absent";
230
232
  unauthenticated: "unauthenticated";
231
233
  }>>;
232
234
  measuredCents: z.ZodCatch<z.ZodNumber>;
@@ -241,10 +243,10 @@ export declare const RoiSavingsSectionSchema: z.ZodObject<{
241
243
  /** The infra cost section (e-AC-6) → {@link import("../contracts.js").RoiInfraSection}. */
242
244
  export declare const RoiInfraSectionSchema: z.ZodObject<{
243
245
  status: z.ZodCatch<z.ZodEnum<{
246
+ absent: "absent";
244
247
  ok: "ok";
245
248
  unreachable: "unreachable";
246
249
  partial: "partial";
247
- absent: "absent";
248
250
  unauthenticated: "unauthenticated";
249
251
  }>>;
250
252
  cents: z.ZodCatch<z.ZodNumber>;
@@ -262,10 +264,10 @@ export declare const RoiPollinationLineSchema: z.ZodObject<{
262
264
  /** The pollination cost section (e-AC-6) → {@link import("../contracts.js").RoiPollinationSection}. */
263
265
  export declare const RoiPollinationSectionSchema: z.ZodObject<{
264
266
  status: z.ZodCatch<z.ZodEnum<{
267
+ absent: "absent";
265
268
  ok: "ok";
266
269
  unreachable: "unreachable";
267
270
  partial: "partial";
268
- absent: "absent";
269
271
  unauthenticated: "unauthenticated";
270
272
  }>>;
271
273
  cents: z.ZodCatch<z.ZodNumber>;
@@ -277,10 +279,10 @@ export declare const RoiPollinationSectionSchema: z.ZodObject<{
277
279
  /** The net-ROI section (e-AC-6) → {@link import("../contracts.js").RoiNetSection}. */
278
280
  export declare const RoiNetSectionSchema: z.ZodObject<{
279
281
  status: z.ZodCatch<z.ZodEnum<{
282
+ absent: "absent";
280
283
  ok: "ok";
281
284
  unreachable: "unreachable";
282
285
  partial: "partial";
283
- absent: "absent";
284
286
  unauthenticated: "unauthenticated";
285
287
  }>>;
286
288
  computed: z.ZodCatch<z.ZodBoolean>;
@@ -333,10 +335,10 @@ export declare const RoiRollupSchema: z.ZodObject<{
333
335
  export declare const RoiViewSchema: z.ZodObject<{
334
336
  savings: z.ZodCatch<z.ZodObject<{
335
337
  status: z.ZodCatch<z.ZodEnum<{
338
+ absent: "absent";
336
339
  ok: "ok";
337
340
  unreachable: "unreachable";
338
341
  partial: "partial";
339
- absent: "absent";
340
342
  unauthenticated: "unauthenticated";
341
343
  }>>;
342
344
  measuredCents: z.ZodCatch<z.ZodNumber>;
@@ -350,10 +352,10 @@ export declare const RoiViewSchema: z.ZodObject<{
350
352
  }, z.core.$strip>>;
351
353
  infra: z.ZodCatch<z.ZodObject<{
352
354
  status: z.ZodCatch<z.ZodEnum<{
355
+ absent: "absent";
353
356
  ok: "ok";
354
357
  unreachable: "unreachable";
355
358
  partial: "partial";
356
- absent: "absent";
357
359
  unauthenticated: "unauthenticated";
358
360
  }>>;
359
361
  cents: z.ZodCatch<z.ZodNumber>;
@@ -365,10 +367,10 @@ export declare const RoiViewSchema: z.ZodObject<{
365
367
  }, z.core.$strip>>;
366
368
  pollination: z.ZodCatch<z.ZodObject<{
367
369
  status: z.ZodCatch<z.ZodEnum<{
370
+ absent: "absent";
368
371
  ok: "ok";
369
372
  unreachable: "unreachable";
370
373
  partial: "partial";
371
- absent: "absent";
372
374
  unauthenticated: "unauthenticated";
373
375
  }>>;
374
376
  cents: z.ZodCatch<z.ZodNumber>;
@@ -379,10 +381,10 @@ export declare const RoiViewSchema: z.ZodObject<{
379
381
  }, z.core.$strip>>;
380
382
  net: z.ZodCatch<z.ZodObject<{
381
383
  status: z.ZodCatch<z.ZodEnum<{
384
+ absent: "absent";
382
385
  ok: "ok";
383
386
  unreachable: "unreachable";
384
387
  partial: "partial";
385
- absent: "absent";
386
388
  unauthenticated: "unauthenticated";
387
389
  }>>;
388
390
  computed: z.ZodCatch<z.ZodBoolean>;
@@ -438,10 +440,10 @@ export declare const RoiTrendSeriesSchema: z.ZodObject<{
438
440
  /** `GET /api/diagnostics/roi/trend` → {@link import("../contracts.js").RoiTrendView}. */
439
441
  export declare const RoiTrendViewSchema: z.ZodObject<{
440
442
  status: z.ZodCatch<z.ZodEnum<{
443
+ absent: "absent";
441
444
  ok: "ok";
442
445
  unreachable: "unreachable";
443
446
  partial: "partial";
444
- absent: "absent";
445
447
  unauthenticated: "unauthenticated";
446
448
  }>>;
447
449
  series: z.ZodCatch<z.ZodArray<z.ZodObject<{
@@ -1099,6 +1101,70 @@ export interface HiveGraphStatusResultWire extends HiveGraphStatusWire {
1099
1101
  export interface HiveGraphSearchResultWire extends HiveGraphSearchWire {
1100
1102
  readonly unreachable: boolean;
1101
1103
  }
1104
+ /** Per-project effective brooding state returned by nectar's `GET /api/hive-graph/projects`. */
1105
+ export declare const NectarProjectBroodingSchema: z.ZodEnum<{
1106
+ active: "active";
1107
+ paused: "paused";
1108
+ "global-paused": "global-paused";
1109
+ }>;
1110
+ export declare const NectarProjectCountsSchema: z.ZodCatch<z.ZodObject<{
1111
+ described: z.ZodCatch<z.ZodNumber>;
1112
+ pending: z.ZodCatch<z.ZodNumber>;
1113
+ }, z.core.$strip>>;
1114
+ /** One active nectar project row (019b `GET /projects`). */
1115
+ export declare const NectarProjectRowSchema: z.ZodObject<{
1116
+ projectId: z.ZodCatch<z.ZodString>;
1117
+ name: z.ZodCatch<z.ZodString>;
1118
+ path: z.ZodCatch<z.ZodString>;
1119
+ brooding: z.ZodCatch<z.ZodEnum<{
1120
+ active: "active";
1121
+ paused: "paused";
1122
+ "global-paused": "global-paused";
1123
+ }>>;
1124
+ watcher: z.ZodCatch<z.ZodString>;
1125
+ counts: z.ZodCatch<z.ZodObject<{
1126
+ described: z.ZodCatch<z.ZodNumber>;
1127
+ pending: z.ZodCatch<z.ZodNumber>;
1128
+ }, z.core.$strip>>;
1129
+ }, z.core.$strip>;
1130
+ export type NectarProjectRowWire = z.infer<typeof NectarProjectRowSchema>;
1131
+ export declare const NectarProjectsBodySchema: z.ZodObject<{
1132
+ globalBrooding: z.ZodCatch<z.ZodEnum<{
1133
+ paused: "paused";
1134
+ on: "on";
1135
+ }>>;
1136
+ projects: z.ZodCatch<z.ZodArray<z.ZodObject<{
1137
+ projectId: z.ZodCatch<z.ZodString>;
1138
+ name: z.ZodCatch<z.ZodString>;
1139
+ path: z.ZodCatch<z.ZodString>;
1140
+ brooding: z.ZodCatch<z.ZodEnum<{
1141
+ active: "active";
1142
+ paused: "paused";
1143
+ "global-paused": "global-paused";
1144
+ }>>;
1145
+ watcher: z.ZodCatch<z.ZodString>;
1146
+ counts: z.ZodCatch<z.ZodObject<{
1147
+ described: z.ZodCatch<z.ZodNumber>;
1148
+ pending: z.ZodCatch<z.ZodNumber>;
1149
+ }, z.core.$strip>>;
1150
+ }, z.core.$strip>>>;
1151
+ }, z.core.$strip>;
1152
+ export type NectarProjectsBodyWire = z.infer<typeof NectarProjectsBodySchema>;
1153
+ /** The nectar projects read-model the Hive Graph page polls (fail-soft `unreachable` flag). */
1154
+ export interface NectarProjectsWire extends NectarProjectsBodyWire {
1155
+ readonly unreachable: boolean;
1156
+ }
1157
+ export declare const EMPTY_NECTAR_PROJECTS: NectarProjectsWire;
1158
+ export declare const UNREACHABLE_NECTAR_PROJECTS: NectarProjectsWire;
1159
+ /** Body for `POST /api/hive-graph/projects/brooding` (per-project or global). */
1160
+ export type SetNectarBroodingBody = {
1161
+ readonly projectId: string;
1162
+ readonly brooding: "on" | "off";
1163
+ } | {
1164
+ readonly global: "on" | "paused";
1165
+ };
1166
+ /** The brooding toggle ack mirrors the persisted projects read-model (019b). */
1167
+ export type NectarBroodingAckWire = NectarProjectsWire;
1102
1168
  /**
1103
1169
  * The generous client-side timeout (ms) for `buildGraph()`. The build parses the WHOLE repo with
1104
1170
  * tree-sitter and can take many seconds to tens of seconds; a short default fetch timeout would abort
@@ -1274,8 +1340,8 @@ export declare const AuthStatusSchema: z.ZodObject<{
1274
1340
  agentId: z.ZodCatch<z.ZodString>;
1275
1341
  source: z.ZodCatch<z.ZodEnum<{
1276
1342
  file: "file";
1277
- none: "none";
1278
1343
  env: "env";
1344
+ none: "none";
1279
1345
  }>>;
1280
1346
  savedAt: z.ZodCatch<z.ZodString>;
1281
1347
  expiresAt: z.ZodOptional<z.ZodNumber>;
@@ -1311,17 +1377,17 @@ export declare const SetupStateSchema: z.ZodObject<{
1311
1377
  hivemind: z.ZodCatch<z.ZodBoolean>;
1312
1378
  }, z.core.$strip>>;
1313
1379
  phase: z.ZodCatch<z.ZodEnum<{
1380
+ migrated: "migrated";
1314
1381
  linking: "linking";
1315
1382
  installed: "installed";
1316
1383
  fresh: "fresh";
1317
1384
  linked: "linked";
1318
1385
  migrating: "migrating";
1319
- migrated: "migrated";
1320
1386
  }>>;
1321
1387
  priorTool: z.ZodCatch<z.ZodObject<{
1322
1388
  hivemind: z.ZodCatch<z.ZodEnum<{
1323
- absent: "absent";
1324
1389
  migrated: "migrated";
1390
+ absent: "absent";
1325
1391
  present: "present";
1326
1392
  }>>;
1327
1393
  }, z.core.$strip>>;
@@ -1800,6 +1866,17 @@ export interface WireClient {
1800
1866
  * 409 already_running, and success honestly — never throws into React.
1801
1867
  */
1802
1868
  hiveGraphBuild(): Promise<HiveGraphBuildAck>;
1869
+ /**
1870
+ * PRD-019c — read nectar's active-project set with brooding state (`GET /api/hive-graph/projects`).
1871
+ * Degrades to {@link UNREACHABLE_NECTAR_PROJECTS} when nectar is down (never throws).
1872
+ */
1873
+ nectarProjects(): Promise<NectarProjectsWire>;
1874
+ /**
1875
+ * PRD-019c — set per-project or global brooding (`POST /api/hive-graph/projects/brooding`).
1876
+ * Returns the persisted read-model on success; degrades to {@link UNREACHABLE_NECTAR_PROJECTS} on failure.
1877
+ * The caller re-lists after a successful write so the UI reflects nectar's truth, never optimistic-only.
1878
+ */
1879
+ setNectarBrooding(body: SetNectarBroodingBody): Promise<NectarBroodingAckWire>;
1803
1880
  /** PRD-032c — read the vault `setting` class + the provider→model catalog (`GET /api/settings`). */
1804
1881
  vaultSettings(): Promise<VaultSettingsWire>;
1805
1882
  /**
@@ -44,6 +44,9 @@ export const ENDPOINTS = Object.freeze({
44
44
  hiveGraphStatus: "/api/hive-graph/status",
45
45
  hiveGraphProjection: "/api/hive-graph/projection",
46
46
  hiveGraphBuild: "/api/hive-graph/build",
47
+ // PRD-019b/c — nectar active-project set + brooding control (proxied to nectar :3854).
48
+ hiveGraphProjects: "/api/hive-graph/projects",
49
+ hiveGraphBrooding: "/api/hive-graph/projects/brooding",
47
50
  // PRD-041b — the memory-graph view-model (the knowledge graph of memories/entities). Served off
48
51
  // the diagnostics group (`/api/diagnostics/memory-graph`), mirroring `/api/graph`. Returns the SAME
49
52
  // `GraphView` shape so the existing `GraphCanvas` renders it unchanged; `built:false` until PRD-008
@@ -761,6 +764,40 @@ export const FAILED_HIVE_GRAPH_BUILD_ACK = Object.freeze({
761
764
  state: "failed",
762
765
  message: "Build failed",
763
766
  });
767
+ // ─────────────────────────────────────────────────────────────────────────────
768
+ // PRD-019b/c — nectar projects + brooding wire shapes (`GET/POST .../projects*`).
769
+ // ─────────────────────────────────────────────────────────────────────────────
770
+ /** Per-project effective brooding state returned by nectar's `GET /api/hive-graph/projects`. */
771
+ export const NectarProjectBroodingSchema = z.enum(["active", "paused", "global-paused"]);
772
+ export const NectarProjectCountsSchema = z
773
+ .object({
774
+ described: z.number().catch(0),
775
+ pending: z.number().catch(0),
776
+ })
777
+ .catch({ described: 0, pending: 0 });
778
+ /** One active nectar project row (019b `GET /projects`). */
779
+ export const NectarProjectRowSchema = z.object({
780
+ projectId: z.string().catch(""),
781
+ name: z.string().catch(""),
782
+ path: z.string().catch(""),
783
+ brooding: NectarProjectBroodingSchema.catch("active"),
784
+ watcher: z.string().catch(""),
785
+ counts: NectarProjectCountsSchema,
786
+ });
787
+ export const NectarProjectsBodySchema = z.object({
788
+ globalBrooding: z.enum(["on", "paused"]).catch("on"),
789
+ projects: z.array(NectarProjectRowSchema).catch([]),
790
+ });
791
+ export const EMPTY_NECTAR_PROJECTS = Object.freeze({
792
+ globalBrooding: "on",
793
+ projects: [],
794
+ unreachable: false,
795
+ });
796
+ export const UNREACHABLE_NECTAR_PROJECTS = Object.freeze({
797
+ globalBrooding: "on",
798
+ projects: [],
799
+ unreachable: true,
800
+ });
764
801
  /**
765
802
  * The generous client-side timeout (ms) for `buildGraph()`. The build parses the WHOLE repo with
766
803
  * tree-sitter and can take many seconds to tens of seconds; a short default fetch timeout would abort
@@ -1791,6 +1828,40 @@ export function createWireClient(options = {}) {
1791
1828
  clearTimeout(timer);
1792
1829
  }
1793
1830
  },
1831
+ async nectarProjects() {
1832
+ try {
1833
+ const res = await fetchImpl(url(ENDPOINTS.hiveGraphProjects), {
1834
+ headers: { accept: "application/json", ...DASHBOARD_SESSION_HEADERS },
1835
+ });
1836
+ if (!res.ok)
1837
+ return UNREACHABLE_NECTAR_PROJECTS;
1838
+ const parsed = NectarProjectsBodySchema.safeParse(await res.json());
1839
+ if (!parsed.success)
1840
+ return UNREACHABLE_NECTAR_PROJECTS;
1841
+ return { ...parsed.data, unreachable: false };
1842
+ }
1843
+ catch {
1844
+ return UNREACHABLE_NECTAR_PROJECTS;
1845
+ }
1846
+ },
1847
+ async setNectarBrooding(body) {
1848
+ try {
1849
+ const res = await fetchImpl(url(ENDPOINTS.hiveGraphBrooding), {
1850
+ method: "POST",
1851
+ headers: { "content-type": "application/json", accept: "application/json", ...DASHBOARD_SESSION_HEADERS },
1852
+ body: JSON.stringify(body),
1853
+ });
1854
+ if (!res.ok)
1855
+ return UNREACHABLE_NECTAR_PROJECTS;
1856
+ const parsed = NectarProjectsBodySchema.safeParse(await res.json());
1857
+ if (!parsed.success)
1858
+ return UNREACHABLE_NECTAR_PROJECTS;
1859
+ return { ...parsed.data, unreachable: false };
1860
+ }
1861
+ catch {
1862
+ return UNREACHABLE_NECTAR_PROJECTS;
1863
+ }
1864
+ },
1794
1865
  async vaultSettings() {
1795
1866
  // GET the `setting` class + catalog; a malformed/absent body degrades to the empty
1796
1867
  // view (nothing selected, no catalog) so the panel renders its empty state, never throws.