@korso/shepherd-ui 0.1.1 → 0.2.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 (100) hide show
  1. package/README.md +47 -47
  2. package/dist/ShepherdProvider.d.ts +12 -0
  3. package/dist/ShepherdProvider.js +33 -0
  4. package/dist/ShepherdProvider.test.d.ts +1 -0
  5. package/dist/ShepherdProvider.test.js +47 -0
  6. package/dist/ShepherdRoot.d.ts +9 -0
  7. package/dist/ShepherdRoot.js +88 -0
  8. package/dist/ShepherdRoot.routing.test.d.ts +1 -0
  9. package/dist/ShepherdRoot.routing.test.js +61 -0
  10. package/dist/ShepherdRoot.test.d.ts +1 -0
  11. package/dist/ShepherdRoot.test.js +37 -0
  12. package/dist/app/assets/index-CDOCIg6s.js +11 -0
  13. package/dist/app/index.html +12 -0
  14. package/dist/client.d.ts +107 -0
  15. package/dist/client.js +238 -0
  16. package/dist/client.test.d.ts +1 -0
  17. package/dist/client.test.js +298 -0
  18. package/dist/components/ActiveList.d.ts +22 -0
  19. package/dist/components/ActiveList.js +59 -0
  20. package/dist/components/Chat.d.ts +30 -0
  21. package/dist/components/Chat.js +61 -0
  22. package/dist/components/Composer.d.ts +37 -0
  23. package/dist/components/Composer.js +146 -0
  24. package/dist/components/Crew.d.ts +23 -0
  25. package/dist/components/Crew.js +31 -0
  26. package/dist/components/Dashboard.d.ts +34 -0
  27. package/dist/components/Dashboard.js +209 -0
  28. package/dist/components/DoneList.d.ts +29 -0
  29. package/dist/components/DoneList.js +50 -0
  30. package/dist/components/RepoSelect.d.ts +38 -0
  31. package/dist/components/RepoSelect.js +56 -0
  32. package/dist/components/Territory.d.ts +21 -0
  33. package/dist/components/Territory.js +21 -0
  34. package/dist/config/ConnectAgent.d.ts +10 -0
  35. package/dist/config/ConnectAgent.js +119 -0
  36. package/dist/config/ConnectAgent.test.d.ts +1 -0
  37. package/dist/config/ConnectAgent.test.js +92 -0
  38. package/dist/config/EmptyState.d.ts +12 -0
  39. package/dist/config/EmptyState.js +4 -0
  40. package/dist/config/EmptyState.test.d.ts +1 -0
  41. package/dist/config/EmptyState.test.js +32 -0
  42. package/dist/config/Members.d.ts +10 -0
  43. package/dist/config/Members.js +83 -0
  44. package/dist/config/Members.test.d.ts +1 -0
  45. package/dist/config/Members.test.js +66 -0
  46. package/dist/config/Workspaces.d.ts +12 -0
  47. package/dist/config/Workspaces.js +96 -0
  48. package/dist/config/Workspaces.test.d.ts +1 -0
  49. package/dist/config/Workspaces.test.js +90 -0
  50. package/dist/config/index.d.ts +8 -0
  51. package/dist/config/index.js +6 -0
  52. package/dist/context.d.ts +28 -0
  53. package/dist/context.js +36 -0
  54. package/dist/index.cjs +5289 -0
  55. package/dist/index.cjs.map +1 -0
  56. package/dist/index.d.cts +149 -0
  57. package/dist/index.d.ts +18 -0
  58. package/dist/index.js +15 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/lib/Dashboard-CG6KeFQ3.js +1214 -0
  61. package/dist/lib/index.d.ts +438 -16
  62. package/dist/lib/index.js +455 -6
  63. package/dist/lib/selfhost.js +9 -9
  64. package/dist/lib/styles.css +209 -182
  65. package/dist/logic.d.ts +208 -0
  66. package/dist/logic.js +372 -0
  67. package/dist/main.d.ts +1 -0
  68. package/dist/main.js +11 -0
  69. package/dist/selfhost/assets/{index-tSyzirZa.css → index-BZmImfYZ.css} +1 -1
  70. package/dist/selfhost/assets/index-CS268KSw.js +40 -0
  71. package/dist/selfhost/index.html +13 -13
  72. package/dist/selfhost.d.ts +22 -0
  73. package/dist/selfhost.js +97 -0
  74. package/dist/test/mockClient.d.ts +6 -0
  75. package/dist/test/mockClient.js +45 -0
  76. package/dist/test/setup.d.ts +1 -0
  77. package/dist/test/setup.js +2 -0
  78. package/dist/useLandscapePolling.d.ts +63 -0
  79. package/dist/useLandscapePolling.js +129 -0
  80. package/dist/views/Chat.d.ts +5 -0
  81. package/dist/views/Chat.js +60 -0
  82. package/dist/views/Chat.test.d.ts +1 -0
  83. package/dist/views/Chat.test.js +92 -0
  84. package/dist/views/Config.d.ts +12 -0
  85. package/dist/views/Config.js +6 -0
  86. package/dist/views/Tasks.d.ts +5 -0
  87. package/dist/views/Tasks.js +75 -0
  88. package/dist/views/Tasks.test.d.ts +1 -0
  89. package/dist/views/Tasks.test.js +115 -0
  90. package/dist/views/useLandscape.d.ts +14 -0
  91. package/dist/views/useLandscape.js +74 -0
  92. package/dist/views/useLandscape.test.d.ts +1 -0
  93. package/dist/views/useLandscape.test.js +101 -0
  94. package/dist/views/wallboard.d.ts +46 -0
  95. package/dist/views/wallboard.js +209 -0
  96. package/dist/views/wallboard.test.d.ts +1 -0
  97. package/dist/views/wallboard.test.js +143 -0
  98. package/package.json +67 -67
  99. package/dist/lib/Dashboard-CB6SL-J2.js +0 -1064
  100. package/dist/selfhost/assets/index-BBx3vo2Y.js +0 -40
@@ -1,19 +1,75 @@
1
+ import { JSX as JSX_2 } from 'react';
1
2
  import { ReactElement } from 'react';
2
3
  import { ReactNode } from 'react';
3
4
  import { z } from 'zod';
4
5
 
6
+ export declare function ConnectAgent({ workspaceId, hubUrl }: ConnectAgentProps): JSX_2.Element;
7
+
8
+ export declare interface ConnectAgentProps {
9
+ workspaceId: string;
10
+ /**
11
+ * The DIRECT Hub URL the agent connects to (public Cloud Run URL when hosted).
12
+ * Defaults to the dashboard client's baseUrl, which is correct for self-host
13
+ * where the agent and the dashboard share the Hub origin.
14
+ */
15
+ hubUrl?: string;
16
+ }
17
+
18
+ declare const CreateInviteRequest: z.ZodObject<{
19
+ expiresInDays: z.ZodOptional<z.ZodNumber>;
20
+ maxUses: z.ZodOptional<z.ZodNumber>;
21
+ }, "strip", z.ZodTypeAny, {
22
+ expiresInDays?: number | undefined;
23
+ maxUses?: number | undefined;
24
+ }, {
25
+ expiresInDays?: number | undefined;
26
+ maxUses?: number | undefined;
27
+ }>;
28
+
29
+ declare type CreateInviteRequestT = z.infer<typeof CreateInviteRequest>;
30
+
5
31
  /**
6
- * Builds a browser fetch client for the Shepherd hub with exactly two methods.
7
- * Each call wires up an AbortController timeout (cleared in `finally`), merges
8
- * the injected auth headers over a JSON content-type base, and Zod-parses ONLY
9
- * the response at the boundary — the request body is forwarded verbatim because
10
- * the caller owns its input shape.
32
+ * Builds a browser fetch client for the Shepherd hub. Each call wires up an
33
+ * AbortController timeout (cleared in `finally`), merges the injected auth
34
+ * headers over a JSON content-type base, and Zod-parses ONLY the response at
35
+ * the boundary — the request body is forwarded verbatim because the caller owns
36
+ * its input shape. void-returning methods (revoke/remove/leave) await the
37
+ * request and parse nothing.
11
38
  *
12
39
  * @param config - Base URL, optional injected auth, 401 hook, and timeout.
13
40
  * @returns A {@link ShepherdClient}.
14
41
  */
15
42
  export declare function createShepherdClient(config: ShepherdClientConfig): ShepherdClient;
16
43
 
44
+ declare const CreateWorkspaceRequest: z.ZodObject<{
45
+ name: z.ZodString;
46
+ }, "strip", z.ZodTypeAny, {
47
+ name: string;
48
+ }, {
49
+ name: string;
50
+ }>;
51
+
52
+ declare type CreateWorkspaceRequestT = z.infer<typeof CreateWorkspaceRequest>;
53
+
54
+ declare const CreateWorkspaceResponse: z.ZodObject<{
55
+ id: z.ZodString;
56
+ slug: z.ZodString;
57
+ name: z.ZodString;
58
+ role: z.ZodEnum<["admin", "member"]>;
59
+ }, "strip", z.ZodTypeAny, {
60
+ id: string;
61
+ name: string;
62
+ slug: string;
63
+ role: "admin" | "member";
64
+ }, {
65
+ id: string;
66
+ name: string;
67
+ slug: string;
68
+ role: "admin" | "member";
69
+ }>;
70
+
71
+ declare type CreateWorkspaceResponseT = z.infer<typeof CreateWorkspaceResponse>;
72
+
17
73
  /**
18
74
  * The Shepherd wallboard shell. Composes {@link useLandscapePolling} (which reads
19
75
  * the client from context, keeping this auth-agnostic) with the six leaf
@@ -36,16 +92,309 @@ export declare function createShepherdClient(config: ShepherdClientConfig): Shep
36
92
  *
37
93
  * @returns The dashboard element.
38
94
  */
39
- export declare function Dashboard(): ReactElement;
95
+ export declare function Dashboard({ workspaceId }?: DashboardProps): ReactElement;
40
96
 
41
- /** Props for {@link Dashboard}. Currently empty — the client comes from context. */
42
- export declare type DashboardProps = Record<string, never>;
97
+ /** Props for {@link Dashboard}. The client comes from context. */
98
+ export declare interface DashboardProps {
99
+ /**
100
+ * Workspace to scope the board to. When given, the polling hook hits the
101
+ * workspace-scoped `landscape(id)` route and the composer posts via
102
+ * `announceTo(id, …)`; when omitted, both fall back to the self-host singular
103
+ * aliases, so a no-id render is unchanged.
104
+ */
105
+ workspaceId?: string;
106
+ }
43
107
 
44
108
  /**
45
- * The wallboard's two read/write operations against the Shepherd hub. Responses
46
- * are Zod-parsed at the boundary so callers receive contract-typed values.
109
+ * Maps any thrown value into a short, human-friendly message for the view layer.
110
+ * A {@link ShepherdClientError} (and any other `Error`) surfaces its own
111
+ * `message` — which already carries the hub's detail for non-2xx responses and a
112
+ * transport description otherwise — while a non-Error value degrades to a
113
+ * generic line rather than stringifying something unprintable.
114
+ *
115
+ * @param err - The caught value (typically from a client method rejection).
116
+ * @returns A display-ready message string.
117
+ */
118
+ export declare function describeError(err: unknown): string;
119
+
120
+ export declare function EmptyState({ title, children, onGetStarted, ctaLabel, }: EmptyStateProps): JSX_2.Element;
121
+
122
+ export declare interface EmptyStateProps {
123
+ /** Heading text. Defaults to a generic "no workspace yet" prompt. */
124
+ title?: string;
125
+ /** Supporting copy. */
126
+ children?: ReactNode;
127
+ /** Invoked when the user clicks the call-to-action (e.g. switch to Config). */
128
+ onGetStarted?: () => void;
129
+ /** CTA label. */
130
+ ctaLabel?: string;
131
+ }
132
+
133
+ declare const InviteResponse: z.ZodObject<{
134
+ code: z.ZodString;
135
+ expiresAt: z.ZodNullable<z.ZodString>;
136
+ maxUses: z.ZodNumber;
137
+ useCount: z.ZodNumber;
138
+ }, "strip", z.ZodTypeAny, {
139
+ code: string;
140
+ expiresAt: string | null;
141
+ maxUses: number;
142
+ useCount: number;
143
+ }, {
144
+ code: string;
145
+ expiresAt: string | null;
146
+ maxUses: number;
147
+ useCount: number;
148
+ }>;
149
+
150
+ export declare type InviteResponseT = z.infer<typeof InviteResponse>;
151
+
152
+ declare const ListMembersResponse: z.ZodObject<{
153
+ members: z.ZodArray<z.ZodObject<{
154
+ accountId: z.ZodString;
155
+ displayName: z.ZodNullable<z.ZodString>;
156
+ githubLogin: z.ZodNullable<z.ZodString>;
157
+ avatarUrl: z.ZodNullable<z.ZodString>;
158
+ role: z.ZodEnum<["admin", "member"]>;
159
+ }, "strip", z.ZodTypeAny, {
160
+ role: "admin" | "member";
161
+ accountId: string;
162
+ displayName: string | null;
163
+ githubLogin: string | null;
164
+ avatarUrl: string | null;
165
+ }, {
166
+ role: "admin" | "member";
167
+ accountId: string;
168
+ displayName: string | null;
169
+ githubLogin: string | null;
170
+ avatarUrl: string | null;
171
+ }>, "many">;
172
+ }, "strip", z.ZodTypeAny, {
173
+ members: {
174
+ role: "admin" | "member";
175
+ accountId: string;
176
+ displayName: string | null;
177
+ githubLogin: string | null;
178
+ avatarUrl: string | null;
179
+ }[];
180
+ }, {
181
+ members: {
182
+ role: "admin" | "member";
183
+ accountId: string;
184
+ displayName: string | null;
185
+ githubLogin: string | null;
186
+ avatarUrl: string | null;
187
+ }[];
188
+ }>;
189
+
190
+ declare type ListMembersResponseT = z.infer<typeof ListMembersResponse>;
191
+
192
+ declare const ListTokensResponse: z.ZodObject<{
193
+ tokens: z.ZodArray<z.ZodObject<{
194
+ id: z.ZodString;
195
+ name: z.ZodNullable<z.ZodString>;
196
+ lastUsedAt: z.ZodNullable<z.ZodString>;
197
+ createdAt: z.ZodString;
198
+ revokedAt: z.ZodNullable<z.ZodString>;
199
+ }, "strip", z.ZodTypeAny, {
200
+ id: string;
201
+ createdAt: string;
202
+ name: string | null;
203
+ lastUsedAt: string | null;
204
+ revokedAt: string | null;
205
+ }, {
206
+ id: string;
207
+ createdAt: string;
208
+ name: string | null;
209
+ lastUsedAt: string | null;
210
+ revokedAt: string | null;
211
+ }>, "many">;
212
+ }, "strip", z.ZodTypeAny, {
213
+ tokens: {
214
+ id: string;
215
+ createdAt: string;
216
+ name: string | null;
217
+ lastUsedAt: string | null;
218
+ revokedAt: string | null;
219
+ }[];
220
+ }, {
221
+ tokens: {
222
+ id: string;
223
+ createdAt: string;
224
+ name: string | null;
225
+ lastUsedAt: string | null;
226
+ revokedAt: string | null;
227
+ }[];
228
+ }>;
229
+
230
+ declare type ListTokensResponseT = z.infer<typeof ListTokensResponse>;
231
+
232
+ declare const ListWorkspacesResponse: z.ZodObject<{
233
+ workspaces: z.ZodArray<z.ZodObject<{
234
+ id: z.ZodString;
235
+ slug: z.ZodString;
236
+ name: z.ZodString;
237
+ role: z.ZodEnum<["admin", "member"]>;
238
+ }, "strip", z.ZodTypeAny, {
239
+ id: string;
240
+ name: string;
241
+ slug: string;
242
+ role: "admin" | "member";
243
+ }, {
244
+ id: string;
245
+ name: string;
246
+ slug: string;
247
+ role: "admin" | "member";
248
+ }>, "many">;
249
+ }, "strip", z.ZodTypeAny, {
250
+ workspaces: {
251
+ id: string;
252
+ name: string;
253
+ slug: string;
254
+ role: "admin" | "member";
255
+ }[];
256
+ }, {
257
+ workspaces: {
258
+ id: string;
259
+ name: string;
260
+ slug: string;
261
+ role: "admin" | "member";
262
+ }[];
263
+ }>;
264
+
265
+ declare type ListWorkspacesResponseT = z.infer<typeof ListWorkspacesResponse>;
266
+
267
+ export declare function Members({ workspaceId, refreshKey, canRemove, onLeft }: MembersProps): JSX_2.Element;
268
+
269
+ export declare interface MembersProps {
270
+ workspaceId: string;
271
+ /** Bumped by the parent to force a refetch (e.g. after an invite is redeemed). */
272
+ refreshKey?: number;
273
+ /** When true, render the per-member remove control (the caller gates on admin). */
274
+ canRemove?: boolean;
275
+ /** Called after a successful self-service leave, so the shell can refresh. */
276
+ onLeft?: () => void;
277
+ }
278
+
279
+ declare const MemberSummary: z.ZodObject<{
280
+ accountId: z.ZodString;
281
+ displayName: z.ZodNullable<z.ZodString>;
282
+ githubLogin: z.ZodNullable<z.ZodString>;
283
+ avatarUrl: z.ZodNullable<z.ZodString>;
284
+ role: z.ZodEnum<["admin", "member"]>;
285
+ }, "strip", z.ZodTypeAny, {
286
+ role: "admin" | "member";
287
+ accountId: string;
288
+ displayName: string | null;
289
+ githubLogin: string | null;
290
+ avatarUrl: string | null;
291
+ }, {
292
+ role: "admin" | "member";
293
+ accountId: string;
294
+ displayName: string | null;
295
+ githubLogin: string | null;
296
+ avatarUrl: string | null;
297
+ }>;
298
+
299
+ export declare type MemberSummaryT = z.infer<typeof MemberSummary>;
300
+
301
+ declare const MintTokenRequest: z.ZodObject<{
302
+ name: z.ZodOptional<z.ZodString>;
303
+ }, "strip", z.ZodTypeAny, {
304
+ name?: string | undefined;
305
+ }, {
306
+ name?: string | undefined;
307
+ }>;
308
+
309
+ declare type MintTokenRequestT = z.infer<typeof MintTokenRequest>;
310
+
311
+ declare const MintTokenResponse: z.ZodObject<{
312
+ token: z.ZodString;
313
+ id: z.ZodString;
314
+ }, "strip", z.ZodTypeAny, {
315
+ id: string;
316
+ token: string;
317
+ }, {
318
+ id: string;
319
+ token: string;
320
+ }>;
321
+
322
+ declare type MintTokenResponseT = z.infer<typeof MintTokenResponse>;
323
+
324
+ declare const RedeemInviteResponse: z.ZodObject<{
325
+ workspace: z.ZodObject<{
326
+ id: z.ZodString;
327
+ slug: z.ZodString;
328
+ name: z.ZodString;
329
+ role: z.ZodEnum<["admin", "member"]>;
330
+ }, "strip", z.ZodTypeAny, {
331
+ id: string;
332
+ name: string;
333
+ slug: string;
334
+ role: "admin" | "member";
335
+ }, {
336
+ id: string;
337
+ name: string;
338
+ slug: string;
339
+ role: "admin" | "member";
340
+ }>;
341
+ }, "strip", z.ZodTypeAny, {
342
+ workspace: {
343
+ id: string;
344
+ name: string;
345
+ slug: string;
346
+ role: "admin" | "member";
347
+ };
348
+ }, {
349
+ workspace: {
350
+ id: string;
351
+ name: string;
352
+ slug: string;
353
+ role: "admin" | "member";
354
+ };
355
+ }>;
356
+
357
+ declare type RedeemInviteResponseT = z.infer<typeof RedeemInviteResponse>;
358
+
359
+ /**
360
+ * The typed Shepherd hub surface. The plural, workspace-scoped methods use the
361
+ * `/workspaces/:id/...` form (which works in both deployments: a bearer token
362
+ * resolves its own workspace and ignores `:id`, while a browser session
363
+ * validates membership of `:id`). The singular `getLandscape()`/`announce()`
364
+ * pair are the self-host aliases against the implicit single-workspace routes.
365
+ * Every response with a dedicated schema is Zod-parsed at the boundary so a
366
+ * contract drift throws `Invalid response schema` rather than flowing a
367
+ * malformed object into the view layer.
47
368
  */
48
369
  export declare interface ShepherdClient {
370
+ /** The normalised (trailing-slash-stripped) hub base URL the client targets. */
371
+ readonly baseUrl: string;
372
+ /** GET the caller's workspaces, each tagged with the caller's role. */
373
+ listWorkspaces(): Promise<ListWorkspacesResponseT>;
374
+ /** POST a new workspace; the caller becomes its admin. */
375
+ createWorkspace(body: CreateWorkspaceRequestT): Promise<CreateWorkspaceResponseT>;
376
+ /** POST a new agent token; the raw `shp_` value is returned exactly once. */
377
+ mintToken(workspaceId: string, body: MintTokenRequestT): Promise<MintTokenResponseT>;
378
+ /** GET the workspace's token metadata (never the raw token). */
379
+ listTokens(workspaceId: string): Promise<ListTokensResponseT>;
380
+ /** DELETE (revoke) a token by id. */
381
+ revokeToken(workspaceId: string, tokenId: string): Promise<void>;
382
+ /** POST a new invite code for the workspace (admin only). */
383
+ createInvite(workspaceId: string, body: CreateInviteRequestT): Promise<InviteResponseT>;
384
+ /** POST to revoke an invite code (admin only). */
385
+ revokeInvite(workspaceId: string, code: string): Promise<void>;
386
+ /** POST to redeem an invite code, joining its workspace as a member. */
387
+ redeemInvite(code: string): Promise<RedeemInviteResponseT>;
388
+ /** GET the workspace's member roster. */
389
+ listMembers(workspaceId: string): Promise<ListMembersResponseT>;
390
+ /** DELETE (remove) a member by account id (admin only). */
391
+ removeMember(workspaceId: string, accountId: string): Promise<void>;
392
+ /** POST to leave the workspace. */
393
+ leave(workspaceId: string): Promise<void>;
394
+ /** GET a specific workspace's landscape (agents, tasks, announcements). */
395
+ landscape(workspaceId: string): Promise<WorkspaceLandscapeResponseT>;
396
+ /** POST an operator announcement to a specific workspace. */
397
+ announceTo(workspaceId: string, body: WorkspaceAnnounceRequestT): Promise<WorkspaceAnnounceResponseT>;
49
398
  /** GET the unfiltered whole-workspace view (agents, tasks, announcements). */
50
399
  getLandscape(): Promise<WorkspaceLandscapeResponseT>;
51
400
  /** POST an operator announcement (broadcast or @targeted) to the workspace. */
@@ -54,15 +403,22 @@ export declare interface ShepherdClient {
54
403
 
55
404
  /**
56
405
  * Construction options for {@link createShepherdClient}. Auth is supplied
57
- * externally via `getAuthHeaders` so the core client stays auth-agnostic — it
58
- * never reads tokens, localStorage, or a BFF; it only merges whatever headers
59
- * the host injects and notifies the host on a 401 via `onUnauthorized`.
406
+ * externally via `getAuthHeader` so the core client stays auth-agnostic — it
407
+ * never reads tokens, localStorage, or a BFF; it only merges whatever the host
408
+ * injects and notifies the host on a 401 via `onUnauthorized`.
60
409
  */
61
410
  export declare interface ShepherdClientConfig {
62
- /** Hub origin; a trailing slash is tolerated and normalised away. */
411
+ /** Hub origin; a trailing slash is tolerated and normalised away. "" = same-origin. */
63
412
  baseUrl: string;
64
- /** Returns auth headers to merge over the JSON content-type base, per call. */
65
- getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
413
+ /**
414
+ * Returns the credential for the next request, as either:
415
+ * - a string → sent as the `Authorization` header value (e.g. "Bearer …"),
416
+ * - a header map → merged verbatim over the JSON content-type base, or
417
+ * - undefined → no auth header added (same-origin BFF supplies the cookie).
418
+ * May be sync or async (e.g. refreshing a short-lived token). Omit entirely
419
+ * for an unauthenticated/same-origin deployment.
420
+ */
421
+ getAuthHeader?: () => string | Record<string, string> | undefined | Promise<string | Record<string, string> | undefined>;
66
422
  /** Invoked once when the hub responds 401, before the error is thrown. */
67
423
  onUnauthorized?: () => void;
68
424
  /** Per-request abort timeout in ms; defaults to {@link DEFAULT_TIMEOUT_MS}. */
@@ -105,6 +461,39 @@ declare interface ShepherdClientProviderProps {
105
461
  children: ReactNode;
106
462
  }
107
463
 
464
+ export declare function ShepherdRoot({ hubUrl }: ShepherdRootProps): JSX_2.Element;
465
+
466
+ export declare interface ShepherdRootProps {
467
+ /**
468
+ * The DIRECT Hub URL embedded in the agent install command (planning decision
469
+ * #2: the headless agent connects straight to the Hub, not the BFF). Defaults
470
+ * to the client's baseUrl, which is correct for self-host.
471
+ */
472
+ hubUrl?: string;
473
+ }
474
+
475
+ declare const TokenSummary: z.ZodObject<{
476
+ id: z.ZodString;
477
+ name: z.ZodNullable<z.ZodString>;
478
+ lastUsedAt: z.ZodNullable<z.ZodString>;
479
+ createdAt: z.ZodString;
480
+ revokedAt: z.ZodNullable<z.ZodString>;
481
+ }, "strip", z.ZodTypeAny, {
482
+ id: string;
483
+ createdAt: string;
484
+ name: string | null;
485
+ lastUsedAt: string | null;
486
+ revokedAt: string | null;
487
+ }, {
488
+ id: string;
489
+ createdAt: string;
490
+ name: string | null;
491
+ lastUsedAt: string | null;
492
+ revokedAt: string | null;
493
+ }>;
494
+
495
+ export declare type TokenSummaryT = z.infer<typeof TokenSummary>;
496
+
108
497
  /**
109
498
  * Reads the {@link ShepherdClient} from context. Throws when called outside a
110
499
  * {@link ShepherdClientProvider} so a missing provider surfaces as an immediate,
@@ -303,4 +692,37 @@ declare const WorkspaceLandscapeResponse: z.ZodObject<{
303
692
 
304
693
  export declare type WorkspaceLandscapeResponseT = z.infer<typeof WorkspaceLandscapeResponse>;
305
694
 
695
+ export declare function Workspaces({ workspaces, selected, onChanged, onSelect }: WorkspacesProps): JSX_2.Element;
696
+
697
+ export declare interface WorkspacesProps {
698
+ /** All workspaces the account belongs to (for the switcher / context). */
699
+ workspaces: WorkspaceSummaryT[];
700
+ /** The currently-selected workspace, or null when the account has none. */
701
+ selected: WorkspaceSummaryT | null;
702
+ /** Called after a mutation that changes membership (create / join / leave). */
703
+ onChanged: () => void;
704
+ /** Switch the active workspace (optional simple switcher). */
705
+ onSelect?: (workspaceId: string) => void;
706
+ }
707
+
708
+ /** One workspace as seen by an account, with that account's role in it. */
709
+ declare const WorkspaceSummary: z.ZodObject<{
710
+ id: z.ZodString;
711
+ slug: z.ZodString;
712
+ name: z.ZodString;
713
+ role: z.ZodEnum<["admin", "member"]>;
714
+ }, "strip", z.ZodTypeAny, {
715
+ id: string;
716
+ name: string;
717
+ slug: string;
718
+ role: "admin" | "member";
719
+ }, {
720
+ id: string;
721
+ name: string;
722
+ slug: string;
723
+ role: "admin" | "member";
724
+ }>;
725
+
726
+ export declare type WorkspaceSummaryT = z.infer<typeof WorkspaceSummary>;
727
+
306
728
  export { }