@korso/shepherd-ui 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -47
- package/dist/ShepherdRoot.js +15 -57
- package/dist/components/Dashboard.d.ts +16 -2
- package/dist/components/Dashboard.js +76 -5
- package/dist/config/ConnectAgent.js +4 -4
- package/dist/config/EmptyState.js +5 -1
- package/dist/config/Members.js +4 -4
- package/dist/config/Workspaces.js +1 -1
- package/dist/lib/{Dashboard-CG6KeFQ3.js → Dashboard-B7nioe5N.js} +529 -457
- package/dist/lib/index.d.ts +15 -1
- package/dist/lib/index.js +300 -359
- package/dist/lib/selfhost.js +1 -1
- package/dist/lib/styles.css +252 -209
- package/dist/selfhost/assets/index-COMbJ-a4.js +40 -0
- package/dist/selfhost/assets/index-CcGvL65Q.css +1 -0
- package/dist/selfhost/index.html +13 -13
- package/dist/useLandscapePolling.d.ts +7 -0
- package/dist/useLandscapePolling.js +6 -1
- package/package.json +67 -67
- package/dist/ShepherdProvider.d.ts +0 -12
- package/dist/ShepherdProvider.js +0 -33
- package/dist/ShepherdProvider.test.d.ts +0 -1
- package/dist/ShepherdProvider.test.js +0 -47
- package/dist/ShepherdRoot.routing.test.d.ts +0 -1
- package/dist/ShepherdRoot.routing.test.js +0 -61
- package/dist/ShepherdRoot.test.d.ts +0 -1
- package/dist/ShepherdRoot.test.js +0 -37
- package/dist/app/assets/index-CDOCIg6s.js +0 -11
- package/dist/app/index.html +0 -12
- package/dist/client.test.d.ts +0 -1
- package/dist/client.test.js +0 -298
- package/dist/config/ConnectAgent.test.d.ts +0 -1
- package/dist/config/ConnectAgent.test.js +0 -92
- package/dist/config/EmptyState.test.d.ts +0 -1
- package/dist/config/EmptyState.test.js +0 -32
- package/dist/config/Members.test.d.ts +0 -1
- package/dist/config/Members.test.js +0 -66
- package/dist/config/Workspaces.test.d.ts +0 -1
- package/dist/config/Workspaces.test.js +0 -90
- package/dist/index.cjs +0 -5289
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -149
- package/dist/index.js.map +0 -1
- package/dist/selfhost/assets/index-BZmImfYZ.css +0 -1
- package/dist/selfhost/assets/index-CS268KSw.js +0 -40
- package/dist/test/setup.d.ts +0 -1
- package/dist/test/setup.js +0 -2
- package/dist/views/Chat.d.ts +0 -5
- package/dist/views/Chat.js +0 -60
- package/dist/views/Chat.test.d.ts +0 -1
- package/dist/views/Chat.test.js +0 -92
- package/dist/views/Config.d.ts +0 -12
- package/dist/views/Config.js +0 -6
- package/dist/views/Tasks.d.ts +0 -5
- package/dist/views/Tasks.js +0 -75
- package/dist/views/Tasks.test.d.ts +0 -1
- package/dist/views/Tasks.test.js +0 -115
- package/dist/views/useLandscape.d.ts +0 -14
- package/dist/views/useLandscape.js +0 -74
- package/dist/views/useLandscape.test.d.ts +0 -1
- package/dist/views/useLandscape.test.js +0 -101
- package/dist/views/wallboard.d.ts +0 -46
- package/dist/views/wallboard.js +0 -209
- package/dist/views/wallboard.test.d.ts +0 -1
- package/dist/views/wallboard.test.js +0 -143
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { jsx as o, jsxs as m, Fragment as
|
|
5
|
-
import { createContext as
|
|
1
|
+
var De = Object.defineProperty;
|
|
2
|
+
var je = (t, n, i) => n in t ? De(t, n, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[n] = i;
|
|
3
|
+
var le = (t, n, i) => je(t, typeof n != "symbol" ? n + "" : n, i);
|
|
4
|
+
import { jsx as o, jsxs as m, Fragment as F } from "react/jsx-runtime";
|
|
5
|
+
import { createContext as Ie, useContext as xe, useState as A, useRef as P, useCallback as R, useEffect as ne, Fragment as Le, useLayoutEffect as Me, useId as Pe } from "react";
|
|
6
6
|
import { z as e } from "zod";
|
|
7
|
-
const
|
|
7
|
+
const C = e.string(), z = e.number(), Ge = e.object({
|
|
8
8
|
agentName: e.string(),
|
|
9
9
|
human: e.string(),
|
|
10
10
|
branch: e.string(),
|
|
@@ -13,9 +13,9 @@ const A = e.string(), H = e.number(), Te = e.object({
|
|
|
13
13
|
message: e.string().nullable(),
|
|
14
14
|
paths: e.array(e.string()).min(1),
|
|
15
15
|
authorIsLive: e.boolean(),
|
|
16
|
-
authorLastActiveAt:
|
|
17
|
-
updatedAt:
|
|
18
|
-
}),
|
|
16
|
+
authorLastActiveAt: C,
|
|
17
|
+
updatedAt: C
|
|
18
|
+
}), Oe = 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 A = e.string(), H = e.number(), Te = 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
|
-
}),
|
|
30
|
+
}), se = e.object({
|
|
31
31
|
branch: e.string(),
|
|
32
32
|
baseBranch: e.string(),
|
|
33
33
|
head: e.string(),
|
|
@@ -36,36 +36,36 @@ const A = e.string(), H = e.number(), Te = 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(
|
|
40
|
-
}),
|
|
39
|
+
entries: e.array(Oe).max(600)
|
|
40
|
+
}), X = 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:
|
|
48
|
-
}),
|
|
47
|
+
expiresAt: C
|
|
48
|
+
}), B = e.object({
|
|
49
49
|
// bigint PK serialised as number; see DbId note above
|
|
50
|
-
id:
|
|
50
|
+
id: z,
|
|
51
51
|
fromAgentName: e.string(),
|
|
52
52
|
fromHuman: e.string().min(1),
|
|
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:
|
|
57
|
-
}),
|
|
58
|
-
conflicts: e.array(
|
|
59
|
-
activeClaims: e.array(
|
|
56
|
+
createdAt: C
|
|
57
|
+
}), Ne = e.object({
|
|
58
|
+
conflicts: e.array(X),
|
|
59
|
+
activeClaims: e.array(X),
|
|
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(
|
|
65
|
-
announcements: e.array(
|
|
64
|
+
yourClaims: e.array(X).default([]),
|
|
65
|
+
announcements: e.array(B),
|
|
66
66
|
// Per-agent change records for the workspace. Defaulted for version-skew safety.
|
|
67
|
-
changeRecords: e.array(
|
|
68
|
-
}),
|
|
67
|
+
changeRecords: e.array(Ge).default([])
|
|
68
|
+
}), Ue = e.object({
|
|
69
69
|
name: e.string(),
|
|
70
70
|
human: e.string(),
|
|
71
71
|
program: e.string(),
|
|
@@ -75,19 +75,19 @@ const A = e.string(), H = e.number(), Te = 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:
|
|
78
|
+
lastHeartbeatAt: C.nullable(),
|
|
79
79
|
presence: e.enum(["live", "offline"])
|
|
80
|
-
}),
|
|
80
|
+
}), He = e.enum(["active", "done", "dropped"]), We = 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:
|
|
88
|
-
createdAt:
|
|
89
|
-
endedAt:
|
|
90
|
-
}),
|
|
87
|
+
status: He,
|
|
88
|
+
createdAt: C,
|
|
89
|
+
endedAt: C.nullable()
|
|
90
|
+
}), Fe = e.object({
|
|
91
91
|
fromAgentName: e.string(),
|
|
92
92
|
fromHuman: e.string(),
|
|
93
93
|
body: e.string(),
|
|
@@ -101,14 +101,14 @@ const A = e.string(), H = e.number(), Te = e.object({
|
|
|
101
101
|
// fromAdmin). The dashboard renders these as "<agent> → admin". Not delivered
|
|
102
102
|
// to other agents. Defaulted for version-skew safety with older hubs.
|
|
103
103
|
toAdmin: e.boolean().default(!1),
|
|
104
|
-
createdAt:
|
|
105
|
-
}),
|
|
106
|
-
agents: e.array(
|
|
107
|
-
tasks: e.array(
|
|
108
|
-
announcements: e.array(
|
|
104
|
+
createdAt: C
|
|
105
|
+
}), de = e.object({
|
|
106
|
+
agents: e.array(Ue),
|
|
107
|
+
tasks: e.array(We),
|
|
108
|
+
announcements: e.array(Fe),
|
|
109
109
|
// The server's clock, so the client computes "expires in / last seen" against
|
|
110
110
|
// the hub rather than the (possibly skewed) browser clock.
|
|
111
|
-
serverTime:
|
|
111
|
+
serverTime: C
|
|
112
112
|
});
|
|
113
113
|
e.object({
|
|
114
114
|
body: e.string().min(1).max(8192),
|
|
@@ -120,11 +120,11 @@ e.object({
|
|
|
120
120
|
// Ignored for a DM (the target's own repo is used).
|
|
121
121
|
repo: e.string().min(1).nullable().optional()
|
|
122
122
|
});
|
|
123
|
-
const
|
|
123
|
+
const ue = e.object({
|
|
124
124
|
ok: e.literal(!0),
|
|
125
125
|
// One id per inserted row: a single id for a DM or repo-scoped broadcast, or
|
|
126
126
|
// several when an all-repos broadcast fans out across repos.
|
|
127
|
-
announcementIds: e.array(
|
|
127
|
+
announcementIds: e.array(z)
|
|
128
128
|
});
|
|
129
129
|
e.object({
|
|
130
130
|
workspace: e.string().min(1),
|
|
@@ -138,18 +138,18 @@ e.object({
|
|
|
138
138
|
agentName: e.string(),
|
|
139
139
|
sessionId: e.string().uuid()
|
|
140
140
|
});
|
|
141
|
-
const
|
|
141
|
+
const qe = e.object({
|
|
142
142
|
sessionId: e.string().uuid(),
|
|
143
143
|
intent: e.string().min(1).max(2048),
|
|
144
144
|
pathGlobs: e.array(e.string().min(1).max(512)).min(1).max(64),
|
|
145
145
|
ttlSeconds: e.number().int().positive().optional(),
|
|
146
|
-
changeReport:
|
|
146
|
+
changeReport: se.optional()
|
|
147
147
|
});
|
|
148
148
|
e.object({
|
|
149
149
|
workItemId: e.string().uuid(),
|
|
150
|
-
landscape:
|
|
150
|
+
landscape: Ne
|
|
151
151
|
});
|
|
152
|
-
const
|
|
152
|
+
const Ke = e.object({
|
|
153
153
|
sessionId: e.string().uuid(),
|
|
154
154
|
workItemId: e.string().uuid()
|
|
155
155
|
});
|
|
@@ -158,9 +158,9 @@ e.object({
|
|
|
158
158
|
// Pending announcements for the caller, delivered as a side effect of done so
|
|
159
159
|
// a message lands the moment a teammate finishes a unit of work (not only on
|
|
160
160
|
// their next work/sync). Defaulted for version-skew safety with older hubs.
|
|
161
|
-
announcements: e.array(
|
|
161
|
+
announcements: e.array(B).default([])
|
|
162
162
|
});
|
|
163
|
-
const
|
|
163
|
+
const ze = e.object({
|
|
164
164
|
sessionId: e.string().uuid(),
|
|
165
165
|
body: e.string().min(1).max(8192),
|
|
166
166
|
// absent or null => broadcast to all agents in the workspace
|
|
@@ -175,22 +175,22 @@ const xe = e.object({
|
|
|
175
175
|
e.object({
|
|
176
176
|
ok: e.literal(!0),
|
|
177
177
|
// bigint PK serialised as number; see DbId note above
|
|
178
|
-
announcementId:
|
|
178
|
+
announcementId: z,
|
|
179
179
|
// Pending announcements for the caller, delivered as a side effect of announce
|
|
180
180
|
// (a turn where the agent is already reading hub output) so inbound messages
|
|
181
181
|
// surface promptly. Excludes the just-sent one. Defaulted for version skew.
|
|
182
|
-
announcements: e.array(
|
|
182
|
+
announcements: e.array(B).default([])
|
|
183
183
|
});
|
|
184
184
|
e.object({
|
|
185
185
|
sessionId: e.string().uuid(),
|
|
186
|
-
changeReport:
|
|
186
|
+
changeReport: se.optional()
|
|
187
187
|
});
|
|
188
188
|
e.object({
|
|
189
|
-
landscape:
|
|
189
|
+
landscape: Ne
|
|
190
190
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
qe.omit({ sessionId: !0, changeReport: !0 });
|
|
192
|
+
ze.omit({ sessionId: !0 });
|
|
193
|
+
Ke.omit({ sessionId: !0 });
|
|
194
194
|
e.object({});
|
|
195
195
|
e.object({});
|
|
196
196
|
e.object({
|
|
@@ -199,7 +199,7 @@ e.object({
|
|
|
199
199
|
// change records fresh (commits surface within ~one heartbeat interval, not
|
|
200
200
|
// only when it next calls work/sync). Processed presence-style: it refreshes
|
|
201
201
|
// change records but, like the rest of heartbeat, does NOT renew claim TTLs.
|
|
202
|
-
changeReport:
|
|
202
|
+
changeReport: se.optional(),
|
|
203
203
|
// Opt-in: when set, the heartbeat returns any pending announcements for the
|
|
204
204
|
// caller in the response. Delivery is now TWO-PHASE and crash-safe: this fetch
|
|
205
205
|
// phase does NOT mark them delivered — the client persists them to its
|
|
@@ -215,14 +215,14 @@ e.object({
|
|
|
215
215
|
// guarantees a message is never recorded delivered before the client holds it
|
|
216
216
|
// (a lost response or a failed local append simply leaves it pending for the
|
|
217
217
|
// next beat). Absent on a plain presence/fetch beat.
|
|
218
|
-
ackAnnouncementIds: e.array(
|
|
218
|
+
ackAnnouncementIds: e.array(z).optional()
|
|
219
219
|
});
|
|
220
220
|
e.object({
|
|
221
221
|
ok: e.literal(!0),
|
|
222
222
|
// Pending announcements for the caller, delivered only when the request set
|
|
223
223
|
// `deliverAnnouncements`. Defaulted to [] for version-skew safety with older
|
|
224
224
|
// hubs (which return just { ok: true }).
|
|
225
|
-
announcements: e.array(
|
|
225
|
+
announcements: e.array(B).default([])
|
|
226
226
|
});
|
|
227
227
|
e.object({
|
|
228
228
|
sessionId: e.string().uuid()
|
|
@@ -230,58 +230,58 @@ e.object({
|
|
|
230
230
|
e.object({
|
|
231
231
|
ok: e.literal(!0)
|
|
232
232
|
});
|
|
233
|
-
const
|
|
233
|
+
const ke = e.enum(["admin", "member"]), ae = e.object({
|
|
234
234
|
id: e.string(),
|
|
235
235
|
slug: e.string(),
|
|
236
236
|
name: e.string(),
|
|
237
|
-
role:
|
|
237
|
+
role: ke
|
|
238
238
|
});
|
|
239
239
|
e.object({
|
|
240
240
|
name: e.string().min(1)
|
|
241
241
|
});
|
|
242
|
-
const
|
|
243
|
-
workspaces: e.array(
|
|
242
|
+
const Be = ae, Ye = e.object({
|
|
243
|
+
workspaces: e.array(ae)
|
|
244
244
|
});
|
|
245
245
|
e.object({
|
|
246
246
|
name: e.string().min(1).optional()
|
|
247
247
|
});
|
|
248
|
-
const
|
|
248
|
+
const Ve = e.object({
|
|
249
249
|
// The raw shp_ token, shown once at creation and never returned again.
|
|
250
250
|
token: e.string(),
|
|
251
251
|
id: e.string()
|
|
252
|
-
}),
|
|
252
|
+
}), Xe = e.object({
|
|
253
253
|
id: e.string(),
|
|
254
254
|
name: e.string().nullable(),
|
|
255
255
|
// ISO timestamp string (see IsoTimestamp note above) or null when unused / not revoked.
|
|
256
|
-
lastUsedAt:
|
|
257
|
-
createdAt:
|
|
258
|
-
revokedAt:
|
|
259
|
-
}),
|
|
260
|
-
tokens: e.array(
|
|
256
|
+
lastUsedAt: C.nullable(),
|
|
257
|
+
createdAt: C,
|
|
258
|
+
revokedAt: C.nullable()
|
|
259
|
+
}), Ze = e.object({
|
|
260
|
+
tokens: e.array(Xe)
|
|
261
261
|
});
|
|
262
262
|
e.object({
|
|
263
263
|
expiresInDays: e.number().int().positive().optional(),
|
|
264
264
|
maxUses: e.number().int().positive().optional()
|
|
265
265
|
});
|
|
266
|
-
const
|
|
266
|
+
const Je = e.object({
|
|
267
267
|
code: e.string(),
|
|
268
268
|
// ISO timestamp string, or null when the invite never expires.
|
|
269
|
-
expiresAt:
|
|
269
|
+
expiresAt: C.nullable(),
|
|
270
270
|
maxUses: e.number().int().positive(),
|
|
271
271
|
useCount: e.number().int().nonnegative()
|
|
272
|
-
}),
|
|
272
|
+
}), Qe = e.object({
|
|
273
273
|
// The workspace the caller just joined.
|
|
274
|
-
workspace:
|
|
275
|
-
}),
|
|
274
|
+
workspace: ae
|
|
275
|
+
}), et = e.object({
|
|
276
276
|
accountId: e.string(),
|
|
277
277
|
displayName: e.string().nullable(),
|
|
278
278
|
githubLogin: e.string().nullable(),
|
|
279
279
|
avatarUrl: e.string().nullable(),
|
|
280
|
-
role:
|
|
281
|
-
}),
|
|
282
|
-
members: e.array(
|
|
283
|
-
}),
|
|
284
|
-
class
|
|
280
|
+
role: ke
|
|
281
|
+
}), tt = e.object({
|
|
282
|
+
members: e.array(et)
|
|
283
|
+
}), nt = 5e3;
|
|
284
|
+
class H extends Error {
|
|
285
285
|
/**
|
|
286
286
|
* @param message - Human-readable failure description.
|
|
287
287
|
* @param status - Upstream HTTP status, omitted for network/abort failures.
|
|
@@ -289,50 +289,50 @@ class P extends Error {
|
|
|
289
289
|
constructor(i, r) {
|
|
290
290
|
super(i);
|
|
291
291
|
/** Upstream HTTP status for a non-2xx response; absent for transport errors. */
|
|
292
|
-
|
|
292
|
+
le(this, "status");
|
|
293
293
|
this.name = "ShepherdClientError", r !== void 0 && (this.status = r);
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
|
-
function
|
|
297
|
-
return
|
|
296
|
+
function Lt(t) {
|
|
297
|
+
return t instanceof Error ? t.message : "Something went wrong.";
|
|
298
298
|
}
|
|
299
|
-
async function
|
|
299
|
+
async function st(t) {
|
|
300
300
|
try {
|
|
301
|
-
const
|
|
302
|
-
if (
|
|
303
|
-
return
|
|
301
|
+
const n = await t.json();
|
|
302
|
+
if (n !== null && typeof n == "object" && "error" in n && typeof n.error == "string")
|
|
303
|
+
return n.error;
|
|
304
304
|
} catch {
|
|
305
305
|
}
|
|
306
306
|
return "";
|
|
307
307
|
}
|
|
308
|
-
function
|
|
309
|
-
const
|
|
308
|
+
function Mt(t) {
|
|
309
|
+
const n = t.baseUrl.replace(/\/$/, ""), i = t.timeoutMs ?? nt, r = encodeURIComponent;
|
|
310
310
|
async function a(s, l, c = {}) {
|
|
311
|
-
var
|
|
311
|
+
var b, N;
|
|
312
312
|
const p = new AbortController(), u = setTimeout(() => p.abort(), i);
|
|
313
313
|
let d;
|
|
314
314
|
try {
|
|
315
|
-
const
|
|
315
|
+
const v = {
|
|
316
316
|
"Content-Type": "application/json"
|
|
317
|
-
},
|
|
317
|
+
}, S = await ((b = t.getAuthHeader) == null ? void 0 : b.call(t)), w = {
|
|
318
318
|
method: s,
|
|
319
|
-
headers: { ...
|
|
319
|
+
headers: { ...v, ...typeof S == "string" ? { Authorization: S } : S ?? {} },
|
|
320
320
|
signal: p.signal
|
|
321
321
|
};
|
|
322
|
-
c.body !== void 0 && (
|
|
323
|
-
} catch (
|
|
324
|
-
throw new
|
|
325
|
-
|
|
322
|
+
c.body !== void 0 && (w.body = JSON.stringify(c.body)), d = await fetch(`${n}${l}`, w);
|
|
323
|
+
} catch (v) {
|
|
324
|
+
throw new H(
|
|
325
|
+
v instanceof Error ? v.message : String(v)
|
|
326
326
|
);
|
|
327
327
|
} finally {
|
|
328
328
|
clearTimeout(u);
|
|
329
329
|
}
|
|
330
330
|
if (d.status === 401)
|
|
331
|
-
throw (N =
|
|
331
|
+
throw (N = t.onUnauthorized) == null || N.call(t), new H("Unauthorized", 401);
|
|
332
332
|
if (!d.ok) {
|
|
333
|
-
const
|
|
334
|
-
throw new
|
|
335
|
-
|
|
333
|
+
const v = await st(d);
|
|
334
|
+
throw new H(
|
|
335
|
+
v !== "" ? `HTTP ${d.status}: ${v}` : `HTTP ${d.status}`,
|
|
336
336
|
d.status
|
|
337
337
|
);
|
|
338
338
|
}
|
|
@@ -343,34 +343,34 @@ function At(n) {
|
|
|
343
343
|
}
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
|
-
const
|
|
347
|
-
if (!
|
|
348
|
-
throw new
|
|
349
|
-
return
|
|
346
|
+
const f = c.schema.safeParse(await d.json());
|
|
347
|
+
if (!f.success)
|
|
348
|
+
throw new H("Invalid response schema");
|
|
349
|
+
return f.data;
|
|
350
350
|
}
|
|
351
351
|
return {
|
|
352
|
-
baseUrl:
|
|
352
|
+
baseUrl: n,
|
|
353
353
|
// --- multi-workspace management surface ---------------------------------
|
|
354
354
|
listWorkspaces() {
|
|
355
355
|
return a("GET", "/workspaces", {
|
|
356
|
-
schema:
|
|
356
|
+
schema: Ye
|
|
357
357
|
});
|
|
358
358
|
},
|
|
359
359
|
createWorkspace(s) {
|
|
360
360
|
return a("POST", "/workspaces", {
|
|
361
361
|
body: s,
|
|
362
|
-
schema:
|
|
362
|
+
schema: Be
|
|
363
363
|
});
|
|
364
364
|
},
|
|
365
365
|
mintToken(s, l) {
|
|
366
366
|
return a("POST", `/workspaces/${r(s)}/tokens`, {
|
|
367
367
|
body: l,
|
|
368
|
-
schema:
|
|
368
|
+
schema: Ve
|
|
369
369
|
});
|
|
370
370
|
},
|
|
371
371
|
listTokens(s) {
|
|
372
372
|
return a("GET", `/workspaces/${r(s)}/tokens`, {
|
|
373
|
-
schema:
|
|
373
|
+
schema: Ze
|
|
374
374
|
});
|
|
375
375
|
},
|
|
376
376
|
revokeToken(s, l) {
|
|
@@ -382,7 +382,7 @@ function At(n) {
|
|
|
382
382
|
createInvite(s, l) {
|
|
383
383
|
return a("POST", `/workspaces/${r(s)}/invites`, {
|
|
384
384
|
body: l,
|
|
385
|
-
schema:
|
|
385
|
+
schema: Je
|
|
386
386
|
});
|
|
387
387
|
},
|
|
388
388
|
revokeInvite(s, l) {
|
|
@@ -393,12 +393,12 @@ function At(n) {
|
|
|
393
393
|
},
|
|
394
394
|
redeemInvite(s) {
|
|
395
395
|
return a("POST", `/invites/${r(s)}/redeem`, {
|
|
396
|
-
schema:
|
|
396
|
+
schema: Qe
|
|
397
397
|
});
|
|
398
398
|
},
|
|
399
399
|
listMembers(s) {
|
|
400
400
|
return a("GET", `/workspaces/${r(s)}/members`, {
|
|
401
|
-
schema:
|
|
401
|
+
schema: tt
|
|
402
402
|
});
|
|
403
403
|
},
|
|
404
404
|
removeMember(s, l) {
|
|
@@ -412,82 +412,83 @@ function At(n) {
|
|
|
412
412
|
},
|
|
413
413
|
landscape(s) {
|
|
414
414
|
return a("GET", `/workspaces/${r(s)}/landscape`, {
|
|
415
|
-
schema:
|
|
415
|
+
schema: de
|
|
416
416
|
});
|
|
417
417
|
},
|
|
418
418
|
announceTo(s, l) {
|
|
419
419
|
return a("POST", `/workspaces/${r(s)}/announce`, {
|
|
420
420
|
body: l,
|
|
421
|
-
schema:
|
|
421
|
+
schema: ue
|
|
422
422
|
});
|
|
423
423
|
},
|
|
424
424
|
// --- self-host singular aliases (implicit single workspace) -------------
|
|
425
425
|
getLandscape() {
|
|
426
426
|
return a("GET", "/workspace/landscape", {
|
|
427
|
-
schema:
|
|
427
|
+
schema: de
|
|
428
428
|
});
|
|
429
429
|
},
|
|
430
430
|
announce(s) {
|
|
431
431
|
return a("POST", "/workspace/announce", {
|
|
432
432
|
body: s,
|
|
433
|
-
schema:
|
|
433
|
+
schema: ue
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
|
-
const
|
|
439
|
-
function
|
|
440
|
-
client:
|
|
441
|
-
children:
|
|
438
|
+
const we = Ie(null);
|
|
439
|
+
function Pt({
|
|
440
|
+
client: t,
|
|
441
|
+
children: n
|
|
442
442
|
}) {
|
|
443
|
-
return /* @__PURE__ */ o(
|
|
443
|
+
return /* @__PURE__ */ o(we.Provider, { value: t, children: n });
|
|
444
444
|
}
|
|
445
|
-
function
|
|
446
|
-
const
|
|
447
|
-
if (
|
|
445
|
+
function Ae() {
|
|
446
|
+
const t = xe(we);
|
|
447
|
+
if (t === null)
|
|
448
448
|
throw new Error(
|
|
449
449
|
"useShepherdClient must be used within <ShepherdClientProvider>"
|
|
450
450
|
);
|
|
451
|
-
return
|
|
451
|
+
return t;
|
|
452
452
|
}
|
|
453
|
-
const
|
|
454
|
-
function
|
|
455
|
-
const
|
|
453
|
+
const at = 5e3, rt = 1e3;
|
|
454
|
+
function ot(t) {
|
|
455
|
+
const n = Ae(), i = t == null ? void 0 : t.workspaceId, r = (t == null ? void 0 : t.pollMs) ?? at, a = (t == null ? void 0 : t.enabled) ?? !0, [s, l] = A(
|
|
456
456
|
null
|
|
457
|
-
), [
|
|
458
|
-
b.current =
|
|
459
|
-
const
|
|
460
|
-
async (
|
|
457
|
+
), [c, p] = A("live"), [u, d] = A(null), [, f] = A(0), b = P(n);
|
|
458
|
+
b.current = n;
|
|
459
|
+
const N = P(0), v = R(
|
|
460
|
+
async (E) => {
|
|
461
461
|
try {
|
|
462
462
|
const w = i ? await b.current.landscape(i) : await b.current.getLandscape();
|
|
463
|
-
if (
|
|
464
|
-
|
|
463
|
+
if (E !== N.current) return;
|
|
464
|
+
l(w), d(Date.now()), p("live");
|
|
465
465
|
} catch (w) {
|
|
466
|
-
if (
|
|
467
|
-
w instanceof
|
|
466
|
+
if (E !== N.current) return;
|
|
467
|
+
w instanceof H && w.status === 401 ? p("unauthorized") : p("reconnecting");
|
|
468
468
|
}
|
|
469
469
|
},
|
|
470
470
|
[i]
|
|
471
471
|
);
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
N
|
|
472
|
+
ne(() => {
|
|
473
|
+
if (!a) return;
|
|
474
|
+
const E = ++N.current;
|
|
475
|
+
v(E);
|
|
475
476
|
const w = setInterval(() => {
|
|
476
|
-
document.visibilityState !== "hidden" &&
|
|
477
|
-
}, r),
|
|
478
|
-
|
|
479
|
-
},
|
|
480
|
-
document.visibilityState === "visible" &&
|
|
477
|
+
document.visibilityState !== "hidden" && v(E);
|
|
478
|
+
}, r), I = setInterval(() => {
|
|
479
|
+
f(($) => $ + 1);
|
|
480
|
+
}, rt), T = () => {
|
|
481
|
+
document.visibilityState === "visible" && v(E);
|
|
481
482
|
};
|
|
482
|
-
return document.addEventListener("visibilitychange",
|
|
483
|
-
|
|
483
|
+
return document.addEventListener("visibilitychange", T), () => {
|
|
484
|
+
N.current++, clearInterval(w), clearInterval(I), document.removeEventListener("visibilitychange", T);
|
|
484
485
|
};
|
|
485
|
-
}, [
|
|
486
|
-
const
|
|
487
|
-
return { snapshot:
|
|
486
|
+
}, [v, r, a]);
|
|
487
|
+
const S = R(() => v(N.current), [v]);
|
|
488
|
+
return { snapshot: s, status: c, lastUpdatedMs: u, refresh: S };
|
|
488
489
|
}
|
|
489
|
-
function
|
|
490
|
-
const i = Math.floor((
|
|
490
|
+
function q(t, n) {
|
|
491
|
+
const i = Math.floor((n - Date.parse(t)) / 1e3);
|
|
491
492
|
if (i < 5) return "just now";
|
|
492
493
|
if (i < 60) return `${i}s ago`;
|
|
493
494
|
const r = Math.floor(i / 60);
|
|
@@ -495,66 +496,66 @@ function G(n, t) {
|
|
|
495
496
|
const a = Math.floor(r / 60);
|
|
496
497
|
return a < 24 ? `${a}h ago` : `${Math.floor(a / 24)}d ago`;
|
|
497
498
|
}
|
|
498
|
-
function
|
|
499
|
-
let
|
|
500
|
-
for (let i = 0; i <
|
|
501
|
-
return `hsl(${
|
|
499
|
+
function K(t) {
|
|
500
|
+
let n = 0;
|
|
501
|
+
for (let i = 0; i < t.length; i++) n = (n * 31 + t.charCodeAt(i)) % 360;
|
|
502
|
+
return `hsl(${n}, 38%, 42%)`;
|
|
502
503
|
}
|
|
503
|
-
function
|
|
504
|
-
if (!
|
|
505
|
-
const
|
|
506
|
-
return
|
|
504
|
+
function re(t) {
|
|
505
|
+
if (!t) return "?";
|
|
506
|
+
const n = t.match(/[A-Z]/g);
|
|
507
|
+
return n && n.length >= 2 ? n[0] + n[1] : t.slice(0, 2).toUpperCase();
|
|
507
508
|
}
|
|
508
|
-
const
|
|
509
|
-
function
|
|
510
|
-
const r =
|
|
509
|
+
const Se = "A-Za-z0-9_-";
|
|
510
|
+
function it(t, n) {
|
|
511
|
+
const r = t.slice(0, n).match(new RegExp(`(?:^|\\s)@([${Se}]*)$`));
|
|
511
512
|
if (!r) return null;
|
|
512
513
|
const a = r[1];
|
|
513
|
-
return { start:
|
|
514
|
+
return { start: n - a.length - 1, end: n, query: a };
|
|
514
515
|
}
|
|
515
|
-
function
|
|
516
|
-
const i = new RegExp(`(?:^|\\s)@([${
|
|
516
|
+
function ct(t, n) {
|
|
517
|
+
const i = new RegExp(`(?:^|\\s)@([${Se}]+)`, "g");
|
|
517
518
|
let r;
|
|
518
|
-
for (; (r = i.exec(
|
|
519
|
-
const a = r[1].toLowerCase(), s =
|
|
519
|
+
for (; (r = i.exec(t)) !== null; ) {
|
|
520
|
+
const a = r[1].toLowerCase(), s = n.find((l) => l.toLowerCase() === a);
|
|
520
521
|
if (s) return s;
|
|
521
522
|
}
|
|
522
523
|
return null;
|
|
523
524
|
}
|
|
524
|
-
function
|
|
525
|
-
return [...new Set(
|
|
525
|
+
function Te(t) {
|
|
526
|
+
return [...new Set(t.map((n) => n.repo))].sort();
|
|
526
527
|
}
|
|
527
|
-
function
|
|
528
|
-
return
|
|
528
|
+
function L(t, n) {
|
|
529
|
+
return n === null || n === "__all__" || t.repo === n;
|
|
529
530
|
}
|
|
530
|
-
function
|
|
531
|
+
function lt(t, n) {
|
|
531
532
|
return [
|
|
532
533
|
...new Set(
|
|
533
|
-
|
|
534
|
+
t.filter((i) => i.presence === "live" && L(i, n)).map((i) => i.name)
|
|
534
535
|
)
|
|
535
536
|
].sort();
|
|
536
537
|
}
|
|
537
|
-
function
|
|
538
|
-
const
|
|
539
|
-
return
|
|
538
|
+
function me(t) {
|
|
539
|
+
const n = t.find((i) => i.status === "active");
|
|
540
|
+
return n ? n.repo : t.length ? t[0].repo : null;
|
|
540
541
|
}
|
|
541
|
-
function
|
|
542
|
-
return
|
|
542
|
+
function dt(t) {
|
|
543
|
+
return t === "dropped" ? "dropped" : "done";
|
|
543
544
|
}
|
|
544
|
-
function
|
|
545
|
-
if (!
|
|
546
|
-
const i = Math.floor((Date.parse(
|
|
545
|
+
function he(t, n) {
|
|
546
|
+
if (!n) return "";
|
|
547
|
+
const i = Math.floor((Date.parse(n) - Date.parse(t)) / 1e3), r = Math.floor(i / 60);
|
|
547
548
|
return r < 60 ? `active ${r}m` : `active ${Math.floor(r / 60)}h`;
|
|
548
549
|
}
|
|
549
|
-
function
|
|
550
|
-
const i = new Date(Date.parse(
|
|
550
|
+
function ut(t, n) {
|
|
551
|
+
const i = new Date(Date.parse(t)), r = new Date(n), a = (l) => new Date(l.getFullYear(), l.getMonth(), l.getDate()).getTime(), s = Math.round((a(r) - a(i)) / 864e5);
|
|
551
552
|
return s <= 0 ? "Today" : s === 1 ? "Yesterday" : i.toLocaleDateString(void 0, { month: "short", day: "numeric" });
|
|
552
553
|
}
|
|
553
|
-
function
|
|
554
|
-
let
|
|
555
|
-
|
|
554
|
+
function pe(t) {
|
|
555
|
+
let n = t.toLowerCase().replace(/\\/g, "/");
|
|
556
|
+
n.endsWith("/") && (n = n.replace(/\/+$/, "") + "/**");
|
|
556
557
|
const i = [];
|
|
557
|
-
for (const r of
|
|
558
|
+
for (const r of n.split("/"))
|
|
558
559
|
if (!(r === "" || r === ".")) {
|
|
559
560
|
if (r === "..") {
|
|
560
561
|
i.length && i.pop();
|
|
@@ -564,43 +565,43 @@ function re(n) {
|
|
|
564
565
|
}
|
|
565
566
|
return i;
|
|
566
567
|
}
|
|
567
|
-
const
|
|
568
|
-
function
|
|
569
|
-
return
|
|
568
|
+
const ge = /[*?{}[\]]/;
|
|
569
|
+
function mt(t, n) {
|
|
570
|
+
return t === "*" ? !0 : (ge.test(t) || !ge.test(n)) && t === n;
|
|
570
571
|
}
|
|
571
|
-
function
|
|
572
|
+
function ht(t, n) {
|
|
572
573
|
const i = /* @__PURE__ */ new Map();
|
|
573
574
|
function r(a, s) {
|
|
574
|
-
if (
|
|
575
|
-
for (let
|
|
575
|
+
if (n.length - s === 0) {
|
|
576
|
+
for (let f = a; f < t.length; f++) if (t[f] !== "**") return !1;
|
|
576
577
|
return !0;
|
|
577
578
|
}
|
|
578
|
-
if (
|
|
579
|
-
const l = a * (
|
|
579
|
+
if (t.length - a === 0) return !1;
|
|
580
|
+
const l = a * (n.length + 1) + s, c = i.get(l);
|
|
580
581
|
if (c !== void 0) return c;
|
|
581
|
-
const p =
|
|
582
|
+
const p = t[a], u = n[s];
|
|
582
583
|
let d;
|
|
583
|
-
return p === "**" ? d = r(a + 1, s) || r(a, s + 1) : u === "**" ? d = !1 : d =
|
|
584
|
+
return p === "**" ? d = r(a + 1, s) || r(a, s + 1) : u === "**" ? d = !1 : d = mt(p, u) && r(a + 1, s + 1), i.set(l, d), d;
|
|
584
585
|
}
|
|
585
586
|
return r(0, 0);
|
|
586
587
|
}
|
|
587
|
-
function
|
|
588
|
-
if (
|
|
589
|
-
const i =
|
|
590
|
-
return
|
|
591
|
-
const a =
|
|
592
|
-
return i.some((s) =>
|
|
588
|
+
function fe(t, n) {
|
|
589
|
+
if (n.length === 0) return !0;
|
|
590
|
+
const i = t.map(pe);
|
|
591
|
+
return n.every((r) => {
|
|
592
|
+
const a = pe(r);
|
|
593
|
+
return i.some((s) => ht(s, a));
|
|
593
594
|
});
|
|
594
595
|
}
|
|
595
|
-
function
|
|
596
|
-
const
|
|
597
|
-
for (const a of
|
|
598
|
-
|
|
596
|
+
function pt(t) {
|
|
597
|
+
const n = /* @__PURE__ */ new Map();
|
|
598
|
+
for (const a of t)
|
|
599
|
+
n.has(a.agentName) || n.set(a.agentName, []), n.get(a.agentName).push(a);
|
|
599
600
|
const i = (a, s) => s.createdAt.localeCompare(a.createdAt), r = [];
|
|
600
|
-
for (const [a, s] of
|
|
601
|
+
for (const [a, s] of n) {
|
|
601
602
|
const l = [...s].sort(i), c = l.map(
|
|
602
603
|
(u) => l.some(
|
|
603
|
-
(d) => d !== u &&
|
|
604
|
+
(d) => d !== u && fe(d.pathGlobs, u.pathGlobs) && !fe(u.pathGlobs, d.pathGlobs)
|
|
604
605
|
)
|
|
605
606
|
), p = l[0];
|
|
606
607
|
r.push({
|
|
@@ -617,37 +618,37 @@ function nt(n) {
|
|
|
617
618
|
return s.primaries.concat(s.narrower)[0].createdAt.localeCompare(l);
|
|
618
619
|
}), r;
|
|
619
620
|
}
|
|
620
|
-
const
|
|
621
|
-
function
|
|
622
|
-
repos:
|
|
623
|
-
counts:
|
|
621
|
+
const be = { active: 0, done: 0 };
|
|
622
|
+
function gt({
|
|
623
|
+
repos: t,
|
|
624
|
+
counts: n,
|
|
624
625
|
selected: i,
|
|
625
626
|
onSelect: r
|
|
626
627
|
}) {
|
|
627
|
-
const [a, s] =
|
|
628
|
-
if (
|
|
629
|
-
var
|
|
628
|
+
const [a, s] = A(!1), l = P(null);
|
|
629
|
+
if (ne(() => {
|
|
630
|
+
var b;
|
|
630
631
|
if (!a) return;
|
|
631
|
-
const d = (
|
|
632
|
+
const d = (b = l.current) == null ? void 0 : b.querySelector(".repo-menu");
|
|
632
633
|
if (!d) return;
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
}, [a]),
|
|
636
|
-
const c = i === null || i === "__all__", p = c ? "All repos" : i, u = (d,
|
|
637
|
-
const
|
|
634
|
+
const f = d.querySelector('[aria-selected="true"]') ?? d.querySelector("button");
|
|
635
|
+
f == null || f.focus();
|
|
636
|
+
}, [a]), t.length < 2) return null;
|
|
637
|
+
const c = i === null || i === "__all__", p = c ? "All repos" : i, u = (d, f) => {
|
|
638
|
+
const b = d === null ? n.__all__ ?? be : n[d] ?? be, N = d === null ? c : i === d, v = "repo-mi" + (N ? " on" : "") + (d === null ? " all" : "");
|
|
638
639
|
return /* @__PURE__ */ m(
|
|
639
640
|
"button",
|
|
640
641
|
{
|
|
641
642
|
type: "button",
|
|
642
|
-
className:
|
|
643
|
+
className: v,
|
|
643
644
|
role: "option",
|
|
644
645
|
"aria-selected": N,
|
|
645
|
-
onClick: (
|
|
646
|
-
|
|
646
|
+
onClick: (S) => {
|
|
647
|
+
S.stopPropagation(), s(!1), r(d);
|
|
647
648
|
},
|
|
648
649
|
children: [
|
|
649
|
-
/* @__PURE__ */ o("span", { children:
|
|
650
|
-
/* @__PURE__ */ o("span", { className: "ct", children: `${
|
|
650
|
+
/* @__PURE__ */ o("span", { children: f }),
|
|
651
|
+
/* @__PURE__ */ o("span", { className: "ct", children: `${b.active} active · ${b.done} done` })
|
|
651
652
|
]
|
|
652
653
|
},
|
|
653
654
|
d ?? "__all__"
|
|
@@ -671,7 +672,7 @@ function st({
|
|
|
671
672
|
"aria-expanded": a,
|
|
672
673
|
"aria-label": `Filter by repo (current: ${p})`,
|
|
673
674
|
onClick: (d) => {
|
|
674
|
-
d.stopPropagation(), s((
|
|
675
|
+
d.stopPropagation(), s((f) => !f);
|
|
675
676
|
},
|
|
676
677
|
children: [
|
|
677
678
|
/* @__PURE__ */ o("span", { className: "slash", children: "/" }),
|
|
@@ -681,18 +682,18 @@ function st({
|
|
|
681
682
|
}
|
|
682
683
|
),
|
|
683
684
|
a && /* @__PURE__ */ m("div", { className: "repo-menu", role: "listbox", children: [
|
|
684
|
-
|
|
685
|
+
t.map((d) => u(d, d)),
|
|
685
686
|
u(null, "All repos")
|
|
686
687
|
] })
|
|
687
688
|
]
|
|
688
689
|
}
|
|
689
690
|
);
|
|
690
691
|
}
|
|
691
|
-
function
|
|
692
|
-
const r =
|
|
693
|
-
(c) => c.presence === "live" &&
|
|
692
|
+
function ft({ agents: t, tasks: n, selectedRepo: i }) {
|
|
693
|
+
const r = t.filter(
|
|
694
|
+
(c) => c.presence === "live" && L({ repo: c.repo ?? "" }, i)
|
|
694
695
|
), a = /* @__PURE__ */ new Set();
|
|
695
|
-
for (const c of
|
|
696
|
+
for (const c of n) c.status === "active" && a.add(c.agentName);
|
|
696
697
|
const s = (c) => a.has(c.name), l = [...r].sort((c, p) => {
|
|
697
698
|
const u = s(c), d = s(p);
|
|
698
699
|
return u !== d ? u ? -1 : 1 : c.name.localeCompare(p.name);
|
|
@@ -702,117 +703,117 @@ function at({ agents: n, tasks: t, selectedRepo: i }) {
|
|
|
702
703
|
{
|
|
703
704
|
className: "person" + (s(c) ? "" : " person--idle"),
|
|
704
705
|
children: [
|
|
705
|
-
/* @__PURE__ */ o("div", { className: "avatar", style: { background:
|
|
706
|
+
/* @__PURE__ */ o("div", { className: "avatar", style: { background: K(c.name) }, children: re(c.name) }),
|
|
706
707
|
/* @__PURE__ */ o("span", { className: "person__name", children: c.name })
|
|
707
708
|
]
|
|
708
709
|
},
|
|
709
710
|
c.name
|
|
710
711
|
)) });
|
|
711
712
|
}
|
|
712
|
-
function
|
|
713
|
-
return
|
|
713
|
+
function Ce({ globs: t }) {
|
|
714
|
+
return t.length <= 1 ? /* @__PURE__ */ m("div", { className: "terr", children: [
|
|
714
715
|
/* @__PURE__ */ o("span", { className: "terr__lbl", children: "territory" }),
|
|
715
|
-
|
|
716
|
+
t.map((n) => /* @__PURE__ */ o("span", { className: "glob", children: n }, n))
|
|
716
717
|
] }) : /* @__PURE__ */ m("details", { className: "terrx", children: [
|
|
717
718
|
/* @__PURE__ */ m("summary", { children: [
|
|
718
719
|
/* @__PURE__ */ o("span", { className: "terr__lbl", children: "territory" }),
|
|
719
720
|
/* @__PURE__ */ m("span", { className: "glob glob--more", children: [
|
|
720
721
|
/* @__PURE__ */ o("span", { className: "tw", children: "▶" }),
|
|
721
|
-
` ${
|
|
722
|
+
` ${t.length} paths`
|
|
722
723
|
] })
|
|
723
724
|
] }),
|
|
724
|
-
/* @__PURE__ */ o("div", { className: "terr terr--full", children:
|
|
725
|
+
/* @__PURE__ */ o("div", { className: "terr terr--full", children: t.map((n) => /* @__PURE__ */ o("span", { className: "glob", children: n }, n)) })
|
|
725
726
|
] });
|
|
726
727
|
}
|
|
727
|
-
const
|
|
728
|
-
function
|
|
729
|
-
task:
|
|
730
|
-
nowMs:
|
|
728
|
+
const ee = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, bt = (t) => t === null || t === "__all__";
|
|
729
|
+
function te({
|
|
730
|
+
task: t,
|
|
731
|
+
nowMs: n
|
|
731
732
|
}) {
|
|
732
|
-
return /* @__PURE__ */ m(
|
|
733
|
-
/* @__PURE__ */ o("div", { className: "task__intent", children:
|
|
734
|
-
/* @__PURE__ */ o(
|
|
735
|
-
/* @__PURE__ */ o("div", { className: "task__meta", children: `started ${
|
|
733
|
+
return /* @__PURE__ */ m(F, { children: [
|
|
734
|
+
/* @__PURE__ */ o("div", { className: "task__intent", children: t.intent }),
|
|
735
|
+
/* @__PURE__ */ o(Ce, { globs: t.pathGlobs }),
|
|
736
|
+
/* @__PURE__ */ o("div", { className: "task__meta", children: `started ${q(t.createdAt, n)}` })
|
|
736
737
|
] });
|
|
737
738
|
}
|
|
738
|
-
function
|
|
739
|
-
task:
|
|
740
|
-
nowMs:
|
|
739
|
+
function vt({
|
|
740
|
+
task: t,
|
|
741
|
+
nowMs: n,
|
|
741
742
|
allRepos: i
|
|
742
743
|
}) {
|
|
743
|
-
const r =
|
|
744
|
+
const r = t.model || t.program;
|
|
744
745
|
return /* @__PURE__ */ m("div", { className: "task", children: [
|
|
745
746
|
/* @__PURE__ */ m("div", { className: "task__r1", children: [
|
|
746
|
-
/* @__PURE__ */ o("span", { className: "task__who", children:
|
|
747
|
-
i && /* @__PURE__ */ o("span", { className: "task__repo", children:
|
|
747
|
+
/* @__PURE__ */ o("span", { className: "task__who", children: t.agentName }),
|
|
748
|
+
i && /* @__PURE__ */ o("span", { className: "task__repo", children: t.repo }),
|
|
748
749
|
r && /* @__PURE__ */ o("span", { className: "task__tag", children: r }),
|
|
749
750
|
/* @__PURE__ */ o("span", { className: "livedot", title: "active" })
|
|
750
751
|
] }),
|
|
751
|
-
/* @__PURE__ */ o(
|
|
752
|
+
/* @__PURE__ */ o(te, { task: t, nowMs: n })
|
|
752
753
|
] });
|
|
753
754
|
}
|
|
754
|
-
function
|
|
755
|
-
group:
|
|
756
|
-
nowMs:
|
|
755
|
+
function _t({
|
|
756
|
+
group: t,
|
|
757
|
+
nowMs: n,
|
|
757
758
|
allRepos: i
|
|
758
759
|
}) {
|
|
759
|
-
const r =
|
|
760
|
+
const r = t.model || t.program, a = t.primaries.length + t.narrower.length, s = t.narrower.length;
|
|
760
761
|
return /* @__PURE__ */ m("div", { className: "grp", children: [
|
|
761
762
|
/* @__PURE__ */ m("div", { className: "grp__head", children: [
|
|
762
|
-
/* @__PURE__ */ o("span", { className: "grp__who", children:
|
|
763
|
-
i && /* @__PURE__ */ o("span", { className: "task__repo", children:
|
|
763
|
+
/* @__PURE__ */ o("span", { className: "grp__who", children: t.agentName }),
|
|
764
|
+
i && /* @__PURE__ */ o("span", { className: "task__repo", children: t.repo }),
|
|
764
765
|
r && /* @__PURE__ */ o("span", { className: "grp__tag", children: r }),
|
|
765
766
|
/* @__PURE__ */ o("span", { className: "grp__count", children: `· ${a} active` }),
|
|
766
767
|
/* @__PURE__ */ o("span", { className: "grp__dot", title: "live" })
|
|
767
768
|
] }),
|
|
768
|
-
/* @__PURE__ */ o("div", { className: "claims", children:
|
|
769
|
+
/* @__PURE__ */ o("div", { className: "claims", children: t.primaries.map((l) => /* @__PURE__ */ o("div", { className: "claim", children: /* @__PURE__ */ o(te, { task: l, nowMs: n }) }, ee(l))) }),
|
|
769
770
|
s > 0 && /* @__PURE__ */ m("details", { className: "fold", children: [
|
|
770
771
|
/* @__PURE__ */ m("summary", { children: [
|
|
771
772
|
/* @__PURE__ */ o("span", { className: "tw", children: "▶" }),
|
|
772
773
|
` +${s} narrower claim${s > 1 ? "s" : ""}`
|
|
773
774
|
] }),
|
|
774
|
-
/* @__PURE__ */ o("div", { className: "fold__body", children:
|
|
775
|
-
/* @__PURE__ */ o(
|
|
775
|
+
/* @__PURE__ */ o("div", { className: "fold__body", children: t.narrower.map((l) => /* @__PURE__ */ m("div", { className: "claim", children: [
|
|
776
|
+
/* @__PURE__ */ o(te, { task: l, nowMs: n }),
|
|
776
777
|
/* @__PURE__ */ o("div", { className: "covered", children: "⊂ covered by a claim above" })
|
|
777
|
-
] },
|
|
778
|
+
] }, ee(l))) })
|
|
778
779
|
] })
|
|
779
780
|
] });
|
|
780
781
|
}
|
|
781
|
-
function
|
|
782
|
-
tasks:
|
|
783
|
-
nowMs:
|
|
782
|
+
function yt({
|
|
783
|
+
tasks: t,
|
|
784
|
+
nowMs: n,
|
|
784
785
|
selectedRepo: i
|
|
785
786
|
}) {
|
|
786
|
-
const r =
|
|
787
|
-
(s) => s.status === "active" &&
|
|
787
|
+
const r = bt(i), a = t.filter(
|
|
788
|
+
(s) => s.status === "active" && L(s, i)
|
|
788
789
|
);
|
|
789
790
|
if (a.length === 0) {
|
|
790
791
|
const s = r ? "Nothing active right now." : `Nothing active in ${i}.`;
|
|
791
792
|
return /* @__PURE__ */ o("div", { id: "active-list", children: /* @__PURE__ */ o("div", { className: "empty", children: s }) });
|
|
792
793
|
}
|
|
793
|
-
return /* @__PURE__ */ o("div", { id: "active-list", children:
|
|
794
|
-
const l = s.primaries.length === 1 && s.narrower.length === 0, c =
|
|
794
|
+
return /* @__PURE__ */ o("div", { id: "active-list", children: pt(a).map((s) => {
|
|
795
|
+
const l = s.primaries.length === 1 && s.narrower.length === 0, c = ee(s.primaries.concat(s.narrower)[0]);
|
|
795
796
|
return l ? /* @__PURE__ */ o(
|
|
796
|
-
|
|
797
|
+
vt,
|
|
797
798
|
{
|
|
798
799
|
task: s.primaries[0],
|
|
799
|
-
nowMs:
|
|
800
|
+
nowMs: n,
|
|
800
801
|
allRepos: r
|
|
801
802
|
},
|
|
802
803
|
c
|
|
803
|
-
) : /* @__PURE__ */ o(
|
|
804
|
+
) : /* @__PURE__ */ o(_t, { group: s, nowMs: n, allRepos: r }, c);
|
|
804
805
|
}) });
|
|
805
806
|
}
|
|
806
|
-
const
|
|
807
|
-
function
|
|
808
|
-
tasks:
|
|
809
|
-
nowMs:
|
|
807
|
+
const Nt = (t) => `${t.agentName}|${t.repo}|${t.createdAt}`, kt = (t) => t === null || t === "__all__";
|
|
808
|
+
function wt({
|
|
809
|
+
tasks: t,
|
|
810
|
+
nowMs: n,
|
|
810
811
|
selectedRepo: i,
|
|
811
812
|
doneShown: r,
|
|
812
813
|
onLoadMore: a
|
|
813
814
|
}) {
|
|
814
|
-
const s =
|
|
815
|
-
(u) => u.status !== "active" &&
|
|
815
|
+
const s = kt(i), l = t.filter(
|
|
816
|
+
(u) => u.status !== "active" && L(u, i)
|
|
816
817
|
);
|
|
817
818
|
if (l.length === 0) {
|
|
818
819
|
const u = s ? "No finished tasks yet." : `No finished tasks in ${i} yet.`;
|
|
@@ -822,11 +823,11 @@ function ut({
|
|
|
822
823
|
let p = null;
|
|
823
824
|
return /* @__PURE__ */ m("div", { id: "done-list", children: [
|
|
824
825
|
c.map((u) => {
|
|
825
|
-
const d =
|
|
826
|
+
const d = ut(u.endedAt ?? u.createdAt, n), f = d !== p ? d : null;
|
|
826
827
|
p = d;
|
|
827
|
-
const
|
|
828
|
-
return /* @__PURE__ */ m(
|
|
829
|
-
|
|
828
|
+
const b = u.status === "dropped", N = b ? `went offline ${q(u.endedAt ?? u.createdAt, n)} — no done signal` : `finished ${q(u.endedAt ?? u.createdAt, n)}${he(u.createdAt, u.endedAt) ? " · " + he(u.createdAt, u.endedAt) : ""}`;
|
|
829
|
+
return /* @__PURE__ */ m(Le, { children: [
|
|
830
|
+
f !== null && /* @__PURE__ */ o("div", { className: "day", children: f }),
|
|
830
831
|
/* @__PURE__ */ m("div", { className: "task", children: [
|
|
831
832
|
/* @__PURE__ */ m("div", { className: "task__r1", children: [
|
|
832
833
|
/* @__PURE__ */ o("span", { className: "task__who", children: u.agentName }),
|
|
@@ -834,16 +835,16 @@ function ut({
|
|
|
834
835
|
/* @__PURE__ */ o(
|
|
835
836
|
"span",
|
|
836
837
|
{
|
|
837
|
-
className: "task__stat" + (
|
|
838
|
-
children:
|
|
838
|
+
className: "task__stat" + (b ? " task__stat--drop" : ""),
|
|
839
|
+
children: dt(u.status)
|
|
839
840
|
}
|
|
840
841
|
)
|
|
841
842
|
] }),
|
|
842
843
|
/* @__PURE__ */ o("div", { className: "task__intent", children: u.intent }),
|
|
843
|
-
/* @__PURE__ */ o(
|
|
844
|
+
/* @__PURE__ */ o(Ce, { globs: u.pathGlobs }),
|
|
844
845
|
/* @__PURE__ */ o("div", { className: "task__meta", children: N })
|
|
845
846
|
] })
|
|
846
|
-
] },
|
|
847
|
+
] }, Nt(u));
|
|
847
848
|
}),
|
|
848
849
|
l.length > r && /* @__PURE__ */ o(
|
|
849
850
|
"div",
|
|
@@ -860,12 +861,12 @@ function ut({
|
|
|
860
861
|
)
|
|
861
862
|
] });
|
|
862
863
|
}
|
|
863
|
-
const
|
|
864
|
-
function
|
|
865
|
-
const r =
|
|
866
|
-
s && (a.current = s.scrollHeight - s.scrollTop - s.clientHeight <
|
|
867
|
-
const l = [...
|
|
868
|
-
return
|
|
864
|
+
const At = 80;
|
|
865
|
+
function St({ announcements: t, selectedRepo: n, nowMs: i }) {
|
|
866
|
+
const r = P(null), a = P(!0), s = r.current;
|
|
867
|
+
s && (a.current = s.scrollHeight - s.scrollTop - s.clientHeight < At);
|
|
868
|
+
const l = [...t].filter((c) => L(c, n)).reverse();
|
|
869
|
+
return Me(() => {
|
|
869
870
|
a.current && r.current && (r.current.scrollTop = r.current.scrollHeight);
|
|
870
871
|
}, [l.length]), /* @__PURE__ */ o("div", { id: "chat", className: "chat", ref: r, children: l.length === 0 ? /* @__PURE__ */ o("div", { className: "empty", children: "No announcements yet — agents will post here as they coordinate." }) : l.map((c, p) => {
|
|
871
872
|
const d = "msg" + (c.targetAgentName !== null || c.toAdmin ? " msg--targeted" : "") + (c.fromAdmin ? " msg--me" : "");
|
|
@@ -877,8 +878,8 @@ function ht({ announcements: n, selectedRepo: t, nowMs: i }) {
|
|
|
877
878
|
"div",
|
|
878
879
|
{
|
|
879
880
|
className: "msg__avatar",
|
|
880
|
-
style: { background:
|
|
881
|
-
children:
|
|
881
|
+
style: { background: K(c.fromAgentName) },
|
|
882
|
+
children: re(c.fromAgentName)
|
|
882
883
|
}
|
|
883
884
|
),
|
|
884
885
|
/* @__PURE__ */ m("div", { className: "msg__body", children: [
|
|
@@ -887,13 +888,13 @@ function ht({ announcements: n, selectedRepo: t, nowMs: i }) {
|
|
|
887
888
|
"span",
|
|
888
889
|
{
|
|
889
890
|
className: "msg__who",
|
|
890
|
-
style: { color:
|
|
891
|
+
style: { color: K(c.fromAgentName) },
|
|
891
892
|
children: c.fromAgentName
|
|
892
893
|
}
|
|
893
894
|
),
|
|
894
895
|
c.fromHuman ? /* @__PURE__ */ o("span", { className: "msg__human", children: c.fromHuman }) : null,
|
|
895
896
|
c.targetAgentName !== null ? /* @__PURE__ */ o("span", { className: "msg__to", children: `→ @${c.targetAgentName}` }) : c.toAdmin ? /* @__PURE__ */ o("span", { className: "msg__to", children: "→ admin" }) : null,
|
|
896
|
-
/* @__PURE__ */ o("span", { className: "msg__time", children:
|
|
897
|
+
/* @__PURE__ */ o("span", { className: "msg__time", children: q(c.createdAt, i) })
|
|
897
898
|
] }),
|
|
898
899
|
/* @__PURE__ */ o("div", { className: "msg__text", children: c.body })
|
|
899
900
|
] })
|
|
@@ -901,64 +902,64 @@ function ht({ announcements: n, selectedRepo: t, nowMs: i }) {
|
|
|
901
902
|
);
|
|
902
903
|
}) });
|
|
903
904
|
}
|
|
904
|
-
const
|
|
905
|
-
function
|
|
906
|
-
const a =
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
),
|
|
905
|
+
const Tt = 8;
|
|
906
|
+
function Ct({ agents: t, selectedRepo: n, workspaceId: i, onSent: r }) {
|
|
907
|
+
const a = Ae(), s = P(null), [l, c] = A(""), [p, u] = A([]), [d, f] = A(0), [b, N] = A(null), [v, S] = A(!1), [E, w] = A(!1), I = lt(
|
|
908
|
+
t.map((h) => ({ name: h.name, presence: h.presence, repo: h.repo ?? "" })),
|
|
909
|
+
n
|
|
910
|
+
), T = p.length > 0, $ = R(() => {
|
|
910
911
|
u([]), N(null);
|
|
911
|
-
}, []),
|
|
912
|
-
(h,
|
|
913
|
-
const
|
|
914
|
-
if (!
|
|
915
|
-
|
|
912
|
+
}, []), W = R(
|
|
913
|
+
(h, y) => {
|
|
914
|
+
const k = it(h, y);
|
|
915
|
+
if (!k) {
|
|
916
|
+
$();
|
|
916
917
|
return;
|
|
917
918
|
}
|
|
918
|
-
const
|
|
919
|
-
u(
|
|
919
|
+
const M = k.query.toLowerCase(), D = I.filter((G) => G.toLowerCase().startsWith(M)).slice(0, Tt);
|
|
920
|
+
u(D), N({ start: k.start, end: k.end }), f(0);
|
|
920
921
|
},
|
|
921
|
-
[
|
|
922
|
-
),
|
|
922
|
+
[I, $]
|
|
923
|
+
), _ = R(
|
|
923
924
|
(h) => {
|
|
924
|
-
if (!
|
|
925
|
-
const
|
|
926
|
-
c(
|
|
927
|
-
const
|
|
928
|
-
|
|
925
|
+
if (!b) return;
|
|
926
|
+
const y = "@" + h + " ", k = l.slice(0, b.start) + y + l.slice(b.end), M = b.start + y.length;
|
|
927
|
+
c(k), $(), requestAnimationFrame(() => {
|
|
928
|
+
const D = s.current;
|
|
929
|
+
D && (D.focus(), D.setSelectionRange(M, M));
|
|
929
930
|
});
|
|
930
931
|
},
|
|
931
|
-
[
|
|
932
|
-
),
|
|
932
|
+
[b, l, $]
|
|
933
|
+
), U = R(
|
|
933
934
|
(h) => {
|
|
934
|
-
var
|
|
935
|
+
var k;
|
|
935
936
|
c(h);
|
|
936
|
-
const
|
|
937
|
-
|
|
937
|
+
const y = ((k = s.current) == null ? void 0 : k.selectionStart) ?? h.length;
|
|
938
|
+
W(h, y);
|
|
938
939
|
},
|
|
939
|
-
[
|
|
940
|
-
),
|
|
940
|
+
[W]
|
|
941
|
+
), Y = R(
|
|
941
942
|
(h) => {
|
|
942
|
-
|
|
943
|
+
T && (h.key === "ArrowDown" ? (h.preventDefault(), f((y) => (y + 1) % p.length)) : h.key === "ArrowUp" ? (h.preventDefault(), f((y) => (y - 1 + p.length) % p.length)) : h.key === "Enter" || h.key === "Tab" ? (h.preventDefault(), _(p[d])) : h.key === "Escape" && (h.preventDefault(), $()));
|
|
943
944
|
},
|
|
944
|
-
[
|
|
945
|
-
),
|
|
945
|
+
[T, p, d, _, $]
|
|
946
|
+
), V = R(
|
|
946
947
|
async (h) => {
|
|
947
948
|
h.preventDefault();
|
|
948
|
-
const
|
|
949
|
-
if (!
|
|
950
|
-
const
|
|
951
|
-
|
|
949
|
+
const y = l.trim();
|
|
950
|
+
if (!y) return;
|
|
951
|
+
const k = ct(y, I), M = n === null || n === "__all__" ? null : n;
|
|
952
|
+
S(!0), w(!1);
|
|
952
953
|
try {
|
|
953
|
-
const
|
|
954
|
-
await (i !== void 0 ? a.announceTo(i,
|
|
954
|
+
const D = { body: y, targetAgentName: k, repo: M };
|
|
955
|
+
await (i !== void 0 ? a.announceTo(i, D) : a.announce(D)), c(""), $(), await r();
|
|
955
956
|
} catch {
|
|
956
|
-
|
|
957
|
+
w(!0);
|
|
957
958
|
} finally {
|
|
958
|
-
|
|
959
|
+
S(!1);
|
|
959
960
|
}
|
|
960
961
|
},
|
|
961
|
-
[l,
|
|
962
|
+
[l, I, n, i, a, $, r]
|
|
962
963
|
);
|
|
963
964
|
return /* @__PURE__ */ m("div", { className: "composer", children: [
|
|
964
965
|
/* @__PURE__ */ o(
|
|
@@ -968,20 +969,20 @@ function gt({ agents: n, selectedRepo: t, workspaceId: i, onSent: r }) {
|
|
|
968
969
|
className: "mention-pop",
|
|
969
970
|
role: "listbox",
|
|
970
971
|
"aria-label": "Agents to mention",
|
|
971
|
-
hidden: !
|
|
972
|
-
children: p.map((h,
|
|
972
|
+
hidden: !T,
|
|
973
|
+
children: p.map((h, y) => /* @__PURE__ */ m(
|
|
973
974
|
"button",
|
|
974
975
|
{
|
|
975
|
-
id: `mention-opt-${
|
|
976
|
+
id: `mention-opt-${y}`,
|
|
976
977
|
type: "button",
|
|
977
978
|
role: "option",
|
|
978
|
-
"aria-selected":
|
|
979
|
-
className: "mention-mi" + (
|
|
980
|
-
onMouseDown: (
|
|
981
|
-
|
|
979
|
+
"aria-selected": y === d,
|
|
980
|
+
className: "mention-mi" + (y === d ? " on" : ""),
|
|
981
|
+
onMouseDown: (k) => {
|
|
982
|
+
k.preventDefault(), _(h);
|
|
982
983
|
},
|
|
983
984
|
children: [
|
|
984
|
-
/* @__PURE__ */ o("div", { className: "ma", style: { background:
|
|
985
|
+
/* @__PURE__ */ o("div", { className: "ma", style: { background: K(h) }, children: re(h) }),
|
|
985
986
|
/* @__PURE__ */ o("span", { children: h })
|
|
986
987
|
]
|
|
987
988
|
},
|
|
@@ -995,7 +996,7 @@ function gt({ agents: n, selectedRepo: t, workspaceId: i, onSent: r }) {
|
|
|
995
996
|
id: "chat-form",
|
|
996
997
|
className: "chat-form",
|
|
997
998
|
onSubmit: (h) => {
|
|
998
|
-
|
|
999
|
+
V(h);
|
|
999
1000
|
},
|
|
1000
1001
|
children: [
|
|
1001
1002
|
/* @__PURE__ */ o(
|
|
@@ -1008,24 +1009,37 @@ function gt({ agents: n, selectedRepo: t, workspaceId: i, onSent: r }) {
|
|
|
1008
1009
|
"aria-label": "Message the team",
|
|
1009
1010
|
placeholder: "Message the team… use @name to direct it",
|
|
1010
1011
|
role: "combobox",
|
|
1011
|
-
"aria-expanded":
|
|
1012
|
+
"aria-expanded": T,
|
|
1012
1013
|
"aria-controls": "mention-pop",
|
|
1013
1014
|
"aria-autocomplete": "list",
|
|
1014
|
-
"aria-activedescendant":
|
|
1015
|
+
"aria-activedescendant": T ? `mention-opt-${d}` : void 0,
|
|
1015
1016
|
ref: s,
|
|
1016
1017
|
value: l,
|
|
1017
|
-
onChange: (h) =>
|
|
1018
|
-
onKeyDown:
|
|
1018
|
+
onChange: (h) => U(h.target.value),
|
|
1019
|
+
onKeyDown: Y
|
|
1019
1020
|
}
|
|
1020
1021
|
),
|
|
1021
|
-
/* @__PURE__ */ o("button", { id: "chat-send", className: "chat-send", type: "submit", disabled:
|
|
1022
|
+
/* @__PURE__ */ o("button", { id: "chat-send", className: "chat-send", type: "submit", disabled: v, children: "Send" })
|
|
1022
1023
|
]
|
|
1023
1024
|
}
|
|
1024
1025
|
),
|
|
1025
|
-
|
|
1026
|
+
E ? /* @__PURE__ */ o("div", { className: "chat__note", role: "status", children: "send failed — retry" }) : null
|
|
1027
|
+
] });
|
|
1028
|
+
}
|
|
1029
|
+
function ve({
|
|
1030
|
+
title: t = "No workspace yet",
|
|
1031
|
+
children: n,
|
|
1032
|
+
onGetStarted: i,
|
|
1033
|
+
ctaLabel: r = "Go to Config"
|
|
1034
|
+
}) {
|
|
1035
|
+
const a = Pe();
|
|
1036
|
+
return /* @__PURE__ */ m("section", { className: "shepherd-empty-state", "aria-labelledby": a, children: [
|
|
1037
|
+
/* @__PURE__ */ o("h2", { id: a, children: t }),
|
|
1038
|
+
/* @__PURE__ */ o("p", { children: n ?? "Create a workspace or join one with an invite code to get started." }),
|
|
1039
|
+
i && /* @__PURE__ */ o("button", { type: "button", onClick: i, children: r })
|
|
1026
1040
|
] });
|
|
1027
1041
|
}
|
|
1028
|
-
const
|
|
1042
|
+
const _e = "shepherd.tab", Z = "shepherd.repo", J = 10, $t = {
|
|
1029
1043
|
live: { text: "live", kind: "ok" },
|
|
1030
1044
|
reconnecting: { text: "reconnecting…", kind: "warn" },
|
|
1031
1045
|
// app.js cleared the token and re-prompted on 401; in the auth-agnostic port
|
|
@@ -1033,152 +1047,199 @@ const le = "shepherd.tab", z = "shepherd.repo", K = 10, ft = {
|
|
|
1033
1047
|
// only surfaces the rejected state.
|
|
1034
1048
|
unauthorized: { text: "token rejected", kind: "error" }
|
|
1035
1049
|
};
|
|
1036
|
-
function
|
|
1050
|
+
function ye(t) {
|
|
1037
1051
|
try {
|
|
1038
|
-
return localStorage.getItem(
|
|
1052
|
+
return localStorage.getItem(t);
|
|
1039
1053
|
} catch {
|
|
1040
1054
|
return null;
|
|
1041
1055
|
}
|
|
1042
1056
|
}
|
|
1043
|
-
function
|
|
1057
|
+
function Q(t, n) {
|
|
1044
1058
|
try {
|
|
1045
|
-
localStorage.setItem(
|
|
1059
|
+
localStorage.setItem(t, n);
|
|
1046
1060
|
} catch {
|
|
1047
1061
|
}
|
|
1048
1062
|
}
|
|
1049
|
-
function
|
|
1050
|
-
const r =
|
|
1051
|
-
let a =
|
|
1052
|
-
if (a === null && r.length >= 2 && (a =
|
|
1053
|
-
const s =
|
|
1063
|
+
function Rt(t, n, i) {
|
|
1064
|
+
const r = Te(n.tasks);
|
|
1065
|
+
let a = t;
|
|
1066
|
+
if (a === null && r.length >= 2 && (a = me(n.tasks)), a !== null && a !== "__all__" && !r.includes(a) && (a = "__all__"), i && a !== null && a !== "__all__") {
|
|
1067
|
+
const s = n.tasks.some(
|
|
1054
1068
|
(c) => c.status === "active" && c.repo === a
|
|
1055
|
-
), l =
|
|
1056
|
-
!s && l && (a =
|
|
1069
|
+
), l = n.tasks.some((c) => c.status === "active");
|
|
1070
|
+
!s && l && (a = me(n.tasks));
|
|
1057
1071
|
}
|
|
1058
1072
|
return a;
|
|
1059
1073
|
}
|
|
1060
|
-
function
|
|
1061
|
-
const
|
|
1062
|
-
const s =
|
|
1074
|
+
function Et(t) {
|
|
1075
|
+
const n = {}, i = (r, a) => {
|
|
1076
|
+
const s = n[r] ?? (n[r] = { active: 0, done: 0 });
|
|
1063
1077
|
s[a]++;
|
|
1064
1078
|
};
|
|
1065
|
-
for (const r of
|
|
1079
|
+
for (const r of t.tasks) {
|
|
1066
1080
|
const a = r.status === "active" ? "active" : "done";
|
|
1067
1081
|
i(r.repo, a), i("__all__", a);
|
|
1068
1082
|
}
|
|
1069
|
-
return
|
|
1083
|
+
return n;
|
|
1070
1084
|
}
|
|
1071
|
-
function
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
)
|
|
1092
|
-
(g) =>
|
|
1093
|
-
|
|
1085
|
+
function Gt({
|
|
1086
|
+
workspaceId: t,
|
|
1087
|
+
config: n,
|
|
1088
|
+
hasWorkspace: i
|
|
1089
|
+
} = {}) {
|
|
1090
|
+
const r = n != null, a = i === !1, { snapshot: s, status: l, lastUpdatedMs: c, refresh: p } = ot({
|
|
1091
|
+
workspaceId: t,
|
|
1092
|
+
// A no-workspace board has nothing to poll; keep it off the hub.
|
|
1093
|
+
enabled: !a
|
|
1094
|
+
}), [u, d] = A(() => {
|
|
1095
|
+
if (r && a) return "config";
|
|
1096
|
+
const g = ye(_e);
|
|
1097
|
+
return g === "chat" ? "chat" : g === "config" && r ? "config" : "tasks";
|
|
1098
|
+
}), f = r ? [
|
|
1099
|
+
{ id: "tasks", label: "Tasks" },
|
|
1100
|
+
{ id: "chat", label: "Chat" },
|
|
1101
|
+
{ id: "config", label: "Config" }
|
|
1102
|
+
] : [
|
|
1103
|
+
{ id: "tasks", label: "Tasks" },
|
|
1104
|
+
{ id: "chat", label: "Chat" }
|
|
1105
|
+
], b = P([]), N = R(
|
|
1106
|
+
(g, x) => {
|
|
1107
|
+
var ce;
|
|
1108
|
+
const O = f.length - 1;
|
|
1109
|
+
let j = null;
|
|
1110
|
+
switch (g.key) {
|
|
1111
|
+
case "ArrowRight":
|
|
1112
|
+
j = x === O ? 0 : x + 1;
|
|
1113
|
+
break;
|
|
1114
|
+
case "ArrowLeft":
|
|
1115
|
+
j = x === 0 ? O : x - 1;
|
|
1116
|
+
break;
|
|
1117
|
+
case "Home":
|
|
1118
|
+
j = 0;
|
|
1119
|
+
break;
|
|
1120
|
+
case "End":
|
|
1121
|
+
j = O;
|
|
1122
|
+
break;
|
|
1123
|
+
default:
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
g.preventDefault();
|
|
1127
|
+
const ie = f[j];
|
|
1128
|
+
ie && (T(ie.id), (ce = b.current[j]) == null || ce.focus());
|
|
1129
|
+
},
|
|
1130
|
+
// `tabs` is rebuilt each render but its identity only matters by length,
|
|
1131
|
+
// which is stable for a given `hasConfig`; `onTab` is stable.
|
|
1132
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1133
|
+
[r]
|
|
1134
|
+
), [v, S] = A(
|
|
1135
|
+
() => ye(Z)
|
|
1136
|
+
), [E, w] = A(J), I = P(!0), T = R((g) => {
|
|
1137
|
+
d(g), Q(_e, g);
|
|
1138
|
+
}, []), $ = R((g) => {
|
|
1139
|
+
const x = g === null ? "__all__" : g;
|
|
1140
|
+
S(x), Q(Z, x), w(J);
|
|
1141
|
+
}, []), W = R(() => {
|
|
1142
|
+
w((g) => g + J);
|
|
1143
|
+
}, []), _ = s ? Rt(v, s, I.current) : v;
|
|
1144
|
+
ne(() => {
|
|
1145
|
+
s && (I.current = !1, _ !== v && (S(_), _ !== null && _ !== "__all__" && Q(Z, _)));
|
|
1146
|
+
}, [s, _, v]);
|
|
1147
|
+
const U = s ? Date.parse(s.serverTime) : Date.now(), Y = s ? Te(s.tasks) : [], V = s ? Et(s) : {}, h = s ? s.agents.filter(
|
|
1148
|
+
(g) => g.presence === "live" && L({ repo: g.repo ?? "" }, _)
|
|
1149
|
+
).length : 0, y = s ? s.tasks.filter((g) => g.status === "active" && L(g, _)).length : 0, k = $t[l], M = c === null ? "" : `updated ${Math.floor((Date.now() - c) / 1e3)}s ago`, D = (s == null ? void 0 : s.agents) ?? [], G = (s == null ? void 0 : s.tasks) ?? [], $e = (s == null ? void 0 : s.announcements) ?? [], Re = G.filter(
|
|
1150
|
+
(g) => g.status === "active" && L(g, _)
|
|
1151
|
+
).length, Ee = G.filter(
|
|
1152
|
+
(g) => g.status !== "active" && L(g, _)
|
|
1153
|
+
).length, oe = !a && u !== "config";
|
|
1094
1154
|
return /* @__PURE__ */ m("div", { id: "board", children: [
|
|
1095
1155
|
/* @__PURE__ */ m("header", { children: [
|
|
1096
|
-
/* @__PURE__ */ o("
|
|
1097
|
-
/* @__PURE__ */
|
|
1098
|
-
st,
|
|
1099
|
-
{
|
|
1100
|
-
repos: $,
|
|
1101
|
-
counts: C,
|
|
1102
|
-
selected: f,
|
|
1103
|
-
onSelect: N
|
|
1104
|
-
}
|
|
1105
|
-
),
|
|
1106
|
-
/* @__PURE__ */ m("span", { className: "vitals", children: [
|
|
1107
|
-
/* @__PURE__ */ o("b", { id: "vitals-online", children: R }),
|
|
1108
|
-
" online · ",
|
|
1109
|
-
/* @__PURE__ */ o("b", { id: "vitals-active", children: T }),
|
|
1110
|
-
" active"
|
|
1111
|
-
] }),
|
|
1112
|
-
/* @__PURE__ */ o("span", { className: "grow" }),
|
|
1113
|
-
/* @__PURE__ */ o("span", { id: "status", className: "status" + (M.kind ? ` status--${M.kind}` : ""), children: M.text }),
|
|
1114
|
-
/* @__PURE__ */ o("span", { id: "freshness", className: "freshness", children: L }),
|
|
1115
|
-
/* @__PURE__ */ m("nav", { className: "tabs", role: "tablist", "aria-label": "Dashboard views", children: [
|
|
1156
|
+
/* @__PURE__ */ o("h1", { className: "brand", style: { margin: 0, font: "inherit" }, children: "Shepherd" }),
|
|
1157
|
+
oe && /* @__PURE__ */ m(F, { children: [
|
|
1116
1158
|
/* @__PURE__ */ o(
|
|
1117
|
-
|
|
1159
|
+
gt,
|
|
1118
1160
|
{
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
id: "tab-tasks",
|
|
1124
|
-
"aria-controls": "panel-tasks",
|
|
1125
|
-
"aria-selected": s === "tasks",
|
|
1126
|
-
onClick: () => v("tasks"),
|
|
1127
|
-
children: "Tasks"
|
|
1161
|
+
repos: Y,
|
|
1162
|
+
counts: V,
|
|
1163
|
+
selected: _,
|
|
1164
|
+
onSelect: $
|
|
1128
1165
|
}
|
|
1129
1166
|
),
|
|
1167
|
+
/* @__PURE__ */ m("span", { className: "vitals", children: [
|
|
1168
|
+
/* @__PURE__ */ o("b", { id: "vitals-online", children: h }),
|
|
1169
|
+
" online · ",
|
|
1170
|
+
/* @__PURE__ */ o("b", { id: "vitals-active", children: y }),
|
|
1171
|
+
" active"
|
|
1172
|
+
] })
|
|
1173
|
+
] }),
|
|
1174
|
+
/* @__PURE__ */ o("span", { className: "grow" }),
|
|
1175
|
+
oe && /* @__PURE__ */ m(F, { children: [
|
|
1130
1176
|
/* @__PURE__ */ o(
|
|
1131
|
-
"
|
|
1177
|
+
"span",
|
|
1132
1178
|
{
|
|
1133
|
-
|
|
1134
|
-
"
|
|
1135
|
-
|
|
1136
|
-
role: "tab",
|
|
1137
|
-
id: "tab-chat",
|
|
1138
|
-
"aria-controls": "panel-chat",
|
|
1139
|
-
"aria-selected": s === "chat",
|
|
1140
|
-
onClick: () => v("chat"),
|
|
1141
|
-
children: "Chat"
|
|
1179
|
+
id: "status",
|
|
1180
|
+
className: "status" + (k.kind ? ` status--${k.kind}` : ""),
|
|
1181
|
+
children: k.text
|
|
1142
1182
|
}
|
|
1143
|
-
)
|
|
1144
|
-
|
|
1183
|
+
),
|
|
1184
|
+
/* @__PURE__ */ o("span", { id: "freshness", className: "freshness", children: M })
|
|
1185
|
+
] }),
|
|
1186
|
+
/* @__PURE__ */ o("nav", { className: "tabs", role: "tablist", "aria-label": "Shepherd views", children: f.map(({ id: g, label: x }, O) => /* @__PURE__ */ o(
|
|
1187
|
+
"button",
|
|
1188
|
+
{
|
|
1189
|
+
ref: (j) => {
|
|
1190
|
+
b.current[O] = j;
|
|
1191
|
+
},
|
|
1192
|
+
className: "tab" + (u === g ? " tab--active" : ""),
|
|
1193
|
+
"data-tab": g,
|
|
1194
|
+
type: "button",
|
|
1195
|
+
role: "tab",
|
|
1196
|
+
id: `tab-${g}`,
|
|
1197
|
+
"aria-controls": `panel-${g}`,
|
|
1198
|
+
"aria-selected": u === g,
|
|
1199
|
+
tabIndex: u === g ? 0 : -1,
|
|
1200
|
+
onClick: () => T(g),
|
|
1201
|
+
onKeyDown: (j) => N(j, O),
|
|
1202
|
+
children: x
|
|
1203
|
+
},
|
|
1204
|
+
g
|
|
1205
|
+
)) })
|
|
1145
1206
|
] }),
|
|
1146
|
-
/* @__PURE__ */
|
|
1207
|
+
/* @__PURE__ */ o(
|
|
1147
1208
|
"section",
|
|
1148
1209
|
{
|
|
1149
1210
|
id: "panel-tasks",
|
|
1150
1211
|
role: "tabpanel",
|
|
1151
1212
|
"aria-labelledby": "tab-tasks",
|
|
1152
|
-
hidden:
|
|
1153
|
-
children: [
|
|
1154
|
-
/* @__PURE__ */ o(
|
|
1213
|
+
hidden: u !== "tasks",
|
|
1214
|
+
children: a ? /* @__PURE__ */ o(ve, { onGetStarted: () => T("config") }) : /* @__PURE__ */ m(F, { children: [
|
|
1215
|
+
/* @__PURE__ */ o(ft, { agents: D, tasks: G, selectedRepo: _ }),
|
|
1155
1216
|
/* @__PURE__ */ m("div", { className: "board", children: [
|
|
1156
1217
|
/* @__PURE__ */ m("div", { className: "col", children: [
|
|
1157
1218
|
/* @__PURE__ */ m("div", { className: "colhead", children: [
|
|
1158
1219
|
/* @__PURE__ */ o("h2", { children: "Active" }),
|
|
1159
|
-
/* @__PURE__ */ o("span", { className: "n", id: "active-count", children:
|
|
1220
|
+
/* @__PURE__ */ o("span", { className: "n", id: "active-count", children: Re })
|
|
1160
1221
|
] }),
|
|
1161
|
-
/* @__PURE__ */ o(
|
|
1222
|
+
/* @__PURE__ */ o(yt, { tasks: G, nowMs: U, selectedRepo: _ })
|
|
1162
1223
|
] }),
|
|
1163
1224
|
/* @__PURE__ */ o("div", { className: "board__rule" }),
|
|
1164
1225
|
/* @__PURE__ */ m("div", { className: "col", children: [
|
|
1165
1226
|
/* @__PURE__ */ m("div", { className: "colhead", children: [
|
|
1166
1227
|
/* @__PURE__ */ o("h2", { children: "Done" }),
|
|
1167
|
-
/* @__PURE__ */ o("span", { className: "n", id: "done-count", children:
|
|
1228
|
+
/* @__PURE__ */ o("span", { className: "n", id: "done-count", children: Ee })
|
|
1168
1229
|
] }),
|
|
1169
1230
|
/* @__PURE__ */ o(
|
|
1170
|
-
|
|
1231
|
+
wt,
|
|
1171
1232
|
{
|
|
1172
|
-
tasks:
|
|
1173
|
-
nowMs:
|
|
1174
|
-
selectedRepo:
|
|
1175
|
-
doneShown:
|
|
1176
|
-
onLoadMore:
|
|
1233
|
+
tasks: G,
|
|
1234
|
+
nowMs: U,
|
|
1235
|
+
selectedRepo: _,
|
|
1236
|
+
doneShown: E,
|
|
1237
|
+
onLoadMore: W
|
|
1177
1238
|
}
|
|
1178
1239
|
)
|
|
1179
1240
|
] })
|
|
1180
1241
|
] })
|
|
1181
|
-
]
|
|
1242
|
+
] })
|
|
1182
1243
|
}
|
|
1183
1244
|
),
|
|
1184
1245
|
/* @__PURE__ */ o(
|
|
@@ -1187,28 +1248,39 @@ function Tt({ workspaceId: n } = {}) {
|
|
|
1187
1248
|
id: "panel-chat",
|
|
1188
1249
|
role: "tabpanel",
|
|
1189
1250
|
"aria-labelledby": "tab-chat",
|
|
1190
|
-
hidden:
|
|
1191
|
-
children: /* @__PURE__ */ m("div", { className: "chat-wrap", children: [
|
|
1192
|
-
/* @__PURE__ */ o(
|
|
1251
|
+
hidden: u !== "chat",
|
|
1252
|
+
children: a ? /* @__PURE__ */ o(ve, { onGetStarted: () => T("config") }) : /* @__PURE__ */ m("div", { className: "chat-wrap", children: [
|
|
1253
|
+
/* @__PURE__ */ o(St, { announcements: $e, selectedRepo: _, nowMs: U }),
|
|
1193
1254
|
/* @__PURE__ */ o(
|
|
1194
|
-
|
|
1255
|
+
Ct,
|
|
1195
1256
|
{
|
|
1196
|
-
agents:
|
|
1197
|
-
selectedRepo:
|
|
1198
|
-
workspaceId:
|
|
1199
|
-
onSent:
|
|
1257
|
+
agents: D,
|
|
1258
|
+
selectedRepo: _,
|
|
1259
|
+
workspaceId: t,
|
|
1260
|
+
onSent: p
|
|
1200
1261
|
}
|
|
1201
1262
|
)
|
|
1202
1263
|
] })
|
|
1203
1264
|
}
|
|
1265
|
+
),
|
|
1266
|
+
r && /* @__PURE__ */ o(
|
|
1267
|
+
"section",
|
|
1268
|
+
{
|
|
1269
|
+
id: "panel-config",
|
|
1270
|
+
role: "tabpanel",
|
|
1271
|
+
"aria-labelledby": "tab-config",
|
|
1272
|
+
hidden: u !== "config",
|
|
1273
|
+
children: n
|
|
1274
|
+
}
|
|
1204
1275
|
)
|
|
1205
1276
|
] });
|
|
1206
1277
|
}
|
|
1207
1278
|
export {
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1279
|
+
Gt as D,
|
|
1280
|
+
ve as E,
|
|
1281
|
+
H as S,
|
|
1282
|
+
Pt as a,
|
|
1283
|
+
Mt as c,
|
|
1284
|
+
Lt as d,
|
|
1285
|
+
Ae as u
|
|
1214
1286
|
};
|