@korso/shepherd-ui 0.10.0 → 0.11.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.
@@ -1,10 +1,10 @@
1
- var Me = Object.defineProperty;
2
- var Le = (t, n, c) => n in t ? Me(t, n, { enumerable: !0, configurable: !0, writable: !0, value: c }) : t[n] = c;
3
- var ue = (t, n, c) => Le(t, typeof n != "symbol" ? n + "" : n, c);
4
- import { jsx as r, jsxs as m, Fragment as H } from "react/jsx-runtime";
5
- import { createContext as Pe, useContext as Oe, useState as N, useRef as P, useCallback as R, useEffect as se, Fragment as Ge, useLayoutEffect as Fe, useId as Se } from "react";
1
+ var Pe = Object.defineProperty;
2
+ var Oe = (t, n, i) => n in t ? Pe(t, n, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[n] = i;
3
+ var he = (t, n, i) => Oe(t, typeof n != "symbol" ? n + "" : n, i);
4
+ import { jsx as r, jsxs as m, Fragment as q } from "react/jsx-runtime";
5
+ import { createContext as We, useContext as Ge, useState as _, useRef as P, useCallback as j, useEffect as ae, Fragment as Fe, useLayoutEffect as Ue, useId as Ce } from "react";
6
6
  import { z as e } from "zod";
7
- const E = e.string(), Y = e.number(), We = e.object({
7
+ const C = e.string(), Y = e.number(), He = e.object({
8
8
  agentName: e.string(),
9
9
  human: e.string(),
10
10
  branch: e.string(),
@@ -13,9 +13,9 @@ const E = e.string(), Y = e.number(), We = e.object({
13
13
  message: e.string().nullable(),
14
14
  paths: e.array(e.string()).min(1),
15
15
  authorIsLive: e.boolean(),
16
- authorLastActiveAt: E,
17
- updatedAt: E
18
- }), Ue = e.object({
16
+ authorLastActiveAt: C,
17
+ updatedAt: C
18
+ }), qe = e.object({
19
19
  kind: e.enum(["committed", "uncommitted"]),
20
20
  // A git object id (lowercase hex, 4–64 chars) for `committed` entries, or null
21
21
  // for `uncommitted`. This value is forwarded by the hub to OTHER clients, which
@@ -27,7 +27,7 @@ const E = e.string(), Y = e.number(), We = e.object({
27
27
  sha: e.string().regex(/^[0-9a-f]{4,64}$/).nullable(),
28
28
  message: e.string().nullable(),
29
29
  paths: e.array(e.string()).min(1).max(500)
30
- }), ae = e.object({
30
+ }), re = e.object({
31
31
  branch: e.string(),
32
32
  baseBranch: e.string(),
33
33
  head: e.string(),
@@ -36,15 +36,15 @@ const E = e.string(), Y = e.number(), We = e.object({
36
36
  // (100) committed entries + 1 uncommitted, so this ceiling is generous. If
37
37
  // MAX_COMMITS is ever raised above ~599, raise this in lockstep or the hub
38
38
  // will start 400-rejecting otherwise-valid reports.
39
- entries: e.array(Ue).max(600)
40
- }), Z = e.object({
39
+ entries: e.array(qe).max(600)
40
+ }), J = e.object({
41
41
  workItemId: e.string().uuid(),
42
42
  agentName: e.string(),
43
43
  human: e.string().min(1),
44
44
  intent: e.string().min(1).max(2048),
45
45
  pathGlobs: e.array(e.string().min(1).max(512)).min(1).max(64),
46
46
  // ISO timestamp string; see IsoTimestamp note above
47
- expiresAt: E
47
+ expiresAt: C
48
48
  }), V = e.object({
49
49
  // bigint PK serialised as number; see DbId note above
50
50
  id: Y,
@@ -53,19 +53,19 @@ const E = e.string(), Y = e.number(), We = e.object({
53
53
  body: e.string().min(1).max(8192),
54
54
  targetAgentName: e.string().nullable(),
55
55
  // ISO timestamp string; see IsoTimestamp note above
56
- createdAt: E
57
- }), Te = e.object({
58
- conflicts: e.array(Z),
59
- activeClaims: e.array(Z),
56
+ createdAt: C
57
+ }), $e = e.object({
58
+ conflicts: e.array(J),
59
+ activeClaims: e.array(J),
60
60
  // The caller's OWN active claims. `activeClaims` deliberately excludes the
61
61
  // caller's session, so without this an agent has no way to confirm its own
62
62
  // claim is live. Optional with a default so an older client talking to a
63
63
  // newer hub (or vice-versa) never fails validation on its absence.
64
- yourClaims: e.array(Z).default([]),
64
+ yourClaims: e.array(J).default([]),
65
65
  announcements: e.array(V),
66
66
  // Per-agent change records for the workspace. Defaulted for version-skew safety.
67
- changeRecords: e.array(We).default([])
68
- }), He = e.object({
67
+ changeRecords: e.array(He).default([])
68
+ }), Be = e.object({
69
69
  name: e.string(),
70
70
  human: e.string(),
71
71
  program: e.string(),
@@ -75,19 +75,19 @@ const E = e.string(), Y = e.number(), We = e.object({
75
75
  // are null when the agent has no session yet.
76
76
  repo: e.string().nullable(),
77
77
  branch: e.string().nullable(),
78
- lastHeartbeatAt: E.nullable(),
78
+ lastHeartbeatAt: C.nullable(),
79
79
  presence: e.enum(["live", "offline"])
80
- }), qe = e.enum(["active", "done", "dropped"]), Be = e.object({
80
+ }), Ke = e.enum(["active", "done", "dropped"]), ze = e.object({
81
81
  agentName: e.string(),
82
82
  program: e.string(),
83
83
  model: e.string().nullable(),
84
84
  repo: e.string(),
85
85
  intent: e.string(),
86
86
  pathGlobs: e.array(e.string()),
87
- status: qe,
88
- createdAt: E,
89
- endedAt: E.nullable()
90
- }), Ke = e.object({
87
+ status: Ke,
88
+ createdAt: C,
89
+ endedAt: C.nullable()
90
+ }), Ye = e.object({
91
91
  fromAgentName: e.string(),
92
92
  fromHuman: e.string(),
93
93
  body: e.string(),
@@ -107,14 +107,14 @@ const E = e.string(), Y = e.number(), We = e.object({
107
107
  // the collective "→ admin". Null for legacy/collective operator messages and
108
108
  // everything else. Defaulted for version-skew safety with older hubs.
109
109
  targetMemberName: e.string().nullable().default(null),
110
- createdAt: E
111
- }), me = e.object({
112
- agents: e.array(He),
113
- tasks: e.array(Be),
114
- announcements: e.array(Ke),
110
+ createdAt: C
111
+ }), pe = e.object({
112
+ agents: e.array(Be),
113
+ tasks: e.array(ze),
114
+ announcements: e.array(Ye),
115
115
  // The server's clock, so the client computes "expires in / last seen" against
116
116
  // the hub rather than the (possibly skewed) browser clock.
117
- serverTime: E
117
+ serverTime: C
118
118
  });
119
119
  e.object({
120
120
  body: e.string().min(1).max(8192),
@@ -126,7 +126,7 @@ e.object({
126
126
  // Ignored for a DM (the target's own repo is used).
127
127
  repo: e.string().min(1).nullable().optional()
128
128
  });
129
- const he = e.object({
129
+ const ge = e.object({
130
130
  ok: e.literal(!0),
131
131
  // One id per inserted row: a single id for a DM or repo-scoped broadcast, or
132
132
  // several when an all-repos broadcast fans out across repos.
@@ -144,18 +144,18 @@ e.object({
144
144
  agentName: e.string(),
145
145
  sessionId: e.string().uuid()
146
146
  });
147
- const ze = e.object({
147
+ const Ve = e.object({
148
148
  sessionId: e.string().uuid(),
149
149
  intent: e.string().min(1).max(2048),
150
150
  pathGlobs: e.array(e.string().min(1).max(512)).min(1).max(64),
151
151
  ttlSeconds: e.number().int().positive().optional(),
152
- changeReport: ae.optional()
152
+ changeReport: re.optional()
153
153
  });
154
154
  e.object({
155
155
  workItemId: e.string().uuid(),
156
- landscape: Te
156
+ landscape: $e
157
157
  });
158
- const Ye = e.object({
158
+ const Xe = e.object({
159
159
  sessionId: e.string().uuid(),
160
160
  workItemId: e.string().uuid()
161
161
  });
@@ -166,7 +166,7 @@ e.object({
166
166
  // their next work/sync). Defaulted for version-skew safety with older hubs.
167
167
  announcements: e.array(V).default([])
168
168
  });
169
- const Ve = e.object({
169
+ const Ze = e.object({
170
170
  sessionId: e.string().uuid(),
171
171
  body: e.string().min(1).max(8192),
172
172
  // THE preferred addressing field: one name that reaches either kind of
@@ -196,14 +196,14 @@ e.object({
196
196
  });
197
197
  e.object({
198
198
  sessionId: e.string().uuid(),
199
- changeReport: ae.optional()
199
+ changeReport: re.optional()
200
200
  });
201
201
  e.object({
202
- landscape: Te
202
+ landscape: $e
203
203
  });
204
- ze.omit({ sessionId: !0, changeReport: !0 });
205
- Ve.omit({ sessionId: !0 });
206
- Ye.omit({ sessionId: !0 });
204
+ Ve.omit({ sessionId: !0, changeReport: !0 });
205
+ Ze.omit({ sessionId: !0 });
206
+ Xe.omit({ sessionId: !0 });
207
207
  e.object({});
208
208
  e.object({});
209
209
  e.object({
@@ -212,7 +212,7 @@ e.object({
212
212
  // change records fresh (commits surface within ~one heartbeat interval, not
213
213
  // only when it next calls work/sync). Processed presence-style: it refreshes
214
214
  // change records but, like the rest of heartbeat, does NOT renew claim TTLs.
215
- changeReport: ae.optional(),
215
+ changeReport: re.optional(),
216
216
  // Opt-in: when set, the heartbeat returns any pending announcements for the
217
217
  // caller in the response. Delivery is now TWO-PHASE and crash-safe: this fetch
218
218
  // phase does NOT mark them delivered — the client persists them to its
@@ -243,36 +243,36 @@ e.object({
243
243
  e.object({
244
244
  ok: e.literal(!0)
245
245
  });
246
- const Ce = e.enum(["admin", "member"]), re = e.object({
246
+ const Ee = e.enum(["admin", "member"]), oe = e.object({
247
247
  id: e.string(),
248
248
  slug: e.string(),
249
249
  name: e.string(),
250
- role: Ce
250
+ role: Ee
251
251
  });
252
252
  e.object({
253
253
  name: e.string().min(1)
254
254
  });
255
- const Xe = re, Ze = e.object({
256
- workspaces: e.array(re)
257
- }), Je = e.object({
255
+ const Je = oe, Qe = e.object({
256
+ workspaces: e.array(oe)
257
+ }), et = e.object({
258
258
  deleted: e.literal(!0)
259
259
  });
260
260
  e.object({
261
261
  name: e.string().min(1).optional()
262
262
  });
263
- const pe = e.object({
263
+ const be = e.object({
264
264
  // The raw shp_ token, shown once at creation and never returned again.
265
265
  token: e.string(),
266
266
  id: e.string()
267
- }), Qe = e.object({
267
+ }), tt = e.object({
268
268
  id: e.string(),
269
269
  name: e.string().nullable(),
270
270
  // ISO timestamp string (see IsoTimestamp note above) or null when unused / not revoked.
271
- lastUsedAt: E.nullable(),
272
- createdAt: E,
273
- revokedAt: E.nullable()
274
- }), ge = e.object({
275
- tokens: e.array(Qe)
271
+ lastUsedAt: C.nullable(),
272
+ createdAt: C,
273
+ revokedAt: C.nullable()
274
+ }), fe = e.object({
275
+ tokens: e.array(tt)
276
276
  });
277
277
  e.object({
278
278
  expiresInDays: e.number().int().positive().optional(),
@@ -280,10 +280,10 @@ e.object({
280
280
  // integer to cap it instead.
281
281
  maxUses: e.number().int().positive().optional()
282
282
  });
283
- const et = e.object({
283
+ const nt = e.object({
284
284
  code: e.string(),
285
285
  // ISO timestamp string, or null when the invite never expires.
286
- expiresAt: E.nullable(),
286
+ expiresAt: C.nullable(),
287
287
  // null = unlimited (redeemable until revoked).
288
288
  maxUses: e.number().int().positive().nullable(),
289
289
  useCount: e.number().int().nonnegative()
@@ -291,47 +291,88 @@ const et = e.object({
291
291
  e.object({
292
292
  email: e.string().email()
293
293
  });
294
- const tt = e.object({
294
+ const st = e.object({
295
295
  email: e.string(),
296
- sentAt: E
297
- }), nt = e.object({
296
+ sentAt: C
297
+ }), at = e.object({
298
298
  // The workspace the caller just joined.
299
- workspace: re
300
- }), st = e.object({
299
+ workspace: oe
300
+ }), rt = e.object({
301
301
  accountId: e.string(),
302
302
  displayName: e.string().nullable(),
303
303
  githubLogin: e.string().nullable(),
304
304
  email: e.string().nullable(),
305
305
  avatarUrl: e.string().nullable(),
306
- role: Ce
307
- }), at = e.object({
308
- members: e.array(st)
309
- }), rt = e.enum(["bug", "suggestion", "other"]);
306
+ role: Ee
307
+ }), ot = e.object({
308
+ members: e.array(rt)
309
+ }), ct = e.enum(["bug", "suggestion", "other"]);
310
310
  e.object({
311
- type: rt,
311
+ type: ct,
312
312
  body: e.string().trim().min(1).max(4e3)
313
313
  });
314
- const ot = e.object({
314
+ const it = e.object({
315
315
  ok: e.literal(!0),
316
316
  // uuid PK (the feedback table, like workspaces, uses gen_random_uuid()).
317
317
  id: e.string()
318
- }), it = 5e3;
319
- class U extends Error {
318
+ }), B = e.object({
319
+ // `YYYY-MM-DD` (UTC day).
320
+ date: e.string(),
321
+ count: e.number()
322
+ }), lt = e.object({
323
+ name: e.string(),
324
+ slug: e.string(),
325
+ members: e.number(),
326
+ agents: e.number(),
327
+ liveSessions: e.number()
328
+ });
329
+ e.object({
330
+ generatedAt: C,
331
+ totals: e.object({
332
+ accounts: e.number(),
333
+ workspaces: e.number(),
334
+ memberships: e.number(),
335
+ agents: e.number(),
336
+ liveSessions: e.number(),
337
+ activeTokens: e.number(),
338
+ revokedTokens: e.number(),
339
+ activeInvites: e.number(),
340
+ feedback: e.number(),
341
+ changeRecords: e.number(),
342
+ activeWorkItems: e.number()
343
+ }),
344
+ engagement: e.object({
345
+ activeWorkspaces7d: e.number(),
346
+ activeWorkspaces30d: e.number(),
347
+ avgMembersPerWorkspace: e.number(),
348
+ largestWorkspace: e.number()
349
+ }),
350
+ feedbackByType: e.array(e.object({ type: e.string(), count: e.number() })),
351
+ trends: e.object({
352
+ newAccounts: e.array(B),
353
+ newWorkspaces: e.array(B),
354
+ newSessions: e.array(B),
355
+ commits: e.array(B)
356
+ }),
357
+ topWorkspaces: e.array(lt)
358
+ });
359
+ const dt = 5e3;
360
+ class H extends Error {
320
361
  /**
321
362
  * @param message - Human-readable failure description.
322
363
  * @param status - Upstream HTTP status, omitted for network/abort failures.
323
364
  */
324
- constructor(c, o) {
325
- super(c);
365
+ constructor(i, o) {
366
+ super(i);
326
367
  /** Upstream HTTP status for a non-2xx response; absent for transport errors. */
327
- ue(this, "status");
368
+ he(this, "status");
328
369
  this.name = "ShepherdClientError", o !== void 0 && (this.status = o);
329
370
  }
330
371
  }
331
- function ct(t) {
372
+ function ut(t) {
332
373
  return t instanceof Error ? t.message : "Something went wrong.";
333
374
  }
334
- async function lt(t) {
375
+ async function mt(t) {
335
376
  try {
336
377
  const n = await t.json();
337
378
  if (n !== null && typeof n == "object" && "error" in n && typeof n.error == "string")
@@ -340,227 +381,227 @@ async function lt(t) {
340
381
  }
341
382
  return "";
342
383
  }
343
- function qt(t) {
344
- const n = t.baseUrl.replace(/\/$/, ""), c = t.timeoutMs ?? it, o = encodeURIComponent;
345
- async function s(a, i, l = {}) {
384
+ function zt(t) {
385
+ const n = t.baseUrl.replace(/\/$/, ""), i = t.timeoutMs ?? dt, o = encodeURIComponent;
386
+ async function a(s, l, c = {}) {
346
387
  var f, k;
347
- const h = new AbortController(), u = setTimeout(() => h.abort(), c);
388
+ const h = new AbortController(), u = setTimeout(() => h.abort(), i);
348
389
  let d;
349
390
  try {
350
- const v = l.body !== void 0 ? { "Content-Type": "application/json" } : {}, A = await ((f = t.getAuthHeader) == null ? void 0 : f.call(t)), S = {
351
- method: a,
352
- headers: { ...v, ...typeof A == "string" ? { Authorization: A } : A ?? {} },
391
+ const v = c.body !== void 0 ? { "Content-Type": "application/json" } : {}, $ = await ((f = t.getAuthHeader) == null ? void 0 : f.call(t)), A = {
392
+ method: s,
393
+ headers: { ...v, ...typeof $ == "string" ? { Authorization: $ } : $ ?? {} },
353
394
  signal: h.signal
354
395
  };
355
- l.body !== void 0 && (S.body = JSON.stringify(l.body)), d = await fetch(`${n}${i}`, S);
396
+ c.body !== void 0 && (A.body = JSON.stringify(c.body)), d = await fetch(`${n}${l}`, A);
356
397
  } catch (v) {
357
- throw new U(
398
+ throw new H(
358
399
  v instanceof Error ? v.message : String(v)
359
400
  );
360
401
  } finally {
361
402
  clearTimeout(u);
362
403
  }
363
404
  if (d.status === 401)
364
- throw (k = t.onUnauthorized) == null || k.call(t), new U("Unauthorized", 401);
405
+ throw (k = t.onUnauthorized) == null || k.call(t), new H("Unauthorized", 401);
365
406
  if (!d.ok) {
366
- const v = await lt(d);
367
- throw new U(
407
+ const v = await mt(d);
408
+ throw new H(
368
409
  v !== "" ? `HTTP ${d.status}: ${v}` : `HTTP ${d.status}`,
369
410
  d.status
370
411
  );
371
412
  }
372
- if (!l.schema) {
413
+ if (!c.schema) {
373
414
  try {
374
415
  await d.json();
375
416
  } catch {
376
417
  }
377
418
  return;
378
419
  }
379
- const b = l.schema.safeParse(await d.json());
380
- if (!b.success)
381
- throw new U("Invalid response schema");
382
- return b.data;
420
+ const g = c.schema.safeParse(await d.json());
421
+ if (!g.success)
422
+ throw new H("Invalid response schema");
423
+ return g.data;
383
424
  }
384
425
  return {
385
426
  baseUrl: n,
386
427
  // --- multi-workspace management surface ---------------------------------
387
428
  listWorkspaces() {
388
- return s("GET", "/workspaces", {
389
- schema: Ze
429
+ return a("GET", "/workspaces", {
430
+ schema: Qe
390
431
  });
391
432
  },
392
- createWorkspace(a) {
393
- return s("POST", "/workspaces", {
394
- body: a,
395
- schema: Xe
433
+ createWorkspace(s) {
434
+ return a("POST", "/workspaces", {
435
+ body: s,
436
+ schema: Je
396
437
  });
397
438
  },
398
- deleteWorkspace(a) {
399
- return s("DELETE", `/workspaces/${o(a)}`, {
400
- schema: Je
439
+ deleteWorkspace(s) {
440
+ return a("DELETE", `/workspaces/${o(s)}`, {
441
+ schema: et
401
442
  });
402
443
  },
403
- mintToken(a, i) {
404
- return s("POST", `/workspaces/${o(a)}/tokens`, {
405
- body: i,
406
- schema: pe
444
+ mintToken(s, l) {
445
+ return a("POST", `/workspaces/${o(s)}/tokens`, {
446
+ body: l,
447
+ schema: be
407
448
  });
408
449
  },
409
- listTokens(a) {
410
- return s("GET", `/workspaces/${o(a)}/tokens`, {
411
- schema: ge
450
+ listTokens(s) {
451
+ return a("GET", `/workspaces/${o(s)}/tokens`, {
452
+ schema: fe
412
453
  });
413
454
  },
414
- revokeToken(a, i) {
415
- return s(
455
+ revokeToken(s, l) {
456
+ return a(
416
457
  "DELETE",
417
- `/workspaces/${o(a)}/tokens/${o(i)}`
458
+ `/workspaces/${o(s)}/tokens/${o(l)}`
418
459
  );
419
460
  },
420
- mintAccountToken(a) {
421
- return s("POST", "/tokens", {
422
- body: a,
423
- schema: pe
461
+ mintAccountToken(s) {
462
+ return a("POST", "/tokens", {
463
+ body: s,
464
+ schema: be
424
465
  });
425
466
  },
426
467
  listAccountTokens() {
427
- return s("GET", "/tokens", {
428
- schema: ge
468
+ return a("GET", "/tokens", {
469
+ schema: fe
429
470
  });
430
471
  },
431
- revokeAccountToken(a) {
432
- return s("DELETE", `/tokens/${o(a)}`);
472
+ revokeAccountToken(s) {
473
+ return a("DELETE", `/tokens/${o(s)}`);
433
474
  },
434
- createInvite(a, i) {
435
- return s("POST", `/workspaces/${o(a)}/invites`, {
436
- body: i,
437
- schema: et
475
+ createInvite(s, l) {
476
+ return a("POST", `/workspaces/${o(s)}/invites`, {
477
+ body: l,
478
+ schema: nt
438
479
  });
439
480
  },
440
- inviteByEmail(a, i) {
441
- return s("POST", `/workspaces/${o(a)}/invites/email`, {
442
- body: { email: i },
443
- schema: tt
481
+ inviteByEmail(s, l) {
482
+ return a("POST", `/workspaces/${o(s)}/invites/email`, {
483
+ body: { email: l },
484
+ schema: st
444
485
  });
445
486
  },
446
- revokeInvite(a, i) {
447
- return s(
487
+ revokeInvite(s, l) {
488
+ return a(
448
489
  "POST",
449
- `/workspaces/${o(a)}/invites/${o(i)}/revoke`
490
+ `/workspaces/${o(s)}/invites/${o(l)}/revoke`
450
491
  );
451
492
  },
452
- redeemInvite(a) {
453
- return s("POST", `/invites/${o(a)}/redeem`, {
454
- schema: nt
493
+ redeemInvite(s) {
494
+ return a("POST", `/invites/${o(s)}/redeem`, {
495
+ schema: at
455
496
  });
456
497
  },
457
- listMembers(a) {
458
- return s("GET", `/workspaces/${o(a)}/members`, {
459
- schema: at
498
+ listMembers(s) {
499
+ return a("GET", `/workspaces/${o(s)}/members`, {
500
+ schema: ot
460
501
  });
461
502
  },
462
- removeMember(a, i) {
463
- return s(
503
+ removeMember(s, l) {
504
+ return a(
464
505
  "DELETE",
465
- `/workspaces/${o(a)}/members/${o(i)}`
506
+ `/workspaces/${o(s)}/members/${o(l)}`
466
507
  );
467
508
  },
468
- leave(a) {
469
- return s("POST", `/workspaces/${o(a)}/leave`);
509
+ leave(s) {
510
+ return a("POST", `/workspaces/${o(s)}/leave`);
470
511
  },
471
- landscape(a) {
472
- return s("GET", `/workspaces/${o(a)}/landscape`, {
473
- schema: me
512
+ landscape(s) {
513
+ return a("GET", `/workspaces/${o(s)}/landscape`, {
514
+ schema: pe
474
515
  });
475
516
  },
476
- announceTo(a, i) {
477
- return s("POST", `/workspaces/${o(a)}/announce`, {
478
- body: i,
479
- schema: he
517
+ announceTo(s, l) {
518
+ return a("POST", `/workspaces/${o(s)}/announce`, {
519
+ body: l,
520
+ schema: ge
480
521
  });
481
522
  },
482
- submitFeedback(a, i) {
483
- const l = i !== void 0 ? `/workspaces/${o(i)}/feedback` : "/feedback";
484
- return s("POST", l, { body: a, schema: ot });
523
+ submitFeedback(s, l) {
524
+ const c = l !== void 0 ? `/workspaces/${o(l)}/feedback` : "/feedback";
525
+ return a("POST", c, { body: s, schema: it });
485
526
  },
486
527
  // --- self-host singular aliases (implicit single workspace) -------------
487
528
  getLandscape() {
488
- return s("GET", "/workspace/landscape", {
489
- schema: me
529
+ return a("GET", "/workspace/landscape", {
530
+ schema: pe
490
531
  });
491
532
  },
492
- announce(a) {
493
- return s("POST", "/workspace/announce", {
494
- body: a,
495
- schema: he
533
+ announce(s) {
534
+ return a("POST", "/workspace/announce", {
535
+ body: s,
536
+ schema: ge
496
537
  });
497
538
  }
498
539
  };
499
540
  }
500
- const $e = Pe(null);
501
- function Bt({
541
+ const Re = We(null);
542
+ function Yt({
502
543
  client: t,
503
544
  children: n
504
545
  }) {
505
- return /* @__PURE__ */ r($e.Provider, { value: t, children: n });
546
+ return /* @__PURE__ */ r(Re.Provider, { value: t, children: n });
506
547
  }
507
- function oe() {
508
- const t = Oe($e);
548
+ function ce() {
549
+ const t = Ge(Re);
509
550
  if (t === null)
510
551
  throw new Error(
511
552
  "useShepherdClient must be used within <ShepherdClientProvider>"
512
553
  );
513
554
  return t;
514
555
  }
515
- const dt = 5e3, ut = 1e3;
516
- function mt(t) {
517
- const n = oe(), c = t == null ? void 0 : t.workspaceId, o = (t == null ? void 0 : t.pollMs) ?? dt, s = (t == null ? void 0 : t.enabled) ?? !0, [a, i] = N(
556
+ const ht = 5e3, pt = 1e3;
557
+ function gt(t) {
558
+ const n = ce(), i = t == null ? void 0 : t.workspaceId, o = (t == null ? void 0 : t.pollMs) ?? ht, a = (t == null ? void 0 : t.enabled) ?? !0, [s, l] = _(
518
559
  null
519
- ), [l, h] = N("live"), [u, d] = N(null), [, b] = N(0), f = P(n);
560
+ ), [c, h] = _("live"), [u, d] = _(null), [, g] = _(0), f = P(n);
520
561
  f.current = n;
521
- const k = P(0), v = R(
522
- async ($) => {
562
+ const k = P(0), v = j(
563
+ async (T) => {
523
564
  try {
524
- const S = c ? await f.current.landscape(c) : await f.current.getLandscape();
525
- if ($ !== k.current) return;
526
- i(S), d(Date.now()), h("live");
527
- } catch (S) {
528
- if ($ !== k.current) return;
529
- S instanceof U && S.status === 401 ? h("unauthorized") : h("reconnecting");
565
+ const A = i ? await f.current.landscape(i) : await f.current.getLandscape();
566
+ if (T !== k.current) return;
567
+ l(A), d(Date.now()), h("live");
568
+ } catch (A) {
569
+ if (T !== k.current) return;
570
+ A instanceof H && A.status === 401 ? h("unauthorized") : h("reconnecting");
530
571
  }
531
572
  },
532
- [c]
573
+ [i]
533
574
  );
534
- se(() => {
535
- if (!s) return;
536
- const $ = ++k.current;
537
- v($);
538
- const S = setInterval(() => {
539
- document.visibilityState !== "hidden" && v($);
540
- }, o), y = setInterval(() => {
541
- b((T) => T + 1);
542
- }, ut), j = () => {
543
- document.visibilityState === "visible" && v($);
575
+ ae(() => {
576
+ if (!a) return;
577
+ const T = ++k.current;
578
+ v(T);
579
+ const A = setInterval(() => {
580
+ document.visibilityState !== "hidden" && v(T);
581
+ }, o), N = setInterval(() => {
582
+ g((E) => E + 1);
583
+ }, pt), D = () => {
584
+ document.visibilityState === "visible" && v(T);
544
585
  };
545
- return document.addEventListener("visibilitychange", j), () => {
546
- k.current++, clearInterval(S), clearInterval(y), document.removeEventListener("visibilitychange", j);
586
+ return document.addEventListener("visibilitychange", D), () => {
587
+ k.current++, clearInterval(A), clearInterval(N), document.removeEventListener("visibilitychange", D);
547
588
  };
548
- }, [v, o, s]);
549
- const A = R(() => v(k.current), [v]);
550
- return { snapshot: a, status: l, lastUpdatedMs: u, refresh: A };
589
+ }, [v, o, a]);
590
+ const $ = j(() => v(k.current), [v]);
591
+ return { snapshot: s, status: c, lastUpdatedMs: u, refresh: $ };
551
592
  }
552
593
  function K(t, n) {
553
- const c = Math.floor((n - Date.parse(t)) / 1e3);
554
- if (c < 5) return "just now";
555
- if (c < 60) return `${c}s ago`;
556
- const o = Math.floor(c / 60);
594
+ const i = Math.floor((n - Date.parse(t)) / 1e3);
595
+ if (i < 5) return "just now";
596
+ if (i < 60) return `${i}s ago`;
597
+ const o = Math.floor(i / 60);
557
598
  if (o < 60) return `${o}m ago`;
558
- const s = Math.floor(o / 60);
559
- return s < 24 ? `${s}h ago` : `${Math.floor(s / 24)}d ago`;
599
+ const a = Math.floor(o / 60);
600
+ return a < 24 ? `${a}h ago` : `${Math.floor(a / 24)}d ago`;
560
601
  }
561
602
  function z(t) {
562
603
  let n = 0;
563
- for (let c = 0; c < t.length; c++) n = (n * 31 + t.charCodeAt(c)) % 360;
604
+ for (let i = 0; i < t.length; i++) n = (n * 31 + t.charCodeAt(i)) % 360;
564
605
  return `hsl(${n}, 38%, 42%)`;
565
606
  }
566
607
  function ie(t) {
@@ -568,136 +609,136 @@ function ie(t) {
568
609
  const n = t.match(/[A-Z]/g);
569
610
  return n && n.length >= 2 ? n[0] + n[1] : t.slice(0, 2).toUpperCase();
570
611
  }
571
- const Ee = "A-Za-z0-9_-";
572
- function ht(t, n) {
573
- const o = t.slice(0, n).match(new RegExp(`(?:^|\\s)@([${Ee}]*)$`));
612
+ const je = "A-Za-z0-9_-";
613
+ function bt(t, n) {
614
+ const o = t.slice(0, n).match(new RegExp(`(?:^|\\s)@([${je}]*)$`));
574
615
  if (!o) return null;
575
- const s = o[1];
576
- return { start: n - s.length - 1, end: n, query: s };
616
+ const a = o[1];
617
+ return { start: n - a.length - 1, end: n, query: a };
577
618
  }
578
- function pt(t, n) {
579
- const c = new RegExp(`(?:^|\\s)@([${Ee}]+)`, "g");
619
+ function ft(t, n) {
620
+ const i = new RegExp(`(?:^|\\s)@([${je}]+)`, "g");
580
621
  let o;
581
- for (; (o = c.exec(t)) !== null; ) {
582
- const s = o[1].toLowerCase(), a = n.find((i) => i.toLowerCase() === s);
583
- if (a) return a;
622
+ for (; (o = i.exec(t)) !== null; ) {
623
+ const a = o[1].toLowerCase(), s = n.find((l) => l.toLowerCase() === a);
624
+ if (s) return s;
584
625
  }
585
626
  return null;
586
627
  }
587
- function Re(t) {
628
+ function De(t) {
588
629
  return [...new Set(t.map((n) => n.repo))].sort();
589
630
  }
590
- function L(t, n) {
631
+ function M(t, n) {
591
632
  return n === null || n === "__all__" || t.repo === n;
592
633
  }
593
- function gt(t, n) {
634
+ function vt(t, n) {
594
635
  return [
595
636
  ...new Set(
596
- t.filter((c) => c.presence === "live" && L(c, n)).map((c) => c.name)
637
+ t.filter((i) => i.presence === "live" && M(i, n)).map((i) => i.name)
597
638
  )
598
639
  ].sort();
599
640
  }
600
- function fe(t) {
601
- const n = t.find((c) => c.status === "active");
641
+ function ve(t) {
642
+ const n = t.find((i) => i.status === "active");
602
643
  return n ? n.repo : t.length ? t[0].repo : null;
603
644
  }
604
- function ft(t) {
645
+ function kt(t) {
605
646
  return t === "dropped" ? "dropped" : "done";
606
647
  }
607
- function be(t, n) {
648
+ function ke(t, n) {
608
649
  if (!n) return "";
609
- const c = Math.floor((Date.parse(n) - Date.parse(t)) / 1e3), o = Math.floor(c / 60);
650
+ const i = Math.floor((Date.parse(n) - Date.parse(t)) / 1e3), o = Math.floor(i / 60);
610
651
  return o < 60 ? `active ${o}m` : `active ${Math.floor(o / 60)}h`;
611
652
  }
612
- function bt(t, n) {
613
- const c = new Date(Date.parse(t)), o = new Date(n), s = (i) => new Date(i.getFullYear(), i.getMonth(), i.getDate()).getTime(), a = Math.round((s(o) - s(c)) / 864e5);
614
- return a <= 0 ? "Today" : a === 1 ? "Yesterday" : c.toLocaleDateString(void 0, { month: "short", day: "numeric" });
653
+ function yt(t, n) {
654
+ const i = new Date(Date.parse(t)), o = new Date(n), a = (l) => new Date(l.getFullYear(), l.getMonth(), l.getDate()).getTime(), s = Math.round((a(o) - a(i)) / 864e5);
655
+ return s <= 0 ? "Today" : s === 1 ? "Yesterday" : i.toLocaleDateString(void 0, { month: "short", day: "numeric" });
615
656
  }
616
- function ve(t) {
657
+ function ye(t) {
617
658
  let n = t.toLowerCase().replace(/\\/g, "/");
618
659
  n.endsWith("/") && (n = n.replace(/\/+$/, "") + "/**");
619
- const c = [];
660
+ const i = [];
620
661
  for (const o of n.split("/"))
621
662
  if (!(o === "" || o === ".")) {
622
663
  if (o === "..") {
623
- c.length && c.pop();
664
+ i.length && i.pop();
624
665
  continue;
625
666
  }
626
- c.push(o);
667
+ i.push(o);
627
668
  }
628
- return c;
669
+ return i;
629
670
  }
630
- const ke = /[*?{}[\]]/;
631
- function vt(t, n) {
632
- return t === "*" ? !0 : (ke.test(t) || !ke.test(n)) && t === n;
671
+ const _e = /[*?{}[\]]/;
672
+ function _t(t, n) {
673
+ return t === "*" ? !0 : (_e.test(t) || !_e.test(n)) && t === n;
633
674
  }
634
- function kt(t, n) {
635
- const c = /* @__PURE__ */ new Map();
636
- function o(s, a) {
637
- if (n.length - a === 0) {
638
- for (let b = s; b < t.length; b++) if (t[b] !== "**") return !1;
675
+ function Nt(t, n) {
676
+ const i = /* @__PURE__ */ new Map();
677
+ function o(a, s) {
678
+ if (n.length - s === 0) {
679
+ for (let g = a; g < t.length; g++) if (t[g] !== "**") return !1;
639
680
  return !0;
640
681
  }
641
- if (t.length - s === 0) return !1;
642
- const i = s * (n.length + 1) + a, l = c.get(i);
643
- if (l !== void 0) return l;
644
- const h = t[s], u = n[a];
682
+ if (t.length - a === 0) return !1;
683
+ const l = a * (n.length + 1) + s, c = i.get(l);
684
+ if (c !== void 0) return c;
685
+ const h = t[a], u = n[s];
645
686
  let d;
646
- return h === "**" ? d = o(s + 1, a) || o(s, a + 1) : u === "**" ? d = !1 : d = vt(h, u) && o(s + 1, a + 1), c.set(i, d), d;
687
+ return h === "**" ? d = o(a + 1, s) || o(a, s + 1) : u === "**" ? d = !1 : d = _t(h, u) && o(a + 1, s + 1), i.set(l, d), d;
647
688
  }
648
689
  return o(0, 0);
649
690
  }
650
- function ye(t, n) {
691
+ function Ne(t, n) {
651
692
  if (n.length === 0) return !0;
652
- const c = t.map(ve);
693
+ const i = t.map(ye);
653
694
  return n.every((o) => {
654
- const s = ve(o);
655
- return c.some((a) => kt(a, s));
695
+ const a = ye(o);
696
+ return i.some((s) => Nt(s, a));
656
697
  });
657
698
  }
658
- function yt(t) {
699
+ function wt(t) {
659
700
  const n = /* @__PURE__ */ new Map();
660
- for (const s of t)
661
- n.has(s.agentName) || n.set(s.agentName, []), n.get(s.agentName).push(s);
662
- const c = (s, a) => a.createdAt.localeCompare(s.createdAt), o = [];
663
- for (const [s, a] of n) {
664
- const i = [...a].sort(c), l = i.map(
665
- (u) => i.some(
666
- (d) => d !== u && ye(d.pathGlobs, u.pathGlobs) && !ye(u.pathGlobs, d.pathGlobs)
701
+ for (const a of t)
702
+ n.has(a.agentName) || n.set(a.agentName, []), n.get(a.agentName).push(a);
703
+ const i = (a, s) => s.createdAt.localeCompare(a.createdAt), o = [];
704
+ for (const [a, s] of n) {
705
+ const l = [...s].sort(i), c = l.map(
706
+ (u) => l.some(
707
+ (d) => d !== u && Ne(d.pathGlobs, u.pathGlobs) && !Ne(u.pathGlobs, d.pathGlobs)
667
708
  )
668
- ), h = i[0];
709
+ ), h = l[0];
669
710
  o.push({
670
- agentName: s,
711
+ agentName: a,
671
712
  model: h.model,
672
713
  program: h.program,
673
714
  repo: h.repo,
674
- primaries: i.filter((u, d) => !l[d]),
675
- narrower: i.filter((u, d) => l[d])
715
+ primaries: l.filter((u, d) => !c[d]),
716
+ narrower: l.filter((u, d) => c[d])
676
717
  });
677
718
  }
678
- return o.sort((s, a) => {
679
- const i = s.primaries.concat(s.narrower)[0].createdAt;
680
- return a.primaries.concat(a.narrower)[0].createdAt.localeCompare(i);
719
+ return o.sort((a, s) => {
720
+ const l = a.primaries.concat(a.narrower)[0].createdAt;
721
+ return s.primaries.concat(s.narrower)[0].createdAt.localeCompare(l);
681
722
  }), o;
682
723
  }
683
- const _e = { active: 0, done: 0 };
684
- function _t({
724
+ const we = { active: 0, done: 0 };
725
+ function At({
685
726
  repos: t,
686
727
  counts: n,
687
- selected: c,
728
+ selected: i,
688
729
  onSelect: o
689
730
  }) {
690
- const [s, a] = N(!1), i = P(null);
691
- if (se(() => {
731
+ const [a, s] = _(!1), l = P(null);
732
+ if (ae(() => {
692
733
  var f;
693
- if (!s) return;
694
- const d = (f = i.current) == null ? void 0 : f.querySelector(".repo-menu");
734
+ if (!a) return;
735
+ const d = (f = l.current) == null ? void 0 : f.querySelector(".repo-menu");
695
736
  if (!d) return;
696
- const b = d.querySelector('[aria-selected="true"]') ?? d.querySelector("button");
697
- b == null || b.focus();
698
- }, [s]), t.length < 2) return null;
699
- const l = c === null || c === "__all__", h = l ? "All repos" : c, u = (d, b) => {
700
- const f = d === null ? n.__all__ ?? _e : n[d] ?? _e, k = d === null ? l : c === d, v = "repo-mi" + (k ? " on" : "") + (d === null ? " all" : "");
737
+ const g = d.querySelector('[aria-selected="true"]') ?? d.querySelector("button");
738
+ g == null || g.focus();
739
+ }, [a]), t.length < 2) return null;
740
+ const c = i === null || i === "__all__", h = c ? "All repos" : i, u = (d, g) => {
741
+ const f = d === null ? n.__all__ ?? we : n[d] ?? we, k = d === null ? c : i === d, v = "repo-mi" + (k ? " on" : "") + (d === null ? " all" : "");
701
742
  return /* @__PURE__ */ m(
702
743
  "button",
703
744
  {
@@ -705,11 +746,11 @@ function _t({
705
746
  className: v,
706
747
  role: "option",
707
748
  "aria-selected": k,
708
- onClick: (A) => {
709
- A.stopPropagation(), a(!1), o(d);
749
+ onClick: ($) => {
750
+ $.stopPropagation(), s(!1), o(d);
710
751
  },
711
752
  children: [
712
- /* @__PURE__ */ r("span", { children: b }),
753
+ /* @__PURE__ */ r("span", { children: g }),
713
754
  /* @__PURE__ */ r("span", { className: "ct", children: `${f.active} active · ${f.done} done` })
714
755
  ]
715
756
  },
@@ -719,10 +760,10 @@ function _t({
719
760
  return /* @__PURE__ */ m(
720
761
  "span",
721
762
  {
722
- ref: i,
763
+ ref: l,
723
764
  className: "repo",
724
765
  onKeyDown: (d) => {
725
- d.key === "Escape" && a(!1);
766
+ d.key === "Escape" && s(!1);
726
767
  },
727
768
  children: [
728
769
  /* @__PURE__ */ m(
@@ -731,10 +772,10 @@ function _t({
731
772
  type: "button",
732
773
  className: "repo-trig",
733
774
  "aria-haspopup": "listbox",
734
- "aria-expanded": s,
775
+ "aria-expanded": a,
735
776
  "aria-label": `Filter by repo (current: ${h})`,
736
777
  onClick: (d) => {
737
- d.stopPropagation(), a((b) => !b);
778
+ d.stopPropagation(), s((g) => !g);
738
779
  },
739
780
  children: [
740
781
  /* @__PURE__ */ r("span", { className: "slash", children: "/" }),
@@ -743,7 +784,7 @@ function _t({
743
784
  ]
744
785
  }
745
786
  ),
746
- s && /* @__PURE__ */ m("div", { className: "repo-menu", role: "listbox", children: [
787
+ a && /* @__PURE__ */ m("div", { className: "repo-menu", role: "listbox", children: [
747
788
  t.map((d) => u(d, d)),
748
789
  u(null, "All repos")
749
790
  ] })
@@ -751,28 +792,28 @@ function _t({
751
792
  }
752
793
  );
753
794
  }
754
- function Nt({ agents: t, tasks: n, selectedRepo: c }) {
795
+ function Tt({ agents: t, tasks: n, selectedRepo: i }) {
755
796
  const o = t.filter(
756
- (l) => l.presence === "live" && L({ repo: l.repo ?? "" }, c)
757
- ), s = /* @__PURE__ */ new Set();
758
- for (const l of n) l.status === "active" && s.add(l.agentName);
759
- const a = (l) => s.has(l.name), i = [...o].sort((l, h) => {
760
- const u = a(l), d = a(h);
761
- return u !== d ? u ? -1 : 1 : l.name.localeCompare(h.name);
797
+ (c) => c.presence === "live" && M({ repo: c.repo ?? "" }, i)
798
+ ), a = /* @__PURE__ */ new Set();
799
+ for (const c of n) c.status === "active" && a.add(c.agentName);
800
+ const s = (c) => a.has(c.name), l = [...o].sort((c, h) => {
801
+ const u = s(c), d = s(h);
802
+ return u !== d ? u ? -1 : 1 : c.name.localeCompare(h.name);
762
803
  });
763
- return /* @__PURE__ */ r("div", { className: "crew", id: "crew", children: i.map((l) => /* @__PURE__ */ m(
804
+ return /* @__PURE__ */ r("div", { className: "crew", id: "crew", children: l.map((c) => /* @__PURE__ */ m(
764
805
  "div",
765
806
  {
766
- className: "person" + (a(l) ? "" : " person--idle"),
807
+ className: "person" + (s(c) ? "" : " person--idle"),
767
808
  children: [
768
- /* @__PURE__ */ r("div", { className: "avatar", style: { background: z(l.name) }, children: ie(l.name) }),
769
- /* @__PURE__ */ r("span", { className: "person__name", children: l.name })
809
+ /* @__PURE__ */ r("div", { className: "avatar", style: { background: z(c.name) }, children: ie(c.name) }),
810
+ /* @__PURE__ */ r("span", { className: "person__name", children: c.name })
770
811
  ]
771
812
  },
772
- l.name
813
+ c.name
773
814
  )) });
774
815
  }
775
- function je({ globs: t }) {
816
+ function Ie({ globs: t }) {
776
817
  return t.length <= 1 ? /* @__PURE__ */ m("div", { className: "terr", children: [
777
818
  /* @__PURE__ */ r("span", { className: "terr__lbl", children: "territory" }),
778
819
  t.map((n) => /* @__PURE__ */ r("span", { className: "glob", children: n }, n))
@@ -787,151 +828,151 @@ function je({ globs: t }) {
787
828
  /* @__PURE__ */ r("div", { className: "terr terr--full", children: t.map((n) => /* @__PURE__ */ r("span", { className: "glob", children: n }, n)) })
788
829
  ] });
789
830
  }
790
- const te = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, wt = (t) => t === null || t === "__all__";
791
- function ne({
831
+ const ne = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, St = (t) => t === null || t === "__all__";
832
+ function se({
792
833
  task: t,
793
834
  nowMs: n
794
835
  }) {
795
- return /* @__PURE__ */ m(H, { children: [
836
+ return /* @__PURE__ */ m(q, { children: [
796
837
  /* @__PURE__ */ r("div", { className: "task__intent", children: t.intent }),
797
- /* @__PURE__ */ r(je, { globs: t.pathGlobs }),
838
+ /* @__PURE__ */ r(Ie, { globs: t.pathGlobs }),
798
839
  /* @__PURE__ */ r("div", { className: "task__meta", children: `started ${K(t.createdAt, n)}` })
799
840
  ] });
800
841
  }
801
- function At({
842
+ function Ct({
802
843
  task: t,
803
844
  nowMs: n,
804
- allRepos: c
845
+ allRepos: i
805
846
  }) {
806
847
  const o = t.model || t.program;
807
848
  return /* @__PURE__ */ m("div", { className: "task", children: [
808
849
  /* @__PURE__ */ m("div", { className: "task__r1", children: [
809
850
  /* @__PURE__ */ r("span", { className: "task__who", children: t.agentName }),
810
- c && /* @__PURE__ */ r("span", { className: "task__repo", children: t.repo }),
851
+ i && /* @__PURE__ */ r("span", { className: "task__repo", children: t.repo }),
811
852
  o && /* @__PURE__ */ r("span", { className: "task__tag", children: o }),
812
853
  /* @__PURE__ */ r("span", { className: "livedot", title: "active" })
813
854
  ] }),
814
- /* @__PURE__ */ r(ne, { task: t, nowMs: n })
855
+ /* @__PURE__ */ r(se, { task: t, nowMs: n })
815
856
  ] });
816
857
  }
817
- function St({
858
+ function $t({
818
859
  group: t,
819
860
  nowMs: n,
820
- allRepos: c
861
+ allRepos: i
821
862
  }) {
822
- const o = t.model || t.program, s = t.primaries.length + t.narrower.length, a = t.narrower.length;
863
+ const o = t.model || t.program, a = t.primaries.length + t.narrower.length, s = t.narrower.length;
823
864
  return /* @__PURE__ */ m("div", { className: "grp", children: [
824
865
  /* @__PURE__ */ m("div", { className: "grp__head", children: [
825
866
  /* @__PURE__ */ r("span", { className: "grp__who", children: t.agentName }),
826
- c && /* @__PURE__ */ r("span", { className: "task__repo", children: t.repo }),
867
+ i && /* @__PURE__ */ r("span", { className: "task__repo", children: t.repo }),
827
868
  o && /* @__PURE__ */ r("span", { className: "grp__tag", children: o }),
828
- /* @__PURE__ */ r("span", { className: "grp__count", children: `· ${s} active` }),
869
+ /* @__PURE__ */ r("span", { className: "grp__count", children: `· ${a} active` }),
829
870
  /* @__PURE__ */ r("span", { className: "grp__dot", title: "live" })
830
871
  ] }),
831
- /* @__PURE__ */ r("div", { className: "claims", children: t.primaries.map((i) => /* @__PURE__ */ r("div", { className: "claim", children: /* @__PURE__ */ r(ne, { task: i, nowMs: n }) }, te(i))) }),
832
- a > 0 && /* @__PURE__ */ m("details", { className: "fold", children: [
872
+ /* @__PURE__ */ r("div", { className: "claims", children: t.primaries.map((l) => /* @__PURE__ */ r("div", { className: "claim", children: /* @__PURE__ */ r(se, { task: l, nowMs: n }) }, ne(l))) }),
873
+ s > 0 && /* @__PURE__ */ m("details", { className: "fold", children: [
833
874
  /* @__PURE__ */ m("summary", { children: [
834
875
  /* @__PURE__ */ r("span", { className: "tw", children: "▶" }),
835
- ` +${a} narrower claim${a > 1 ? "s" : ""}`
876
+ ` +${s} narrower claim${s > 1 ? "s" : ""}`
836
877
  ] }),
837
- /* @__PURE__ */ r("div", { className: "fold__body", children: t.narrower.map((i) => /* @__PURE__ */ m("div", { className: "claim", children: [
838
- /* @__PURE__ */ r(ne, { task: i, nowMs: n }),
878
+ /* @__PURE__ */ r("div", { className: "fold__body", children: t.narrower.map((l) => /* @__PURE__ */ m("div", { className: "claim", children: [
879
+ /* @__PURE__ */ r(se, { task: l, nowMs: n }),
839
880
  /* @__PURE__ */ r("div", { className: "covered", children: "⊂ covered by a claim above" })
840
- ] }, te(i))) })
881
+ ] }, ne(l))) })
841
882
  ] })
842
883
  ] });
843
884
  }
844
- function Tt({
885
+ function Et({
845
886
  tasks: t,
846
887
  nowMs: n,
847
- selectedRepo: c
888
+ selectedRepo: i
848
889
  }) {
849
- const o = wt(c), s = t.filter(
850
- (a) => a.status === "active" && L(a, c)
890
+ const o = St(i), a = t.filter(
891
+ (s) => s.status === "active" && M(s, i)
851
892
  );
852
- if (s.length === 0) {
853
- const a = o ? "Nothing active right now." : `Nothing active in ${c}.`;
854
- return /* @__PURE__ */ r("div", { id: "active-list", children: /* @__PURE__ */ r("div", { className: "empty", children: a }) });
893
+ if (a.length === 0) {
894
+ const s = o ? "Nothing active right now." : `Nothing active in ${i}.`;
895
+ return /* @__PURE__ */ r("div", { id: "active-list", children: /* @__PURE__ */ r("div", { className: "empty", children: s }) });
855
896
  }
856
- return /* @__PURE__ */ r("div", { id: "active-list", children: yt(s).map((a) => {
857
- const i = a.primaries.length === 1 && a.narrower.length === 0, l = te(a.primaries.concat(a.narrower)[0]);
858
- return i ? /* @__PURE__ */ r(
859
- At,
897
+ return /* @__PURE__ */ r("div", { id: "active-list", children: wt(a).map((s) => {
898
+ const l = s.primaries.length === 1 && s.narrower.length === 0, c = ne(s.primaries.concat(s.narrower)[0]);
899
+ return l ? /* @__PURE__ */ r(
900
+ Ct,
860
901
  {
861
- task: a.primaries[0],
902
+ task: s.primaries[0],
862
903
  nowMs: n,
863
904
  allRepos: o
864
905
  },
865
- l
866
- ) : /* @__PURE__ */ r(St, { group: a, nowMs: n, allRepos: o }, l);
906
+ c
907
+ ) : /* @__PURE__ */ r($t, { group: s, nowMs: n, allRepos: o }, c);
867
908
  }) });
868
909
  }
869
- const Ct = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, $t = (t) => t === null || t === "__all__";
870
- function Et({
910
+ const Rt = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, jt = (t) => t === null || t === "__all__";
911
+ function Dt({
871
912
  tasks: t,
872
913
  nowMs: n,
873
- selectedRepo: c,
914
+ selectedRepo: i,
874
915
  doneShown: o,
875
- onLoadMore: s
916
+ onLoadMore: a
876
917
  }) {
877
- const a = $t(c), i = t.filter(
878
- (u) => u.status !== "active" && L(u, c)
918
+ const s = jt(i), l = t.filter(
919
+ (u) => u.status !== "active" && M(u, i)
879
920
  );
880
- if (i.length === 0) {
881
- const u = a ? "No finished tasks yet." : `No finished tasks in ${c} yet.`;
921
+ if (l.length === 0) {
922
+ const u = s ? "No finished tasks yet." : `No finished tasks in ${i} yet.`;
882
923
  return /* @__PURE__ */ r("div", { id: "done-list", children: /* @__PURE__ */ r("div", { className: "empty", children: u }) });
883
924
  }
884
- const l = i.slice(0, o);
925
+ const c = l.slice(0, o);
885
926
  let h = null;
886
927
  return /* @__PURE__ */ m("div", { id: "done-list", children: [
887
- l.map((u) => {
888
- const d = bt(u.endedAt ?? u.createdAt, n), b = d !== h ? d : null;
928
+ c.map((u) => {
929
+ const d = yt(u.endedAt ?? u.createdAt, n), g = d !== h ? d : null;
889
930
  h = d;
890
- const f = u.status === "dropped", k = f ? `went offline ${K(u.endedAt ?? u.createdAt, n)} no done signal` : `finished ${K(u.endedAt ?? u.createdAt, n)}${be(u.createdAt, u.endedAt) ? " · " + be(u.createdAt, u.endedAt) : ""}`;
891
- return /* @__PURE__ */ m(Ge, { children: [
892
- b !== null && /* @__PURE__ */ r("div", { className: "day", children: b }),
931
+ const f = u.status === "dropped", k = f ? `went offline ${K(u.endedAt ?? u.createdAt, n)}, no done signal` : `finished ${K(u.endedAt ?? u.createdAt, n)}${ke(u.createdAt, u.endedAt) ? " · " + ke(u.createdAt, u.endedAt) : ""}`;
932
+ return /* @__PURE__ */ m(Fe, { children: [
933
+ g !== null && /* @__PURE__ */ r("div", { className: "day", children: g }),
893
934
  /* @__PURE__ */ m("div", { className: "task", children: [
894
935
  /* @__PURE__ */ m("div", { className: "task__r1", children: [
895
936
  /* @__PURE__ */ r("span", { className: "task__who", children: u.agentName }),
896
- a && /* @__PURE__ */ r("span", { className: "task__repo", children: u.repo }),
937
+ s && /* @__PURE__ */ r("span", { className: "task__repo", children: u.repo }),
897
938
  /* @__PURE__ */ r(
898
939
  "span",
899
940
  {
900
941
  className: "task__stat" + (f ? " task__stat--drop" : ""),
901
- children: ft(u.status)
942
+ children: kt(u.status)
902
943
  }
903
944
  )
904
945
  ] }),
905
946
  /* @__PURE__ */ r("div", { className: "task__intent", children: u.intent }),
906
- /* @__PURE__ */ r(je, { globs: u.pathGlobs }),
947
+ /* @__PURE__ */ r(Ie, { globs: u.pathGlobs }),
907
948
  /* @__PURE__ */ r("div", { className: "task__meta", children: k })
908
949
  ] })
909
- ] }, Ct(u));
950
+ ] }, Rt(u));
910
951
  }),
911
- i.length > o && /* @__PURE__ */ r(
952
+ l.length > o && /* @__PURE__ */ r(
912
953
  "div",
913
954
  {
914
955
  className: "more",
915
956
  role: "button",
916
957
  tabIndex: 0,
917
- onClick: s,
958
+ onClick: a,
918
959
  onKeyDown: (u) => {
919
- (u.key === "Enter" || u.key === " ") && (u.preventDefault(), s());
960
+ (u.key === "Enter" || u.key === " ") && (u.preventDefault(), a());
920
961
  },
921
- children: `Load older · ${o} of ${i.length}`
962
+ children: `Load older · ${o} of ${l.length}`
922
963
  }
923
964
  )
924
965
  ] });
925
966
  }
926
- const Rt = 80;
927
- function jt({ announcements: t, selectedRepo: n, nowMs: c }) {
928
- const o = P(null), s = P(!0), a = o.current;
929
- a && (s.current = a.scrollHeight - a.scrollTop - a.clientHeight < Rt);
930
- const i = [...t].filter((l) => L(l, n)).reverse();
931
- return Fe(() => {
932
- s.current && o.current && (o.current.scrollTop = o.current.scrollHeight);
933
- }, [i.length]), /* @__PURE__ */ r("div", { id: "chat", className: "chat", ref: o, children: i.length === 0 ? /* @__PURE__ */ r("div", { className: "empty", children: "No announcements yet agents will post here as they coordinate." }) : i.map((l, h) => {
934
- const d = "msg" + (l.targetAgentName !== null || l.toAdmin ? " msg--targeted" : "") + (l.fromAdmin ? " msg--me" : "");
967
+ const It = 80;
968
+ function xt({ announcements: t, selectedRepo: n, nowMs: i }) {
969
+ const o = P(null), a = P(!0), s = o.current;
970
+ s && (a.current = s.scrollHeight - s.scrollTop - s.clientHeight < It);
971
+ const l = [...t].filter((c) => M(c, n)).reverse();
972
+ return Ue(() => {
973
+ a.current && o.current && (o.current.scrollTop = o.current.scrollHeight);
974
+ }, [l.length]), /* @__PURE__ */ r("div", { id: "chat", className: "chat", ref: o, children: l.length === 0 ? /* @__PURE__ */ r("div", { className: "empty", children: "No announcements yet. Agents will post here as they coordinate." }) : l.map((c, h) => {
975
+ const d = "msg" + (c.targetAgentName !== null || c.toAdmin ? " msg--targeted" : "") + (c.fromAdmin ? " msg--me" : "");
935
976
  return (
936
977
  // The feed has no stable id; index is acceptable because the list is
937
978
  // append-only oldest->newest and rows are never reordered in place.
@@ -940,8 +981,8 @@ function jt({ announcements: t, selectedRepo: n, nowMs: c }) {
940
981
  "div",
941
982
  {
942
983
  className: "msg__avatar",
943
- style: { background: z(l.fromAgentName) },
944
- children: ie(l.fromAgentName)
984
+ style: { background: z(c.fromAgentName) },
985
+ children: ie(c.fromAgentName)
945
986
  }
946
987
  ),
947
988
  /* @__PURE__ */ m("div", { className: "msg__body", children: [
@@ -950,82 +991,82 @@ function jt({ announcements: t, selectedRepo: n, nowMs: c }) {
950
991
  "span",
951
992
  {
952
993
  className: "msg__who",
953
- style: { color: z(l.fromAgentName) },
954
- children: l.fromAgentName
994
+ style: { color: z(c.fromAgentName) },
995
+ children: c.fromAgentName
955
996
  }
956
997
  ),
957
- l.fromHuman ? /* @__PURE__ */ r("span", { className: "msg__human", children: l.fromHuman }) : null,
958
- l.targetAgentName !== null ? /* @__PURE__ */ r("span", { className: "msg__to", children: `→ @${l.targetAgentName}` }) : l.targetMemberName !== null ? (
998
+ c.fromHuman ? /* @__PURE__ */ r("span", { className: "msg__human", children: c.fromHuman }) : null,
999
+ c.targetAgentName !== null ? /* @__PURE__ */ r("span", { className: "msg__to", children: `→ @${c.targetAgentName}` }) : c.targetMemberName !== null ? (
959
1000
  // An agent addressed a specific workspace member by name;
960
1001
  // legacy/collective operator messages fall through to "admin".
961
- /* @__PURE__ */ r("span", { className: "msg__to", children: `→ @${l.targetMemberName}` })
962
- ) : l.toAdmin ? /* @__PURE__ */ r("span", { className: "msg__to", children: "→ admin" }) : null,
963
- /* @__PURE__ */ r("span", { className: "msg__time", children: K(l.createdAt, c) })
1002
+ /* @__PURE__ */ r("span", { className: "msg__to", children: `→ @${c.targetMemberName}` })
1003
+ ) : c.toAdmin ? /* @__PURE__ */ r("span", { className: "msg__to", children: "→ admin" }) : null,
1004
+ /* @__PURE__ */ r("span", { className: "msg__time", children: K(c.createdAt, i) })
964
1005
  ] }),
965
- /* @__PURE__ */ r("div", { className: "msg__text", children: l.body })
1006
+ /* @__PURE__ */ r("div", { className: "msg__text", children: c.body })
966
1007
  ] })
967
1008
  ] }, h)
968
1009
  );
969
1010
  }) });
970
1011
  }
971
- const Dt = 8;
972
- function It({ agents: t, selectedRepo: n, workspaceId: c, onSent: o }) {
973
- const s = oe(), a = P(null), [i, l] = N(""), [h, u] = N([]), [d, b] = N(0), [f, k] = N(null), [v, A] = N(!1), [$, S] = N(!1), y = gt(
1012
+ const Mt = 8;
1013
+ function Lt({ agents: t, selectedRepo: n, workspaceId: i, onSent: o }) {
1014
+ const a = ce(), s = P(null), [l, c] = _(""), [h, u] = _([]), [d, g] = _(0), [f, k] = _(null), [v, $] = _(!1), [T, A] = _(!1), N = vt(
974
1015
  t.map((p) => ({ name: p.name, presence: p.presence, repo: p.repo ?? "" })),
975
1016
  n
976
- ), j = h.length > 0, T = R(() => {
1017
+ ), D = h.length > 0, E = j(() => {
977
1018
  u([]), k(null);
978
- }, []), q = R(
979
- (p, _) => {
980
- const C = ht(p, _);
981
- if (!C) {
982
- T();
1019
+ }, []), O = j(
1020
+ (p, y) => {
1021
+ const S = bt(p, y);
1022
+ if (!S) {
1023
+ E();
983
1024
  return;
984
1025
  }
985
- const D = C.query.toLowerCase(), I = y.filter((B) => B.toLowerCase().startsWith(D)).slice(0, Dt);
986
- u(I), k({ start: C.start, end: C.end }), b(0);
1026
+ const L = S.query.toLowerCase(), R = N.filter((Z) => Z.toLowerCase().startsWith(L)).slice(0, Mt);
1027
+ u(R), k({ start: S.start, end: S.end }), g(0);
987
1028
  },
988
- [y, T]
989
- ), G = R(
1029
+ [N, E]
1030
+ ), G = j(
990
1031
  (p) => {
991
1032
  if (!f) return;
992
- const _ = "@" + p + " ", C = i.slice(0, f.start) + _ + i.slice(f.end), D = f.start + _.length;
993
- l(C), T(), requestAnimationFrame(() => {
994
- const I = a.current;
995
- I && (I.focus(), I.setSelectionRange(D, D));
1033
+ const y = "@" + p + " ", S = l.slice(0, f.start) + y + l.slice(f.end), L = f.start + y.length;
1034
+ c(S), E(), requestAnimationFrame(() => {
1035
+ const R = s.current;
1036
+ R && (R.focus(), R.setSelectionRange(L, L));
996
1037
  });
997
1038
  },
998
- [f, i, T]
999
- ), w = R(
1039
+ [f, l, E]
1040
+ ), X = j(
1000
1041
  (p) => {
1001
- var C;
1002
- l(p);
1003
- const _ = ((C = a.current) == null ? void 0 : C.selectionStart) ?? p.length;
1004
- q(p, _);
1042
+ var S;
1043
+ c(p);
1044
+ const y = ((S = s.current) == null ? void 0 : S.selectionStart) ?? p.length;
1045
+ O(p, y);
1005
1046
  },
1006
- [q]
1007
- ), F = R(
1047
+ [O]
1048
+ ), w = j(
1008
1049
  (p) => {
1009
- j && (p.key === "ArrowDown" ? (p.preventDefault(), b((_) => (_ + 1) % h.length)) : p.key === "ArrowUp" ? (p.preventDefault(), b((_) => (_ - 1 + h.length) % h.length)) : p.key === "Enter" || p.key === "Tab" ? (p.preventDefault(), G(h[d])) : p.key === "Escape" && (p.preventDefault(), T()));
1050
+ D && (p.key === "ArrowDown" ? (p.preventDefault(), g((y) => (y + 1) % h.length)) : p.key === "ArrowUp" ? (p.preventDefault(), g((y) => (y - 1 + h.length) % h.length)) : p.key === "Enter" || p.key === "Tab" ? (p.preventDefault(), G(h[d])) : p.key === "Escape" && (p.preventDefault(), E()));
1010
1051
  },
1011
- [j, h, d, G, T]
1012
- ), X = R(
1052
+ [D, h, d, G, E]
1053
+ ), F = j(
1013
1054
  async (p) => {
1014
1055
  p.preventDefault();
1015
- const _ = i.trim();
1016
- if (!_) return;
1017
- const C = pt(_, y), D = n === null || n === "__all__" ? null : n;
1018
- A(!0), S(!1);
1056
+ const y = l.trim();
1057
+ if (!y) return;
1058
+ const S = ft(y, N), L = n === null || n === "__all__" ? null : n;
1059
+ $(!0), A(!1);
1019
1060
  try {
1020
- const I = { body: _, targetAgentName: C, repo: D };
1021
- await (c !== void 0 ? s.announceTo(c, I) : s.announce(I)), l(""), T(), await o();
1061
+ const R = { body: y, targetAgentName: S, repo: L };
1062
+ await (i !== void 0 ? a.announceTo(i, R) : a.announce(R)), c(""), E(), await o();
1022
1063
  } catch {
1023
- S(!0);
1064
+ A(!0);
1024
1065
  } finally {
1025
- A(!1);
1066
+ $(!1);
1026
1067
  }
1027
1068
  },
1028
- [i, y, n, c, s, T, o]
1069
+ [l, N, n, i, a, E, o]
1029
1070
  );
1030
1071
  return /* @__PURE__ */ m("div", { className: "composer", children: [
1031
1072
  /* @__PURE__ */ r(
@@ -1035,17 +1076,17 @@ function It({ agents: t, selectedRepo: n, workspaceId: c, onSent: o }) {
1035
1076
  className: "mention-pop",
1036
1077
  role: "listbox",
1037
1078
  "aria-label": "Agents to mention",
1038
- hidden: !j,
1039
- children: h.map((p, _) => /* @__PURE__ */ m(
1079
+ hidden: !D,
1080
+ children: h.map((p, y) => /* @__PURE__ */ m(
1040
1081
  "button",
1041
1082
  {
1042
- id: `mention-opt-${_}`,
1083
+ id: `mention-opt-${y}`,
1043
1084
  type: "button",
1044
1085
  role: "option",
1045
- "aria-selected": _ === d,
1046
- className: "mention-mi" + (_ === d ? " on" : ""),
1047
- onMouseDown: (C) => {
1048
- C.preventDefault(), G(p);
1086
+ "aria-selected": y === d,
1087
+ className: "mention-mi" + (y === d ? " on" : ""),
1088
+ onMouseDown: (S) => {
1089
+ S.preventDefault(), G(p);
1049
1090
  },
1050
1091
  children: [
1051
1092
  /* @__PURE__ */ r("div", { className: "ma", style: { background: z(p) }, children: ie(p) }),
@@ -1062,7 +1103,7 @@ function It({ agents: t, selectedRepo: n, workspaceId: c, onSent: o }) {
1062
1103
  id: "chat-form",
1063
1104
  className: "chat-form",
1064
1105
  onSubmit: (p) => {
1065
- X(p);
1106
+ F(p);
1066
1107
  },
1067
1108
  children: [
1068
1109
  /* @__PURE__ */ r(
@@ -1075,57 +1116,57 @@ function It({ agents: t, selectedRepo: n, workspaceId: c, onSent: o }) {
1075
1116
  "aria-label": "Message the team",
1076
1117
  placeholder: "Message the team… use @name to direct it",
1077
1118
  role: "combobox",
1078
- "aria-expanded": j,
1119
+ "aria-expanded": D,
1079
1120
  "aria-controls": "mention-pop",
1080
1121
  "aria-autocomplete": "list",
1081
- "aria-activedescendant": j ? `mention-opt-${d}` : void 0,
1082
- ref: a,
1083
- value: i,
1084
- onChange: (p) => w(p.target.value),
1085
- onKeyDown: F
1122
+ "aria-activedescendant": D ? `mention-opt-${d}` : void 0,
1123
+ ref: s,
1124
+ value: l,
1125
+ onChange: (p) => X(p.target.value),
1126
+ onKeyDown: w
1086
1127
  }
1087
1128
  ),
1088
1129
  /* @__PURE__ */ r("button", { id: "chat-send", className: "chat-send", type: "submit", disabled: v, children: "Send" })
1089
1130
  ]
1090
1131
  }
1091
1132
  ),
1092
- $ ? /* @__PURE__ */ r("div", { className: "chat__note", role: "status", children: "send failed retry" }) : null
1133
+ T ? /* @__PURE__ */ r("div", { className: "chat__note", role: "status", children: "send failed, retry" }) : null
1093
1134
  ] });
1094
1135
  }
1095
- function Ne({
1136
+ function Ae({
1096
1137
  title: t = "No workspace yet",
1097
1138
  children: n,
1098
- onGetStarted: c,
1139
+ onGetStarted: i,
1099
1140
  ctaLabel: o = "Go to Config"
1100
1141
  }) {
1101
- const s = Se();
1102
- return /* @__PURE__ */ m("section", { className: "shepherd-empty-state", "aria-labelledby": s, children: [
1103
- /* @__PURE__ */ r("h2", { id: s, children: t }),
1142
+ const a = Ce();
1143
+ return /* @__PURE__ */ m("section", { className: "shepherd-empty-state", "aria-labelledby": a, children: [
1144
+ /* @__PURE__ */ r("h2", { id: a, children: t }),
1104
1145
  /* @__PURE__ */ r("p", { children: n ?? "Create a workspace or join one with an invite code to get started." }),
1105
- c && /* @__PURE__ */ r("button", { type: "button", onClick: c, children: o })
1146
+ i && /* @__PURE__ */ r("button", { type: "button", onClick: i, children: o })
1106
1147
  ] });
1107
1148
  }
1108
- const xt = [
1149
+ const Pt = [
1109
1150
  { id: "bug", label: "Bug" },
1110
1151
  { id: "suggestion", label: "Suggestion" },
1111
1152
  { id: "other", label: "Other" }
1112
- ], Mt = 1500;
1113
- function Lt({ workspaceId: t }) {
1114
- const n = oe(), c = Se(), [o, s] = N(!1), [a, i] = N("bug"), [l, h] = N(""), [u, d] = N(!1), [b, f] = N(null), [k, v] = N(!1);
1115
- function A() {
1116
- s((y) => !y);
1117
- }
1153
+ ], Ot = 1500;
1154
+ function Wt({ workspaceId: t }) {
1155
+ const n = ce(), i = Ce(), [o, a] = _(!1), [s, l] = _("bug"), [c, h] = _(""), [u, d] = _(!1), [g, f] = _(null), [k, v] = _(!1);
1118
1156
  function $() {
1119
- i("bug"), h(""), f(null), v(!1);
1157
+ a((N) => !N);
1158
+ }
1159
+ function T() {
1160
+ l("bug"), h(""), f(null), v(!1);
1120
1161
  }
1121
- async function S() {
1162
+ async function A() {
1122
1163
  d(!0), f(null);
1123
1164
  try {
1124
- await n.submitFeedback({ type: a, body: l.trim() }, t), v(!0), h(""), setTimeout(() => {
1125
- s(!1), $();
1126
- }, Mt);
1127
- } catch (y) {
1128
- f(ct(y));
1165
+ await n.submitFeedback({ type: s, body: c.trim() }, t), v(!0), h(""), setTimeout(() => {
1166
+ a(!1), T();
1167
+ }, Ot);
1168
+ } catch (N) {
1169
+ f(ut(N));
1129
1170
  } finally {
1130
1171
  d(!1);
1131
1172
  }
@@ -1136,7 +1177,7 @@ function Lt({ workspaceId: t }) {
1136
1177
  {
1137
1178
  type: "button",
1138
1179
  className: "shepherd-feedback__trigger",
1139
- onClick: A,
1180
+ onClick: $,
1140
1181
  "aria-expanded": o,
1141
1182
  children: "Feedback"
1142
1183
  }
@@ -1145,36 +1186,36 @@ function Lt({ workspaceId: t }) {
1145
1186
  "section",
1146
1187
  {
1147
1188
  className: "shepherd-feedback__panel",
1148
- "aria-labelledby": c,
1189
+ "aria-labelledby": i,
1149
1190
  children: [
1150
- /* @__PURE__ */ r("h3", { id: c, children: "Give feedback" }),
1151
- k ? /* @__PURE__ */ r("p", { role: "status", children: "Thanks! Your feedback was sent." }) : /* @__PURE__ */ m(H, { children: [
1152
- /* @__PURE__ */ r("div", { className: "shepherd-feedback__types", children: xt.map((y) => /* @__PURE__ */ r(
1191
+ /* @__PURE__ */ r("h3", { id: i, children: "Give feedback" }),
1192
+ k ? /* @__PURE__ */ r("p", { role: "status", children: "Thanks! Your feedback was sent." }) : /* @__PURE__ */ m(q, { children: [
1193
+ /* @__PURE__ */ r("div", { className: "shepherd-feedback__types", children: Pt.map((N) => /* @__PURE__ */ r(
1153
1194
  "button",
1154
1195
  {
1155
1196
  type: "button",
1156
- "aria-pressed": a === y.id,
1157
- onClick: () => i(y.id),
1158
- children: y.label
1197
+ "aria-pressed": s === N.id,
1198
+ onClick: () => l(N.id),
1199
+ children: N.label
1159
1200
  },
1160
- y.id
1201
+ N.id
1161
1202
  )) }),
1162
1203
  /* @__PURE__ */ r(
1163
1204
  "textarea",
1164
1205
  {
1165
1206
  "aria-label": "Feedback",
1166
1207
  placeholder: "What's on your mind?",
1167
- value: l,
1168
- onChange: (y) => h(y.target.value)
1208
+ value: c,
1209
+ onChange: (N) => h(N.target.value)
1169
1210
  }
1170
1211
  ),
1171
- b && /* @__PURE__ */ r("p", { role: "alert", children: b }),
1212
+ g && /* @__PURE__ */ r("p", { role: "alert", children: g }),
1172
1213
  /* @__PURE__ */ r(
1173
1214
  "button",
1174
1215
  {
1175
1216
  type: "button",
1176
- onClick: () => void S(),
1177
- disabled: l.trim() === "" || u,
1217
+ onClick: () => void A(),
1218
+ disabled: c.trim() === "" || u,
1178
1219
  children: "Submit"
1179
1220
  }
1180
1221
  )
@@ -1184,7 +1225,7 @@ function Lt({ workspaceId: t }) {
1184
1225
  )
1185
1226
  ] });
1186
1227
  }
1187
- const we = "shepherd.tab", J = "shepherd.repo", Q = 10, Pt = {
1228
+ const Te = "shepherd.tab", Q = "shepherd.repo", ee = 10, Gt = {
1188
1229
  live: { text: "live", kind: "ok" },
1189
1230
  reconnecting: { text: "reconnecting…", kind: "warn" },
1190
1231
  // app.js cleared the token and re-prompted on 401; in the auth-agnostic port
@@ -1192,163 +1233,165 @@ const we = "shepherd.tab", J = "shepherd.repo", Q = 10, Pt = {
1192
1233
  // only surfaces the rejected state.
1193
1234
  unauthorized: { text: "token rejected", kind: "error" }
1194
1235
  };
1195
- function Ae(t) {
1236
+ function Se(t) {
1196
1237
  try {
1197
1238
  return localStorage.getItem(t);
1198
1239
  } catch {
1199
1240
  return null;
1200
1241
  }
1201
1242
  }
1202
- function ee(t, n) {
1243
+ function te(t, n) {
1203
1244
  try {
1204
1245
  localStorage.setItem(t, n);
1205
1246
  } catch {
1206
1247
  }
1207
1248
  }
1208
- function Ot(t, n, c) {
1209
- const o = Re(n.tasks);
1210
- let s = t;
1211
- if (s === null && o.length >= 2 && (s = fe(n.tasks)), s !== null && s !== "__all__" && !o.includes(s) && (s = "__all__"), c && s !== null && s !== "__all__") {
1212
- const a = n.tasks.some(
1213
- (l) => l.status === "active" && l.repo === s
1214
- ), i = n.tasks.some((l) => l.status === "active");
1215
- !a && i && (s = fe(n.tasks));
1249
+ function Ft(t, n, i) {
1250
+ const o = De(n.tasks);
1251
+ let a = t;
1252
+ if (a === null && o.length >= 2 && (a = ve(n.tasks)), a !== null && a !== "__all__" && !o.includes(a) && (a = "__all__"), i && a !== null && a !== "__all__") {
1253
+ const s = n.tasks.some(
1254
+ (c) => c.status === "active" && c.repo === a
1255
+ ), l = n.tasks.some((c) => c.status === "active");
1256
+ !s && l && (a = ve(n.tasks));
1216
1257
  }
1217
- return s;
1258
+ return a;
1218
1259
  }
1219
- function Gt(t) {
1220
- const n = {}, c = (o, s) => {
1221
- const a = n[o] ?? (n[o] = { active: 0, done: 0 });
1222
- a[s]++;
1260
+ function Ut(t) {
1261
+ const n = {}, i = (o, a) => {
1262
+ const s = n[o] ?? (n[o] = { active: 0, done: 0 });
1263
+ s[a]++;
1223
1264
  };
1224
1265
  for (const o of t.tasks) {
1225
- const s = o.status === "active" ? "active" : "done";
1226
- c(o.repo, s), c("__all__", s);
1266
+ const a = o.status === "active" ? "active" : "done";
1267
+ i(o.repo, a), i("__all__", a);
1227
1268
  }
1228
1269
  return n;
1229
1270
  }
1230
- function Kt({
1271
+ function Vt({
1231
1272
  workspaceId: t,
1232
1273
  config: n,
1233
- switcher: c,
1234
- hasWorkspace: o
1274
+ switcher: i,
1275
+ hasWorkspace: o,
1276
+ onLogout: a
1235
1277
  } = {}) {
1236
- const s = n != null, a = o === !1, { snapshot: i, status: l, lastUpdatedMs: h, refresh: u } = mt({
1278
+ const s = n != null, l = o === !1, { snapshot: c, status: h, lastUpdatedMs: u, refresh: d } = gt({
1237
1279
  workspaceId: t,
1238
1280
  // A no-workspace board has nothing to poll; keep it off the hub.
1239
- enabled: !a
1240
- }), [d, b] = N(() => {
1241
- if (s && a) return "config";
1242
- const g = Ae(we);
1243
- return g === "chat" ? "chat" : g === "config" && s ? "config" : "tasks";
1244
- }), f = s ? [
1281
+ enabled: !l
1282
+ }), [g, f] = _(() => {
1283
+ if (s && l) return "config";
1284
+ const b = Se(Te);
1285
+ return b === "chat" ? "chat" : b === "config" && s ? "config" : "tasks";
1286
+ }), k = s ? [
1245
1287
  { id: "tasks", label: "Tasks" },
1246
1288
  { id: "chat", label: "Chat" },
1247
1289
  { id: "config", label: "Config" }
1248
1290
  ] : [
1249
1291
  { id: "tasks", label: "Tasks" },
1250
1292
  { id: "chat", label: "Chat" }
1251
- ], k = P([]), v = R(
1252
- (g, M) => {
1253
- var de;
1254
- const O = f.length - 1;
1255
- let x = null;
1256
- switch (g.key) {
1293
+ ], v = P([]), $ = j(
1294
+ (b, x) => {
1295
+ var me;
1296
+ const W = k.length - 1;
1297
+ let I = null;
1298
+ switch (b.key) {
1257
1299
  case "ArrowRight":
1258
- x = M === O ? 0 : M + 1;
1300
+ I = x === W ? 0 : x + 1;
1259
1301
  break;
1260
1302
  case "ArrowLeft":
1261
- x = M === 0 ? O : M - 1;
1303
+ I = x === 0 ? W : x - 1;
1262
1304
  break;
1263
1305
  case "Home":
1264
- x = 0;
1306
+ I = 0;
1265
1307
  break;
1266
1308
  case "End":
1267
- x = O;
1309
+ I = W;
1268
1310
  break;
1269
1311
  default:
1270
1312
  return;
1271
1313
  }
1272
- g.preventDefault();
1273
- const le = f[x];
1274
- le && (T(le.id), (de = k.current[x]) == null || de.focus());
1314
+ b.preventDefault();
1315
+ const ue = k[I];
1316
+ ue && (O(ue.id), (me = v.current[I]) == null || me.focus());
1275
1317
  },
1276
1318
  // `tabs` is rebuilt each render but its identity only matters by length,
1277
1319
  // which is stable for a given `hasConfig`; `onTab` is stable.
1278
1320
  // eslint-disable-next-line react-hooks/exhaustive-deps
1279
1321
  [s]
1280
- ), [A, $] = N(
1281
- () => Ae(J)
1282
- ), [S, y] = N(Q), j = P(!0), T = R((g) => {
1283
- b(g), ee(we, g);
1284
- }, []), q = R((g) => {
1285
- const M = g === null ? "__all__" : g;
1286
- $(M), ee(J, M), y(Q);
1287
- }, []), G = R(() => {
1288
- y((g) => g + Q);
1289
- }, []), w = i ? Ot(A, i, j.current) : A;
1290
- se(() => {
1291
- i && (j.current = !1, w !== A && ($(w), w !== null && w !== "__all__" && ee(J, w)));
1292
- }, [i, w, A]);
1293
- const F = i ? Date.parse(i.serverTime) : Date.now(), X = i ? Re(i.tasks) : [], p = i ? Gt(i) : {}, _ = i ? i.agents.filter(
1294
- (g) => g.presence === "live" && L({ repo: g.repo ?? "" }, w)
1295
- ).length : 0, C = i ? i.tasks.filter((g) => g.status === "active" && L(g, w)).length : 0, D = Pt[l], I = h === null ? "" : `updated ${Math.floor((Date.now() - h) / 1e3)}s ago`, B = (i == null ? void 0 : i.agents) ?? [], W = (i == null ? void 0 : i.tasks) ?? [], De = (i == null ? void 0 : i.announcements) ?? [], Ie = W.filter(
1296
- (g) => g.status === "active" && L(g, w)
1297
- ).length, xe = W.filter(
1298
- (g) => g.status !== "active" && L(g, w)
1299
- ).length, ce = !a && d !== "config";
1322
+ ), [T, A] = _(
1323
+ () => Se(Q)
1324
+ ), [N, D] = _(ee), E = P(!0), O = j((b) => {
1325
+ f(b), te(Te, b);
1326
+ }, []), G = j((b) => {
1327
+ const x = b === null ? "__all__" : b;
1328
+ A(x), te(Q, x), D(ee);
1329
+ }, []), X = j(() => {
1330
+ D((b) => b + ee);
1331
+ }, []), w = c ? Ft(T, c, E.current) : T;
1332
+ ae(() => {
1333
+ c && (E.current = !1, w !== T && (A(w), w !== null && w !== "__all__" && te(Q, w)));
1334
+ }, [c, w, T]);
1335
+ const F = c ? Date.parse(c.serverTime) : Date.now(), p = c ? De(c.tasks) : [], y = c ? Ut(c) : {}, S = c ? c.agents.filter(
1336
+ (b) => b.presence === "live" && M({ repo: b.repo ?? "" }, w)
1337
+ ).length : 0, L = c ? c.tasks.filter((b) => b.status === "active" && M(b, w)).length : 0, R = Gt[h], Z = u === null ? "" : `updated ${Math.floor((Date.now() - u) / 1e3)}s ago`, le = (c == null ? void 0 : c.agents) ?? [], U = (c == null ? void 0 : c.tasks) ?? [], xe = (c == null ? void 0 : c.announcements) ?? [], Me = U.filter(
1338
+ (b) => b.status === "active" && M(b, w)
1339
+ ).length, Le = U.filter(
1340
+ (b) => b.status !== "active" && M(b, w)
1341
+ ).length, de = !l && g !== "config";
1300
1342
  return /* @__PURE__ */ m("div", { id: "board", children: [
1301
1343
  /* @__PURE__ */ m("header", { children: [
1302
1344
  /* @__PURE__ */ r("h1", { className: "brand", style: { margin: 0, font: "inherit" }, children: "Shepherd" }),
1303
- c,
1304
- ce && /* @__PURE__ */ m(H, { children: [
1345
+ i,
1346
+ de && /* @__PURE__ */ m(q, { children: [
1305
1347
  /* @__PURE__ */ r(
1306
- _t,
1348
+ At,
1307
1349
  {
1308
- repos: X,
1309
- counts: p,
1350
+ repos: p,
1351
+ counts: y,
1310
1352
  selected: w,
1311
- onSelect: q
1353
+ onSelect: G
1312
1354
  }
1313
1355
  ),
1314
1356
  /* @__PURE__ */ m("span", { className: "vitals", children: [
1315
- /* @__PURE__ */ r("b", { id: "vitals-online", children: _ }),
1357
+ /* @__PURE__ */ r("b", { id: "vitals-online", children: S }),
1316
1358
  " online · ",
1317
- /* @__PURE__ */ r("b", { id: "vitals-active", children: C }),
1359
+ /* @__PURE__ */ r("b", { id: "vitals-active", children: L }),
1318
1360
  " active"
1319
1361
  ] })
1320
1362
  ] }),
1321
1363
  /* @__PURE__ */ r("span", { className: "grow" }),
1322
- ce && /* @__PURE__ */ m(H, { children: [
1364
+ de && /* @__PURE__ */ m(q, { children: [
1323
1365
  /* @__PURE__ */ r(
1324
1366
  "span",
1325
1367
  {
1326
1368
  id: "status",
1327
- className: "status" + (D.kind ? ` status--${D.kind}` : ""),
1328
- children: D.text
1369
+ className: "status" + (R.kind ? ` status--${R.kind}` : ""),
1370
+ children: R.text
1329
1371
  }
1330
1372
  ),
1331
- /* @__PURE__ */ r("span", { id: "freshness", className: "freshness", children: I })
1373
+ /* @__PURE__ */ r("span", { id: "freshness", className: "freshness", children: Z })
1332
1374
  ] }),
1333
- /* @__PURE__ */ r("nav", { className: "tabs", role: "tablist", "aria-label": "Shepherd views", children: f.map(({ id: g, label: M }, O) => /* @__PURE__ */ r(
1375
+ a && /* @__PURE__ */ r("button", { type: "button", className: "header-signout", onClick: a, children: "Sign out" }),
1376
+ /* @__PURE__ */ r("nav", { className: "tabs", role: "tablist", "aria-label": "Shepherd views", children: k.map(({ id: b, label: x }, W) => /* @__PURE__ */ r(
1334
1377
  "button",
1335
1378
  {
1336
- ref: (x) => {
1337
- k.current[O] = x;
1379
+ ref: (I) => {
1380
+ v.current[W] = I;
1338
1381
  },
1339
- className: "tab" + (d === g ? " tab--active" : ""),
1340
- "data-tab": g,
1382
+ className: "tab" + (g === b ? " tab--active" : ""),
1383
+ "data-tab": b,
1341
1384
  type: "button",
1342
1385
  role: "tab",
1343
- id: `tab-${g}`,
1344
- "aria-controls": `panel-${g}`,
1345
- "aria-selected": d === g,
1346
- tabIndex: d === g ? 0 : -1,
1347
- onClick: () => T(g),
1348
- onKeyDown: (x) => v(x, O),
1349
- children: M
1386
+ id: `tab-${b}`,
1387
+ "aria-controls": `panel-${b}`,
1388
+ "aria-selected": g === b,
1389
+ tabIndex: g === b ? 0 : -1,
1390
+ onClick: () => O(b),
1391
+ onKeyDown: (I) => $(I, W),
1392
+ children: x
1350
1393
  },
1351
- g
1394
+ b
1352
1395
  )) })
1353
1396
  ] }),
1354
1397
  /* @__PURE__ */ r(
@@ -1357,31 +1400,31 @@ function Kt({
1357
1400
  id: "panel-tasks",
1358
1401
  role: "tabpanel",
1359
1402
  "aria-labelledby": "tab-tasks",
1360
- hidden: d !== "tasks",
1361
- children: a ? /* @__PURE__ */ r(Ne, { onGetStarted: () => T("config") }) : /* @__PURE__ */ m(H, { children: [
1362
- /* @__PURE__ */ r(Nt, { agents: B, tasks: W, selectedRepo: w }),
1403
+ hidden: g !== "tasks",
1404
+ children: l ? /* @__PURE__ */ r(Ae, { onGetStarted: () => O("config") }) : /* @__PURE__ */ m(q, { children: [
1405
+ /* @__PURE__ */ r(Tt, { agents: le, tasks: U, selectedRepo: w }),
1363
1406
  /* @__PURE__ */ m("div", { className: "board", children: [
1364
1407
  /* @__PURE__ */ m("div", { className: "col", children: [
1365
1408
  /* @__PURE__ */ m("div", { className: "colhead", children: [
1366
1409
  /* @__PURE__ */ r("h2", { children: "Active" }),
1367
- /* @__PURE__ */ r("span", { className: "n", id: "active-count", children: Ie })
1410
+ /* @__PURE__ */ r("span", { className: "n", id: "active-count", children: Me })
1368
1411
  ] }),
1369
- /* @__PURE__ */ r(Tt, { tasks: W, nowMs: F, selectedRepo: w })
1412
+ /* @__PURE__ */ r(Et, { tasks: U, nowMs: F, selectedRepo: w })
1370
1413
  ] }),
1371
1414
  /* @__PURE__ */ r("div", { className: "board__rule" }),
1372
1415
  /* @__PURE__ */ m("div", { className: "col", children: [
1373
1416
  /* @__PURE__ */ m("div", { className: "colhead", children: [
1374
1417
  /* @__PURE__ */ r("h2", { children: "Done" }),
1375
- /* @__PURE__ */ r("span", { className: "n", id: "done-count", children: xe })
1418
+ /* @__PURE__ */ r("span", { className: "n", id: "done-count", children: Le })
1376
1419
  ] }),
1377
1420
  /* @__PURE__ */ r(
1378
- Et,
1421
+ Dt,
1379
1422
  {
1380
- tasks: W,
1423
+ tasks: U,
1381
1424
  nowMs: F,
1382
1425
  selectedRepo: w,
1383
- doneShown: S,
1384
- onLoadMore: G
1426
+ doneShown: N,
1427
+ onLoadMore: X
1385
1428
  }
1386
1429
  )
1387
1430
  ] })
@@ -1395,16 +1438,16 @@ function Kt({
1395
1438
  id: "panel-chat",
1396
1439
  role: "tabpanel",
1397
1440
  "aria-labelledby": "tab-chat",
1398
- hidden: d !== "chat",
1399
- children: a ? /* @__PURE__ */ r(Ne, { onGetStarted: () => T("config") }) : /* @__PURE__ */ m("div", { className: "chat-wrap", children: [
1400
- /* @__PURE__ */ r(jt, { announcements: De, selectedRepo: w, nowMs: F }),
1441
+ hidden: g !== "chat",
1442
+ children: l ? /* @__PURE__ */ r(Ae, { onGetStarted: () => O("config") }) : /* @__PURE__ */ m("div", { className: "chat-wrap", children: [
1443
+ /* @__PURE__ */ r(xt, { announcements: xe, selectedRepo: w, nowMs: F }),
1401
1444
  /* @__PURE__ */ r(
1402
- It,
1445
+ Lt,
1403
1446
  {
1404
- agents: B,
1447
+ agents: le,
1405
1448
  selectedRepo: w,
1406
1449
  workspaceId: t,
1407
- onSent: u
1450
+ onSent: d
1408
1451
  }
1409
1452
  )
1410
1453
  ] })
@@ -1416,20 +1459,20 @@ function Kt({
1416
1459
  id: "panel-config",
1417
1460
  role: "tabpanel",
1418
1461
  "aria-labelledby": "tab-config",
1419
- hidden: d !== "config",
1462
+ hidden: g !== "config",
1420
1463
  children: n
1421
1464
  }
1422
1465
  ),
1423
- /* @__PURE__ */ r(Lt, { workspaceId: t })
1466
+ /* @__PURE__ */ r(Wt, { workspaceId: t })
1424
1467
  ] });
1425
1468
  }
1426
1469
  export {
1427
- Kt as D,
1428
- Ne as E,
1429
- U as S,
1430
- Bt as a,
1431
- qt as c,
1432
- ct as d,
1470
+ Vt as D,
1471
+ Ae as E,
1472
+ H as S,
1473
+ Yt as a,
1474
+ zt as c,
1475
+ ut as d,
1433
1476
  K as f,
1434
- oe as u
1477
+ ce as u
1435
1478
  };