@kubitnodes/stellaris 0.3.3 → 0.3.5
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/dist/cli/index.js +23 -4
- package/dist/server/index.js +83 -9
- package/package.json +1 -1
- package/web/dist/assets/BackLink-DivaHiZ7.js +1 -0
- package/web/dist/assets/{ChannelView-CBWvCs5U.js → ChannelView-DgkkiZuY.js} +1 -1
- package/web/dist/assets/CitizenView-BzhH1ycF.js +2 -0
- package/web/dist/assets/{CitizensView-BtutRBPU.js → CitizensView-BzGNyC2f.js} +1 -1
- package/web/dist/assets/KnowledgeView-DedLlEZd.js +1 -0
- package/web/dist/assets/Markdown-MZnGPfvk.js +31 -0
- package/web/dist/assets/{MessageItem-DaQY-yGb.js → MessageItem-Deq-ntT8.js} +1 -1
- package/web/dist/assets/MetricsView-C-2j71rI.js +1 -0
- package/web/dist/assets/NeedsYouView-D4xqHNDU.js +1 -0
- package/web/dist/assets/{Overview-C7bUUfnY.js → Overview-DxCYcW_A.js} +1 -1
- package/web/dist/assets/{Pane-JzhKR0rO.js → Pane-B-pz52UC.js} +1 -1
- package/web/dist/assets/ProjectView-BhZYFv7f.js +1 -0
- package/web/dist/assets/ProposalView-DAc9lEHB.js +1 -0
- package/web/dist/assets/{ProposalsView-D35XMr14.js → ProposalsView-CmwwJuop.js} +1 -1
- package/web/dist/assets/{RunnersView-DxmadMPv.js → RunnersView-Dqo_BEoK.js} +1 -1
- package/web/dist/assets/{SocietyView-DQ3w5OWp.js → SocietyView-DA_65uyo.js} +1 -1
- package/web/dist/assets/{SubjectThread-XI7ydhsi.js → SubjectThread-M4F1paqV.js} +1 -1
- package/web/dist/assets/TaskFileView-CCNVrooP.js +4 -0
- package/web/dist/assets/TaskView-BTSDk1yL.js +1 -0
- package/web/dist/assets/{TasksView-nQhDOU_5.js → TasksView-0IQm6u-_.js} +1 -1
- package/web/dist/assets/ThreadCard-BTGP4fOT.js +1 -0
- package/web/dist/assets/{ThreadForms-TZMoO5-W.js → ThreadForms-BipMby65.js} +1 -1
- package/web/dist/assets/ThreadView-D96DZAOM.js +1 -0
- package/web/dist/assets/{citizen-9NPRBOpv.js → citizen-CYBzbWt-.js} +1 -1
- package/web/dist/assets/{format-8m6fdeP8.js → format-11lojpK1.js} +1 -1
- package/web/dist/assets/index-BXq4t0NA.js +23 -0
- package/web/dist/assets/index-CKjqsZME.css +2 -0
- package/web/dist/assets/{tasks-Di8iatzY.js → tasks-DnJj3psB.js} +1 -1
- package/web/dist/assets/{useStickyScroll-BPuANcOs.js → useStickyScroll-D_7q2RKi.js} +1 -1
- package/web/dist/index.html +4 -4
- package/web/dist/assets/CitizenView-DKqzTA5L.js +0 -2
- package/web/dist/assets/KnowledgeView-DSinMNzK.js +0 -1
- package/web/dist/assets/Markdown-CwjhVNEk.js +0 -31
- package/web/dist/assets/MetricsView-BBgZsSMk.js +0 -1
- package/web/dist/assets/NeedsYouView-gft672O-.js +0 -1
- package/web/dist/assets/ProjectView-CSTwTULB.js +0 -1
- package/web/dist/assets/ProposalView-B0qXK-Vb.js +0 -1
- package/web/dist/assets/TaskFileView-7ljZ5Olx.js +0 -1
- package/web/dist/assets/TaskView-DyZBBjh1.js +0 -1
- package/web/dist/assets/ThreadCard-BZHmKArH.js +0 -1
- package/web/dist/assets/ThreadView-BV2yDunm.js +0 -1
- package/web/dist/assets/index-C3ujZpqY.css +0 -2
- package/web/dist/assets/index-DrMc2vuA.js +0 -23
package/dist/cli/index.js
CHANGED
|
@@ -1261,7 +1261,7 @@ var RunnerConfigSchema = z10.object({
|
|
|
1261
1261
|
});
|
|
1262
1262
|
|
|
1263
1263
|
// packages/shared/dist/version.js
|
|
1264
|
-
var STELLARIS_VERSION = "0.3.
|
|
1264
|
+
var STELLARIS_VERSION = "0.3.5";
|
|
1265
1265
|
|
|
1266
1266
|
// packages/board-core/dist/errors.js
|
|
1267
1267
|
var BoardError = class extends Error {
|
|
@@ -2315,6 +2315,8 @@ var SignInsSchema = z12.object({
|
|
|
2315
2315
|
signIns: z12.array(z12.object({
|
|
2316
2316
|
tokenHash: z12.string().min(1),
|
|
2317
2317
|
login: z12.string().min(1),
|
|
2318
|
+
/** The account's picture at the identity provider; sign-ins from before it have none. */
|
|
2319
|
+
avatarUrl: z12.url().optional(),
|
|
2318
2320
|
createdAt: IsoDateTimeSchema,
|
|
2319
2321
|
expiresAt: IsoDateTimeSchema
|
|
2320
2322
|
})).default([])
|
|
@@ -2934,23 +2936,36 @@ ${charter.purpose}
|
|
|
2934
2936
|
* token, shown once. Only its hash is kept, in `state/sign-ins.json`, so a sign-in outlives a
|
|
2935
2937
|
* restart; it acts as the user, like the user's own token, until it expires or is signed out.
|
|
2936
2938
|
*/
|
|
2937
|
-
async signIn(login, ttlMs) {
|
|
2939
|
+
async signIn(login, ttlMs, avatarUrl) {
|
|
2938
2940
|
return this.mutex.run(async () => {
|
|
2939
2941
|
const token = mintToken();
|
|
2940
2942
|
const now = this.now().getTime();
|
|
2941
2943
|
const record = {
|
|
2942
2944
|
tokenHash: hashToken(token),
|
|
2943
2945
|
login,
|
|
2946
|
+
...avatarUrl === void 0 ? {} : { avatarUrl },
|
|
2944
2947
|
createdAt: new Date(now).toISOString(),
|
|
2945
2948
|
expiresAt: new Date(now + ttlMs).toISOString()
|
|
2946
2949
|
};
|
|
2947
2950
|
const live = (await this.readSignIns()).filter((each) => Date.parse(each.expiresAt) > now);
|
|
2948
2951
|
await writeJson(this.signInsFile(), { signIns: [...live, record] });
|
|
2949
|
-
this.signIns.set(record.tokenHash, {
|
|
2952
|
+
this.signIns.set(record.tokenHash, {
|
|
2953
|
+
login,
|
|
2954
|
+
avatarUrl,
|
|
2955
|
+
expiresAt: Date.parse(record.expiresAt)
|
|
2956
|
+
});
|
|
2950
2957
|
await this.events.append("user.signed_in", USER_NAME, { login });
|
|
2951
2958
|
return token;
|
|
2952
2959
|
});
|
|
2953
2960
|
}
|
|
2961
|
+
/** Who a token signed in as, while its sign-in lasts; null for any other token. */
|
|
2962
|
+
signInOf(token) {
|
|
2963
|
+
const signIn = this.signIns.get(hashToken(token));
|
|
2964
|
+
if (signIn === void 0 || signIn.expiresAt <= this.now().getTime()) {
|
|
2965
|
+
return null;
|
|
2966
|
+
}
|
|
2967
|
+
return { login: signIn.login, avatarUrl: signIn.avatarUrl };
|
|
2968
|
+
}
|
|
2954
2969
|
/** Ends the sign-in a token belongs to; false for a token that is no sign-in's. */
|
|
2955
2970
|
async signOut(token) {
|
|
2956
2971
|
const hash = hashToken(token);
|
|
@@ -2996,7 +3011,11 @@ ${charter.purpose}
|
|
|
2996
3011
|
for (const signIn of await this.readSignIns()) {
|
|
2997
3012
|
const expiresAt = Date.parse(signIn.expiresAt);
|
|
2998
3013
|
if (expiresAt > now) {
|
|
2999
|
-
this.signIns.set(signIn.tokenHash, {
|
|
3014
|
+
this.signIns.set(signIn.tokenHash, {
|
|
3015
|
+
login: signIn.login,
|
|
3016
|
+
avatarUrl: signIn.avatarUrl,
|
|
3017
|
+
expiresAt
|
|
3018
|
+
});
|
|
3000
3019
|
}
|
|
3001
3020
|
}
|
|
3002
3021
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -1341,7 +1341,7 @@ var RunnerConfigSchema = z10.object({
|
|
|
1341
1341
|
});
|
|
1342
1342
|
|
|
1343
1343
|
// packages/shared/dist/version.js
|
|
1344
|
-
var STELLARIS_VERSION = "0.3.
|
|
1344
|
+
var STELLARIS_VERSION = "0.3.5";
|
|
1345
1345
|
|
|
1346
1346
|
// packages/board-core/dist/errors.js
|
|
1347
1347
|
var BoardError = class extends Error {
|
|
@@ -2398,6 +2398,8 @@ var SignInsSchema = z12.object({
|
|
|
2398
2398
|
signIns: z12.array(z12.object({
|
|
2399
2399
|
tokenHash: z12.string().min(1),
|
|
2400
2400
|
login: z12.string().min(1),
|
|
2401
|
+
/** The account's picture at the identity provider; sign-ins from before it have none. */
|
|
2402
|
+
avatarUrl: z12.url().optional(),
|
|
2401
2403
|
createdAt: IsoDateTimeSchema,
|
|
2402
2404
|
expiresAt: IsoDateTimeSchema
|
|
2403
2405
|
})).default([])
|
|
@@ -3017,23 +3019,36 @@ ${charter.purpose}
|
|
|
3017
3019
|
* token, shown once. Only its hash is kept, in `state/sign-ins.json`, so a sign-in outlives a
|
|
3018
3020
|
* restart; it acts as the user, like the user's own token, until it expires or is signed out.
|
|
3019
3021
|
*/
|
|
3020
|
-
async signIn(login, ttlMs) {
|
|
3022
|
+
async signIn(login, ttlMs, avatarUrl) {
|
|
3021
3023
|
return this.mutex.run(async () => {
|
|
3022
3024
|
const token = mintToken();
|
|
3023
3025
|
const now = this.now().getTime();
|
|
3024
3026
|
const record = {
|
|
3025
3027
|
tokenHash: hashToken(token),
|
|
3026
3028
|
login,
|
|
3029
|
+
...avatarUrl === void 0 ? {} : { avatarUrl },
|
|
3027
3030
|
createdAt: new Date(now).toISOString(),
|
|
3028
3031
|
expiresAt: new Date(now + ttlMs).toISOString()
|
|
3029
3032
|
};
|
|
3030
3033
|
const live = (await this.readSignIns()).filter((each) => Date.parse(each.expiresAt) > now);
|
|
3031
3034
|
await writeJson(this.signInsFile(), { signIns: [...live, record] });
|
|
3032
|
-
this.signIns.set(record.tokenHash, {
|
|
3035
|
+
this.signIns.set(record.tokenHash, {
|
|
3036
|
+
login,
|
|
3037
|
+
avatarUrl,
|
|
3038
|
+
expiresAt: Date.parse(record.expiresAt)
|
|
3039
|
+
});
|
|
3033
3040
|
await this.events.append("user.signed_in", USER_NAME, { login });
|
|
3034
3041
|
return token;
|
|
3035
3042
|
});
|
|
3036
3043
|
}
|
|
3044
|
+
/** Who a token signed in as, while its sign-in lasts; null for any other token. */
|
|
3045
|
+
signInOf(token) {
|
|
3046
|
+
const signIn = this.signIns.get(hashToken(token));
|
|
3047
|
+
if (signIn === void 0 || signIn.expiresAt <= this.now().getTime()) {
|
|
3048
|
+
return null;
|
|
3049
|
+
}
|
|
3050
|
+
return { login: signIn.login, avatarUrl: signIn.avatarUrl };
|
|
3051
|
+
}
|
|
3037
3052
|
/** Ends the sign-in a token belongs to; false for a token that is no sign-in's. */
|
|
3038
3053
|
async signOut(token) {
|
|
3039
3054
|
const hash = hashToken(token);
|
|
@@ -3079,7 +3094,11 @@ ${charter.purpose}
|
|
|
3079
3094
|
for (const signIn of await this.readSignIns()) {
|
|
3080
3095
|
const expiresAt = Date.parse(signIn.expiresAt);
|
|
3081
3096
|
if (expiresAt > now) {
|
|
3082
|
-
this.signIns.set(signIn.tokenHash, {
|
|
3097
|
+
this.signIns.set(signIn.tokenHash, {
|
|
3098
|
+
login: signIn.login,
|
|
3099
|
+
avatarUrl: signIn.avatarUrl,
|
|
3100
|
+
expiresAt
|
|
3101
|
+
});
|
|
3083
3102
|
}
|
|
3084
3103
|
}
|
|
3085
3104
|
}
|
|
@@ -6520,13 +6539,20 @@ var Scheduler = class {
|
|
|
6520
6539
|
if (taskId !== null && !settled) {
|
|
6521
6540
|
await this.wakeStage(taskId, event.actor, now);
|
|
6522
6541
|
}
|
|
6542
|
+
if (taskId !== null) {
|
|
6543
|
+
await this.pruneStageWakes(taskId);
|
|
6544
|
+
}
|
|
6523
6545
|
return;
|
|
6524
6546
|
}
|
|
6525
6547
|
case "task.claimed": {
|
|
6526
6548
|
const taskId = stringOf(payload["taskId"]);
|
|
6527
|
-
if (taskId
|
|
6549
|
+
if (taskId === null) {
|
|
6550
|
+
return;
|
|
6551
|
+
}
|
|
6552
|
+
if (stringOf(payload["thread"]) !== taskId) {
|
|
6528
6553
|
await this.wakeHolder(taskId, event.actor, now);
|
|
6529
6554
|
}
|
|
6555
|
+
await this.pruneStageWakes(taskId);
|
|
6530
6556
|
return;
|
|
6531
6557
|
}
|
|
6532
6558
|
case "task.completing": {
|
|
@@ -6534,6 +6560,7 @@ var Scheduler = class {
|
|
|
6534
6560
|
const project = stringOf(payload["project"]);
|
|
6535
6561
|
if (taskId !== null && project !== null) {
|
|
6536
6562
|
this.completions.set(taskId, { project, actor: event.actor });
|
|
6563
|
+
await this.pruneStageWakes(taskId);
|
|
6537
6564
|
}
|
|
6538
6565
|
return;
|
|
6539
6566
|
}
|
|
@@ -6545,6 +6572,7 @@ var Scheduler = class {
|
|
|
6545
6572
|
return;
|
|
6546
6573
|
}
|
|
6547
6574
|
delete this.state.releaseCounts[taskId];
|
|
6575
|
+
await this.pruneStageWakes(taskId);
|
|
6548
6576
|
if (creator !== null && creator !== event.actor) {
|
|
6549
6577
|
await this.wakeCreator(taskId, project, creator, event.actor, now);
|
|
6550
6578
|
}
|
|
@@ -6555,6 +6583,9 @@ var Scheduler = class {
|
|
|
6555
6583
|
if (taskId !== null && payload["to"] === "abandoned") {
|
|
6556
6584
|
delete this.state.releaseCounts[taskId];
|
|
6557
6585
|
}
|
|
6586
|
+
if (taskId !== null) {
|
|
6587
|
+
await this.pruneStageWakes(taskId);
|
|
6588
|
+
}
|
|
6558
6589
|
return;
|
|
6559
6590
|
}
|
|
6560
6591
|
case "task.released":
|
|
@@ -6769,6 +6800,25 @@ var Scheduler = class {
|
|
|
6769
6800
|
}, now, { id: task.id, task: scope === task.project });
|
|
6770
6801
|
return sessionKey(agent.name, scope, task.id);
|
|
6771
6802
|
}
|
|
6803
|
+
/**
|
|
6804
|
+
* Drops each queued turn made only of stage wakes, one of them for this task, once none of its
|
|
6805
|
+
* stages waits for its citizen any more: as soon as an event about the task could have changed
|
|
6806
|
+
* that, the stage taken by anyone, the plan moved on or reshaped, the task ended, rather than
|
|
6807
|
+
* only at dispatch, so a wake that will not run leaves the queue at once.
|
|
6808
|
+
*/
|
|
6809
|
+
async pruneStageWakes(taskId) {
|
|
6810
|
+
for (const [key, item] of this.pending) {
|
|
6811
|
+
const wakes = item.stageWakes;
|
|
6812
|
+
if (wakes === void 0 || !wakes.some((wake) => wake.taskId === taskId)) {
|
|
6813
|
+
continue;
|
|
6814
|
+
}
|
|
6815
|
+
const due = await this.stillWaiting(item.dispatch.agent, wakes, item.holder === true);
|
|
6816
|
+
if (due === void 0 && this.pending.get(key) === item) {
|
|
6817
|
+
this.pending.delete(key);
|
|
6818
|
+
this.log.info({ agent: item.dispatch.agent, project: item.dispatch.project, taskId }, "dropping stage wake, the stage no longer waits for this agent");
|
|
6819
|
+
}
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6772
6822
|
/**
|
|
6773
6823
|
* The first of these stage wakes still due: its task waits, unheld, on a stage the agent may
|
|
6774
6824
|
* hold, or, with `holder`, the agent holds it, having claimed it outside the task's conversation.
|
|
@@ -8929,7 +8979,19 @@ var SIGN_IN_TTL_MS = 30 * 24 * 36e5;
|
|
|
8929
8979
|
var STATE_TTL_MS = 10 * 6e4;
|
|
8930
8980
|
var MAX_STATES = 1e3;
|
|
8931
8981
|
var TokenAnswerSchema = z14.object({ access_token: z14.string().min(1) });
|
|
8932
|
-
var GithubUserSchema = z14.object({
|
|
8982
|
+
var GithubUserSchema = z14.object({
|
|
8983
|
+
login: z14.string().min(1),
|
|
8984
|
+
id: z14.number().int(),
|
|
8985
|
+
avatar_url: z14.string().optional()
|
|
8986
|
+
});
|
|
8987
|
+
function githubAvatar(url) {
|
|
8988
|
+
try {
|
|
8989
|
+
const parsed = new URL(url ?? "");
|
|
8990
|
+
return parsed.protocol === "https:" && parsed.hostname === "avatars.githubusercontent.com" ? parsed.href : void 0;
|
|
8991
|
+
} catch {
|
|
8992
|
+
return void 0;
|
|
8993
|
+
}
|
|
8994
|
+
}
|
|
8933
8995
|
function safeNext(next) {
|
|
8934
8996
|
return next !== void 0 && /^\/(?![/\\])/.test(next) ? next : "/";
|
|
8935
8997
|
}
|
|
@@ -8973,6 +9035,7 @@ function githubAuthRoutes(options) {
|
|
|
8973
9035
|
}
|
|
8974
9036
|
let login;
|
|
8975
9037
|
let id;
|
|
9038
|
+
let avatar;
|
|
8976
9039
|
try {
|
|
8977
9040
|
const tokenAnswer = await fetchImpl("https://github.com/login/oauth/access_token", {
|
|
8978
9041
|
method: "POST",
|
|
@@ -8994,7 +9057,9 @@ function githubAuthRoutes(options) {
|
|
|
8994
9057
|
if (!userAnswer.ok) {
|
|
8995
9058
|
throw new Error(`GitHub answered ${userAnswer.status} for the user`);
|
|
8996
9059
|
}
|
|
8997
|
-
|
|
9060
|
+
const user = GithubUserSchema.parse(await userAnswer.json());
|
|
9061
|
+
({ login, id } = user);
|
|
9062
|
+
avatar = githubAvatar(user.avatar_url);
|
|
8998
9063
|
} catch (error) {
|
|
8999
9064
|
options.log?.warn({ error: String(error) }, "GitHub sign-in failed");
|
|
9000
9065
|
return land(c, pending.next, "signin-error=github");
|
|
@@ -9003,7 +9068,7 @@ function githubAuthRoutes(options) {
|
|
|
9003
9068
|
options.log?.warn({ login }, "GitHub sign-in refused a login that is not on the list");
|
|
9004
9069
|
return land(c, pending.next, "signin-error=not-allowed");
|
|
9005
9070
|
}
|
|
9006
|
-
const token = await board2.signIn(login, SIGN_IN_TTL_MS);
|
|
9071
|
+
const token = await board2.signIn(login, SIGN_IN_TTL_MS, avatar);
|
|
9007
9072
|
return land(c, pending.next, `session=${encodeURIComponent(token)}`);
|
|
9008
9073
|
});
|
|
9009
9074
|
return routes;
|
|
@@ -9429,7 +9494,16 @@ function createApp(deps) {
|
|
|
9429
9494
|
};
|
|
9430
9495
|
const api = new Hono3();
|
|
9431
9496
|
api.use("*", authenticate);
|
|
9432
|
-
api.get("/me", (c) =>
|
|
9497
|
+
api.get("/me", (c) => {
|
|
9498
|
+
const signIn = board2.signInOf(bearer2(c) ?? "");
|
|
9499
|
+
return c.json(signIn === null ? c.get("actor") : {
|
|
9500
|
+
...c.get("actor"),
|
|
9501
|
+
signIn: {
|
|
9502
|
+
login: signIn.login,
|
|
9503
|
+
avatarUrl: signIn.avatarUrl ?? `https://github.com/${encodeURIComponent(signIn.login)}.png`
|
|
9504
|
+
}
|
|
9505
|
+
});
|
|
9506
|
+
});
|
|
9433
9507
|
api.delete("/sign-in", async (c) => c.json({ signedOut: await board2.signOut(bearer2(c) ?? "") }));
|
|
9434
9508
|
api.get("/society", async (c) => c.json(await board2.society()));
|
|
9435
9509
|
api.get("/agents", async (c) => c.json((await board2.listAgents()).map(({ tokenHash: _hash, ...agent }) => agent)));
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_n as e,b as t,wt as n}from"./format-11lojpK1.js";import{L as r,S as i,n as a,r as o,t as s}from"./index-BXq4t0NA.js";var c=e(),l=`grid size-7 shrink-0 place-items-center rounded-lg text-fg-tertiary hover:bg-surface-2/70 hover:text-fg-primary`;function u({fallback:e}){let u=n(),d=r({select:e=>e.location.state.__TSR_index}),f=o(),p=i(),m=t(),h=a(f,d);if(h===null)return e;let g=s(h,{entity:e=>p.get(e)?.title,project:e=>m.data?.find(t=>t.slug===e)?.name});return(0,c.jsx)(`button`,{type:`button`,onClick:()=>u.history.back(),"aria-label":`Back to ${g}`,title:`Back to ${g}`,className:l,children:`←`})}export{u as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{D as e,F as t,R as n,Xt as r,_n as i,b as a,h as o,vn as s,xn as c,y as l}from"./format-11lojpK1.js";import{B as u,I as d,c as f,i as p}from"./index-BXq4t0NA.js";import{t as m}from"./MessageItem-Deq-ntT8.js";import{n as h,t as g}from"./Pane-B-pz52UC.js";import{n as _}from"./ThreadCard-BTGP4fOT.js";import{i as v}from"./ThreadForms-BipMby65.js";import{t as y}from"./useStickyScroll-D_7q2RKi.js";var b=c(s(),1),x=i();function S(){let{_splat:e=`general`}=u({from:`/c/$`});return(0,x.jsx)(C,{channel:e},e)}function C({channel:i}){let{api:s}=e(),c=r({queryKey:[`channel`,i],queryFn:()=>s.channel(i)}),u=t(),S=o(),C=a(),w=l(3e4),[T,E]=(0,b.useState)(!1),D=(0,b.useMemo)(()=>{let e=(c.data??[]).map(e=>({kind:`message`,at:e.ts,id:e.id,message:e})),t=(u.data??[]).filter(e=>e.channel===i).map(e=>({kind:`thread`,at:e.openedAt,id:e.id,thread:e}));return[...e,...t].toSorted((e,t)=>e.at.localeCompare(t.at)||e.id.localeCompare(t.id))},[c.data,u.data,i]),O=c.data?.at(-1)?.id??null;(0,b.useEffect)(()=>d(i,O),[i,O]);let{ref:k,onScroll:A}=y(),[j,M]=i.split(`/`),N=M??j??i,P=M===void 0?void 0:C.data?.find(e=>e.slug===j),F=M===void 0?`society`:P?.name??j,I=P?.archived!==void 0,L=D.filter(e=>e.kind===`thread`&&e.thread.state===`open`);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(g,{title:`# ${N}`,subtitle:`${F} · ${c.data?.length??0} messages${L.length>0?` · ${L.length} open threads`:``}`,trailing:T||I?null:(0,x.jsx)(f,{onClick:()=>E(!0),children:`New thread`})}),T?(0,x.jsx)(v,{channel:i,onDone:()=>E(!1)}):null,(0,x.jsx)(`div`,{ref:k,onScroll:A,className:`flex-1 overflow-y-auto py-2`,children:c.error instanceof n&&c.error.status===404?(0,x.jsxs)(h,{children:[`There is no channel `,i,`.`]}):c.data===void 0?(0,x.jsx)(h,{children:`Reading the channel…`}):D.length===0?(0,x.jsx)(h,{children:`Nothing has been said here yet.`}):D.map(e=>e.kind===`message`?(0,x.jsx)(m,{message:e.message,members:S.data,now:w},e.id):(0,x.jsx)(_,{thread:e.thread,now:w},e.id))}),c.data===void 0?null:I?(0,x.jsxs)(`p`,{className:`border-t border-line px-4 py-3 text-meta`,children:[F,` is archived, so its channels are read-only.`]}):(0,x.jsx)(p,{target:{channel:i},placeholder:`Message #${N}`})]})}export{S as ChannelView};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{D as e,E as t,H as n,I as r,L as i,P as a,R as o,St as s,T as c,_n as l,a as u,d,f,g as p,gn as m,h,st as g,t as _,u as v,v as y,vn as b,w as x,xn as S,y as C}from"./format-11lojpK1.js";import{B as w,S as T,T as E,V as D,_ as O,c as k,f as A,g as ee,h as te,i as ne,m as j,p as M,v as N,x as P,y as F,z as re}from"./index-BXq4t0NA.js";import{t as I}from"./Markdown-MZnGPfvk.js";import{n as L,t as ie}from"./Pane-B-pz52UC.js";import{n as ae,r as R}from"./ThreadForms-BipMby65.js";import{t as oe}from"./useStickyScroll-D_7q2RKi.js";import{a as z,c as B,n as se,o as ce,r as le,s as ue,t as de}from"./citizen-CYBzbWt-.js";var V=S(b(),1),H=l(),fe={completed:`completed`,timeout:`timed out`,error:`failed`,interrupted:`was interrupted`,blocked:`was blocked`,stopped:`was stopped by you`};function U(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1})}function W({label:e,tone:t,children:n}){return(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`p`,{className:`px-0.5 pb-0.5 text-[10px] tracking-wider text-fg-muted uppercase`,children:e}),(0,H.jsx)(`pre`,{className:`max-h-72 overflow-auto rounded-md bg-surface-0/60 p-2 font-mono text-[11px] leading-relaxed whitespace-pre-wrap break-words ${t}`,children:n})]})}function pe({step:e,open:t}){if(e.kind===`say`)return(0,H.jsx)(`li`,{className:`py-1.5 text-sm`,title:U(e.at),children:(0,H.jsx)(I,{text:e.text})});if(e.kind===`error`)return(0,H.jsx)(`li`,{className:`py-1 font-mono text-xs break-words text-red-400`,title:U(e.at),children:e.message});if(e.kind===`steer`)return(0,H.jsx)(`li`,{children:(0,H.jsxs)(`details`,{open:t,className:`group rounded-md open:bg-surface-2/30`,children:[(0,H.jsxs)(`summary`,{className:`flex cursor-pointer list-none items-center gap-2 rounded-md px-1.5 py-1 text-xs hover:bg-surface-2/40`,children:[(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`grid w-3 shrink-0 place-items-center text-sky-300`,children:`↳`}),(0,H.jsxs)(`span`,{className:`shrink-0 text-fg-tertiary`,children:[`Took `,te(e.posts.length)]}),(0,H.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-fg-secondary`,children:e.from.length===0?``:`from ${e.from.join(`, `)}, delivered mid-turn`}),(0,H.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-fg-muted`,children:U(e.at)})]}),(0,H.jsx)(`ul`,{className:`space-y-1.5 px-1.5 pb-1.5`,children:e.posts.map(e=>(0,H.jsxs)(`li`,{className:`rounded-md bg-surface-0/40 px-2.5 py-2`,children:[(0,H.jsxs)(`p`,{className:`flex gap-1.5 text-meta`,children:[(0,H.jsx)(`span`,{className:`text-fg-secondary`,children:e.author}),(0,H.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`in `,e.where]}),e.at===``?null:(0,H.jsx)(`span`,{className:`ml-auto shrink-0 font-mono`,children:U(e.at)})]}),(0,H.jsx)(`div`,{className:`mt-1 text-sm`,children:(0,H.jsx)(I,{text:e.body})})]},`${e.at}-${e.author}`))})]})});let n=e.ok===null?(0,H.jsx)(`span`,{"aria-label":`running`,className:`size-1.5 animate-pulse rounded-full bg-amber-300`}):e.ok?(0,H.jsx)(`span`,{"aria-label":`succeeded`,className:`text-[11px] text-emerald-400`,children:`✓`}):(0,H.jsx)(`span`,{"aria-label":`failed`,className:`text-[11px] text-red-400`,children:`✕`});return(0,H.jsx)(`li`,{children:(0,H.jsxs)(`details`,{open:t,className:`group rounded-md open:bg-surface-2/30`,children:[(0,H.jsxs)(`summary`,{className:`flex cursor-pointer list-none items-center gap-2 rounded-md px-1.5 py-1 text-xs hover:bg-surface-2/40`,children:[(0,H.jsx)(`span`,{className:`grid w-3 shrink-0 place-items-center`,children:n}),(0,H.jsx)(`span`,{className:`shrink-0 font-mono text-fg-tertiary`,children:ee(e.name)}),(0,H.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-fg-secondary`,children:e.summary}),(0,H.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-fg-muted`,children:U(e.at)})]}),(0,H.jsxs)(`div`,{className:`space-y-1.5 px-1.5 pb-1.5`,children:[(0,H.jsx)(W,{label:`Input`,tone:`text-fg-secondary`,children:e.detail}),e.output===null?null:(0,H.jsx)(W,{label:e.ok===!1?`Returned an error`:`Returned`,tone:e.ok===!1?`text-red-300`:`text-fg-tertiary`,children:e.output})]})]})})}function G({steps:e}){let[t,n]=(0,V.useState)(!1),r=e.filter(e=>e.kind===`tool`).length;return e.length===0?(0,H.jsx)(`p`,{className:`mt-2 text-meta`,children:`No steps yet.`}):(0,H.jsxs)(H.Fragment,{children:[r===0?null:(0,H.jsxs)(`p`,{className:`mt-2 flex items-center gap-2 text-meta`,children:[r===1?`1 tool call`:`${r} tool calls`,(0,H.jsx)(`button`,{type:`button`,onClick:()=>n(!t),className:`rounded-md px-1.5 py-0.5 text-fg-tertiary transition-colors hover:bg-surface-2/60 hover:text-fg-primary`,children:t?`Collapse all`:`Expand all`})]}),(0,H.jsx)(`ol`,{className:`mt-1 space-y-0.5`,children:e.map(e=>(0,H.jsx)(pe,{step:e,open:t},e.seq))})]})}function me({turn:e,running:t,now:n}){if(e.end!==null){let t=e.end.costUsd>0?` · $${e.end.costUsd.toFixed(2)}`:``;return(0,H.jsxs)(`section`,{className:`mt-3 rounded-xl bg-surface-2/40 px-3.5 py-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)]`,children:[(0,H.jsxs)(`p`,{className:`text-caps`,children:[`The turn `,fe[e.end.exitReason],` `,_(e.end.at,n),t,e.fromStart?` · ${M(e.startedAt,Date.parse(e.end.at))}`:``]}),e.end.summary===null?null:(0,H.jsx)(`p`,{className:`mt-1 text-sm text-fg-secondary`,children:e.end.summary})]})}return t?(0,H.jsxs)(`p`,{className:`mt-3 flex items-center gap-2 text-meta`,"aria-live":`polite`,children:[(0,H.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-400`}),`Working · last step `,_(e.lastAt,n)]}):(0,H.jsx)(`p`,{className:`mt-3 text-meta`,children:`The turn ended without a report.`})}var K=30,he={turn:`turn`,board:`board`,merge:`both kept`},ge={turn:`Changed by a turn`,board:`Written by the board`,merge:`Both versions kept`};function _e(e){return e.status===`added`?`new`:e.status===`deleted`?`deleted`:e.added===null||e.removed===null?`binary`:`+${e.added} −${e.removed}`}function ve(e){return e.files.map(e=>`${e.path} ${_e(e)}`).join(`, `)}function ye(e){return e.startsWith(`@@`)||e.startsWith(`\\`)?`text-fg-muted`:e.startsWith(`+`)?`text-emerald-300`:e.startsWith(`-`)?`text-red-300`:`text-fg-tertiary`}function be({file:e}){return(0,H.jsxs)(`div`,{children:[(0,H.jsxs)(`p`,{className:`text-xs text-fg-secondary`,children:[e.path,e.status===`modified`?``:(0,H.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,e.status]})]}),e.patch===null?(0,H.jsx)(`p`,{className:`mt-1 text-meta`,children:`A binary file; its contents are not shown.`}):e.patch===``?(0,H.jsx)(`p`,{className:`mt-1 text-meta`,children:`Empty.`}):(0,H.jsx)(`pre`,{className:`mt-1 max-h-96 overflow-auto rounded-md bg-surface-0/60 p-2 font-mono text-[11px] leading-relaxed`,children:e.patch.split(`
|
|
2
|
+
`).map((e,t)=>(0,H.jsx)(`span`,{className:`block whitespace-pre-wrap break-words ${ye(e)}`,children:e===``?` `:e},t))}),e.truncated?(0,H.jsx)(`p`,{className:`mt-1 text-meta`,children:`The rest of this file's change is cut.`}):null]})}function xe({name:e,change:t}){let n=v(e,t.commit,!0);return(0,H.jsxs)(`div`,{className:`space-y-3 px-4 pt-1 pb-3`,children:[(0,H.jsxs)(`p`,{className:`text-xs text-fg-secondary`,children:[t.kind===`merge`?`Two turns on different runners changed the same lines at once. The file kept one turn's version, and this copy holds the other's until the citizen reconciles them.`:t.kind===`board`?`Written by the board: ${t.subject.replace(/^home: /,``)}.`:t.turnId===void 0?t.subject:(0,H.jsx)(s,{to:`/citizen/$name`,params:{name:e},search:{tab:`turns`,turn:t.turnId},className:`text-fg-secondary underline decoration-line underline-offset-2 hover:text-fg-primary`,children:`Open the turn that made it`}),(0,H.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,U(t.at)]})]}),n.data===void 0?(0,H.jsx)(`p`,{className:`text-meta`,children:n.isError?`Could not read the change.`:`Reading the change…`}):n.data.map(e=>(0,H.jsx)(be,{file:e},e.path))]})}function Se({name:e,change:t,now:n}){let[r,i]=(0,V.useState)(!1),a=t.files.length===0?t.subject:ve(t);return(0,H.jsx)(`li`,{className:`border-b border-line/60 last:border-b-0`,children:(0,H.jsxs)(`details`,{className:`group`,onToggle:e=>i(e.currentTarget.open),children:[(0,H.jsx)(`summary`,{"aria-label":`${ge[t.kind]} ${_(t.at,n)}: ${a}`,className:`block cursor-pointer list-none px-4 py-2.5 transition-colors hover:bg-surface-2/30 group-open:bg-surface-2/20`,children:(0,H.jsxs)(`span`,{className:`flex items-center gap-2 text-xs`,children:[(0,H.jsx)(`span`,{className:`shrink-0 text-fg-muted`,children:he[t.kind]}),(0,H.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-fg-secondary`,children:a}),(0,H.jsx)(`span`,{className:`shrink-0 text-fg-muted`,children:_(t.at,n)}),(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`shrink-0 text-[10px] text-fg-muted transition-transform group-open:rotate-90`,children:`▸`})]})}),r?(0,H.jsx)(xe,{name:e,change:t}):null]})})}function Ce({name:e}){let[t,n]=(0,V.useState)(K),r=f(e,t),i=C(3e4);if(r.data===void 0)return(0,H.jsx)(L,{children:r.isError?`Could not read the home's history.`:`Reading the history…`});let{changes:a,more:o}=r.data;return a.length===0?(0,H.jsxs)(L,{children:[e,`'s home has no history yet; it starts with the citizen's first turn.`]}):(0,H.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[(0,H.jsxs)(`p`,{className:`px-4 pt-3 pb-1 text-meta`,children:[`What `,e,`'s turns changed in its memory, skills, and profile, newest first.`]}),(0,H.jsx)(`ol`,{children:a.map(t=>(0,H.jsx)(Se,{name:e,change:t,now:i},t.commit))}),o?(0,H.jsx)(`button`,{type:`button`,onClick:()=>n(t+K),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:`Show earlier changes`}):null]})}function q({title:e,children:t}){return(0,H.jsxs)(`section`,{className:`border-t border-line pt-4 first:border-t-0 first:pt-0`,children:[(0,H.jsx)(`h3`,{className:`text-section`,children:e}),(0,H.jsx)(`div`,{className:`mt-2`,children:t})]})}function we({member:e,charter:t}){let n=p(e.name),r=u(e.name),i=d(e.name),a=C(3e4);return(0,H.jsxs)(`div`,{className:`flex-1 space-y-5 overflow-y-auto px-4 py-4`,children:[i.data===void 0||i.data.length===0?null:(0,H.jsxs)(q,{title:`Edits to reconcile`,children:[(0,H.jsxs)(`p`,{className:`text-sm text-fg-secondary`,children:[`Two turns on different runners changed these files at once. Each file kept one version; the other waits beside it until `,e.name,` merges it in and deletes the copy.`]}),(0,H.jsx)(`ul`,{className:`mt-2 space-y-1.5`,children:i.data.map(e=>(0,H.jsxs)(`li`,{className:`text-sm`,children:[(0,H.jsx)(`span`,{className:`text-fg-primary`,children:e.file}),(0,H.jsxs)(`span`,{className:`text-meta`,children:[` `,`· `,e.path.slice(e.path.lastIndexOf(`/`)+1),` · left`,` `,_(e.since,a)]})]},e.path))})]}),(0,H.jsx)(q,{title:`Profile`,children:e.profile.trim()===``?(0,H.jsx)(`p`,{className:`text-meta`,children:`No profile yet. The citizen writes its own profile.md.`}):(0,H.jsx)(I,{text:B(e.profile,`Profile`)})}),(0,H.jsx)(q,{title:`Core memory`,children:n.data===void 0?(0,H.jsx)(`p`,{className:`text-meta`,children:`Reading…`}):n.data.body.trim()===``?(0,H.jsx)(`p`,{className:`text-meta`,children:`Empty. Every turn loads this file in full.`}):(0,H.jsx)(I,{text:B(n.data.body,`Core memory`)})}),(0,H.jsx)(q,{title:`Own skills`,children:r.data===void 0?(0,H.jsx)(`p`,{className:`text-meta`,children:`Reading…`}):r.data.length===0?(0,H.jsx)(`p`,{className:`text-meta`,children:`None yet.`}):(0,H.jsx)(`ul`,{className:`space-y-1.5`,children:r.data.map(e=>(0,H.jsxs)(`li`,{className:`text-sm`,children:[(0,H.jsx)(`span`,{className:`text-fg-primary`,children:e.name}),e.summary===``?null:(0,H.jsxs)(`span`,{className:`text-fg-secondary`,children:[` · `,e.summary]})]},e.name))})}),t===void 0?null:(0,H.jsxs)(q,{title:`Charter of ${t.name}`,children:[(0,H.jsx)(`p`,{className:`text-sm text-fg-secondary`,children:t.purpose}),(0,H.jsxs)(`p`,{className:`mt-2 text-meta`,children:[`Wakes on mentions, stages, and `,t.wakeTriggers.join(`, `)||`nothing else`,t.resident?` · keeps a warm session`:``,t.reflects?` · reflects`:``]}),(0,H.jsx)(`p`,{className:`mt-2 flex flex-wrap gap-1`,children:t.verbs.map(e=>(0,H.jsx)(`span`,{className:`rounded-md bg-surface-2/70 px-1.5 py-px font-mono text-[11px] text-fg-tertiary`,children:e},e))})]})]})}function J(e,t){let n=r(e,t?.turnId??null);return{turn:(0,V.useMemo)(()=>t===void 0||n.data===void 0?void 0:O(n.data,e,t.project,t.thread),[t,n.data,e]),loading:t?.turnId!==void 0&&n.isPending,missing:t!==void 0&&(t.turnId===void 0||n.isError)}}var Y=50;function Te({name:e,entry:t,cli:n,now:r,opened:i}){let[a,o]=(0,V.useState)(i),s=(0,V.useRef)(null);(0,V.useEffect)(()=>{i&&s.current?.scrollIntoView({block:`start`})},[i]);let c=T(),l=ce(t),u=t.thread===void 0?null:c.get(t.thread)?.title??`a thread`,d=t.error??t.summary??``,f=t.error===null?`text-fg-secondary`:`text-red-300`;return(0,H.jsx)(`li`,{ref:s,className:`border-b border-line/60 last:border-b-0`,children:(0,H.jsxs)(`details`,{className:`group`,open:a,onToggle:e=>o(e.currentTarget.open),children:[(0,H.jsxs)(`summary`,{className:`block cursor-pointer list-none px-4 py-2.5 transition-colors hover:bg-surface-2/30 group-open:bg-surface-2/20`,children:[(0,H.jsxs)(`span`,{className:`flex items-center gap-2 text-xs`,children:[(0,H.jsxs)(`span`,{className:`min-w-0 truncate text-fg-secondary`,children:[z(t.project),u===null?``:` · ${u}`]}),(0,H.jsx)(`span`,{className:`text-fg-muted`,children:t.trigger}),(0,H.jsxs)(`span`,{className:`min-w-0 flex-1 truncate text-fg-muted`,children:[se(t),` `,_(t.ts,r)]}),(0,H.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-fg-tertiary`,children:[l,t.toolCalls===void 0?null:`${t.toolCalls} tools`,de(t,n)].filter(e=>e!==null).join(` · `)}),(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`shrink-0 text-[10px] text-fg-muted transition-transform group-open:rotate-90`,children:`▸`})]}),d.trim()===``?null:(0,H.jsx)(`span`,{className:`mt-1 line-clamp-2 block text-xs leading-relaxed group-open:hidden ${f}`,children:(0,H.jsx)(P,{text:d,links:!1})})]}),a?(0,H.jsx)(Ee,{name:e,entry:t,text:d,tone:f}):null]})})}function Ee({name:e,entry:t,text:n,tone:r}){let i=J(e,t);return(0,H.jsxs)(`div`,{className:`px-4 pt-1 pb-3`,children:[n.trim()===``?null:(0,H.jsx)(`p`,{className:`text-xs leading-relaxed whitespace-pre-wrap ${r}`,children:(0,H.jsx)(P,{text:n})}),(0,H.jsx)(`div`,{className:`mt-2`,children:t.turnId===void 0?(0,H.jsx)(`p`,{className:`text-meta`,children:`This turn ran before turns kept their steps.`}):i.loading?(0,H.jsx)(`p`,{className:`text-meta`,children:`Reading the steps…`}):i.turn===void 0?(0,H.jsx)(`p`,{className:`text-meta`,children:`No steps were kept for this turn.`}):(0,H.jsxs)(H.Fragment,{children:[t.startedAt===void 0?null:(0,H.jsxs)(`p`,{className:`text-caps`,children:[`Started `,U(t.startedAt)]}),(0,H.jsx)(G,{steps:i.turn.steps})]})})]})}function De({name:e,cli:t,opened:n}){let[r,a]=(0,V.useState)(Y),o=i(e,r),s=C(3e4);if(o.data===void 0)return(0,H.jsx)(L,{children:`Reading the turns…`});let c=o.data.toReversed();if(c.length===0)return(0,H.jsxs)(L,{children:[e,` has not finished a turn yet.`]});let l=le(c),u=t===`codex`?`unmetered`:`$${l.costUsd.toFixed(2)}`;return(0,H.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[(0,H.jsxs)(`p`,{className:`px-4 pt-3 pb-1 text-meta`,children:[l.turns===1?`1 turn`:`${l.turns} turns`,l.failed===0?``:`, ${l.failed} not completed`,` · `,u]}),n!==null&&!c.some(e=>e.turnId===n)?(0,H.jsx)(`p`,{className:`px-4 pb-1 text-meta`,children:o.data.length===r?`The turn this address opens is further back; show earlier turns to reach it.`:`The turn this address opens is not in this citizen's history.`}):null,(0,H.jsx)(`ol`,{children:c.map(r=>(0,H.jsx)(Te,{name:e,entry:r,cli:t,now:s,opened:n!==null&&r.turnId===n},r.id))}),o.data.length===r?(0,H.jsxs)(`button`,{type:`button`,onClick:()=>a(r+Y),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:[`Show `,Y,` earlier turns`]}):null]})}function Oe(e){return e===void 0?``:`${e.name}${e.id===null?``:` · ${e.id}`}`}function X({label:e,choices:t,value:n,onChange:r}){let[i,a]=(0,V.useState)(!1),o=(0,V.useRef)(null),s=(0,V.useRef)(null),c=(0,V.useRef)([]),l=t.findIndex(e=>e.value===n);(0,V.useEffect)(()=>{if(!i)return;c.current[Math.max(l,0)]?.focus();let e=e=>{e.target instanceof Node&&o.current?.contains(e.target)===!0||a(!1)};return window.addEventListener(`pointerdown`,e),()=>window.removeEventListener(`pointerdown`,e)},[i,l]);let u=e=>{if(e.key===`Escape`){e.stopPropagation(),a(!1),s.current?.focus();return}if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault();let n=(c.current.findIndex(e=>e===document.activeElement)+(e.key===`ArrowDown`?1:-1)+t.length)%t.length;c.current[n]?.focus()},d=t[l];return(0,H.jsxs)(`div`,{ref:o,className:`relative min-w-0 flex-1`,children:[(0,H.jsxs)(`button`,{ref:s,type:`button`,"aria-label":`${e}: ${Oe(d)}`,"aria-expanded":i,onClick:()=>a(!i),onKeyDown:i?u:void 0,className:`flex h-7 w-full items-center gap-1.5 rounded-md bg-surface-2/60 px-2.5 text-xs text-fg-secondary transition-colors hover:bg-surface-2 focus-visible:ring-2 focus-visible:ring-fg-primary/30 focus-visible:outline-none`,children:[(0,H.jsxs)(`span`,{className:`min-w-0 flex-1 truncate text-left`,children:[d?.name,d?.id===null||d===void 0?null:(0,H.jsxs)(`span`,{className:`text-fg-tertiary`,children:[` · `,d.id]})]}),(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`text-[10px] text-fg-muted transition-transform ${i?`rotate-180`:``}`,children:`▾`})]}),i?(0,H.jsx)(`div`,{className:`absolute inset-x-0 top-full z-20 mt-1 max-h-80 overflow-y-auto rounded-xl bg-surface-1/95 p-1 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.08),0_16px_32px_-12px_rgba(0,0,0,0.8)] backdrop-blur-xl`,children:t.map((e,t)=>{let i=e.value===n;return(0,H.jsxs)(`button`,{ref:e=>{c.current[t]=e},type:`button`,"aria-current":i?`true`:void 0,onKeyDown:u,onClick:()=>{r(e.value),a(!1),s.current?.focus()},className:`flex w-full items-start gap-2 rounded-lg px-2.5 py-1.5 text-left transition-colors focus-visible:outline-none ${i?`bg-surface-2/80`:`hover:bg-surface-2/50 focus-visible:bg-surface-2/50`}`,children:[(0,H.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,H.jsxs)(`span`,{className:`block truncate text-xs text-fg-secondary`,children:[e.name,e.id===null?null:(0,H.jsxs)(`span`,{className:`text-fg-tertiary`,children:[` · `,e.id]})]}),e.description===``?null:(0,H.jsx)(`span`,{className:`block truncate text-[11px] text-fg-muted`,children:e.description})]}),(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`w-3 shrink-0 pt-px text-[11px] text-fg-primary`,children:i?`✓`:``})]},e.value)})}):null]})}var Z=``;function ke(e,t){return[{value:Z,name:`CLI default`,id:e.find(e=>e.isDefault)?.name??null,description:`Whatever the CLI runs when no model is set.`},...e.map(e=>({value:e.id,name:e.name,id:e.name===e.id?null:e.id,description:e.description})),...t===null?[]:[{value:t,name:t,id:null,description:`Not in the CLI's list.`}]]}function Ae({member:t,onDone:n}){let{api:r}=e(),i=m(),a=y(t.cli),s=t.model??Z,[c,l]=(0,V.useState)(s),u=D({mutationFn:()=>r.setModel(t.name,c===Z?null:c),onSuccess:()=>{i.invalidateQueries({queryKey:[`members`]}),n()}}),d=a.data??[],f=t.model!==void 0&&!d.some(e=>e.id===t.model)?t.model:null;return(0,H.jsxs)(`form`,{"aria-label":`Model of ${t.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),u.mutate()},children:[(0,H.jsxs)(`div`,{className:`flex items-center gap-2`,children:[a.isPending?(0,H.jsxs)(`p`,{className:`min-w-0 flex-1 truncate text-meta`,children:[`Asking `,t.cli,` for its models…`]}):a.error===null?(0,H.jsx)(X,{label:`Model`,choices:ke(d,f),value:c,onChange:l}):(0,H.jsxs)(`p`,{role:`alert`,className:`min-w-0 flex-1 truncate text-xs text-red-400`,children:[t.cli,` did not list its models:`,` `,a.error instanceof o?a.error.message:`the board server did not answer`]}),(0,H.jsx)(k,{onClick:n,children:`Cancel`}),(0,H.jsx)(k,{variant:`primary`,type:`submit`,disabled:u.isPending||c===s||a.error!==null,children:u.isPending?`Saving…`:`Use this model`})]}),(0,H.jsx)(R,{error:u.error})]})}var Q=``;function je(e,t){let n=t.cli;return[e.status,e.clis.length===0?`offers no CLI yet`:e.clis.join(`, `),n!==null&&e.clis.length>0&&!e.clis.includes(n)?`has no ${n}`:``,e.capabilities.length===0?``:e.capabilities.join(`, `)].filter(e=>e!==``).join(` · `)}function Me(e,t){return[{value:Q,name:`Any runner`,id:null,description:`Pinned to the least busy runner on its next turn outside a project.`},...e.map(e=>({value:e.name,name:e.name,id:e.os,description:je(e,t)}))]}function Ne({member:t,onDone:n}){let{api:r}=e(),i=m(),a=c(),o=t.homeRunner??Q,[s,l]=(0,V.useState)(o),u=D({mutationFn:()=>r.setRunner(t.name,s===Q?null:s),onSuccess:()=>{i.invalidateQueries({queryKey:[`members`]}),n()}});return(0,H.jsxs)(`form`,{"aria-label":`Runner of ${t.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),u.mutate()},children:[(0,H.jsxs)(`div`,{className:`flex items-center gap-2`,children:[a.data===void 0?(0,H.jsx)(`p`,{className:`min-w-0 flex-1 truncate text-meta`,children:`Reading the runners…`}):(0,H.jsx)(X,{label:`Runner`,choices:Me(a.data,t),value:s,onChange:l}),(0,H.jsx)(k,{onClick:n,children:`Cancel`}),(0,H.jsx)(k,{variant:`primary`,type:`submit`,disabled:u.isPending||s===o,children:u.isPending?`Saving…`:`Run here`})]}),(0,H.jsx)(`p`,{className:`text-meta`,children:`Its conversations outside projects start afresh there from its next turn; its memory and skills follow it. Project work runs where each project lives.`}),(0,H.jsx)(R,{error:u.error})]})}function Pe(e){return e.thread===void 0?{channel:e.channel??(e.scope===`society`?`general`:`${e.scope}/general`)}:{threadId:e.thread}}function Fe({name:t,turn:n}){let{api:r}=e(),i=m(),[a,o]=(0,V.useState)(!1),s=D({mutationFn:()=>r.stopTurn(n.turnId),onSuccess:()=>{o(!1),i.invalidateQueries({queryKey:[`scheduler`]})}});return(0,H.jsxs)(`div`,{className:`border-t border-line`,children:[(0,H.jsx)(ne,{target:Pe(n),initialText:`@${t} `,placeholder:n.steerable?`Message ${t} while it works`:`Message ${t} for its next turn`,className:`px-3 pt-3 pb-2`},n.turnId),n.stoppable?(0,H.jsxs)(`div`,{className:`flex items-center gap-2 px-3 pb-3`,children:[(0,H.jsx)(`p`,{className:`min-w-0 flex-1 text-[11px] leading-snug text-fg-muted`,children:a?`Ends the turn now. What it was shown counts as read; its stages stay held.`:n.steerable?`Posts reach the turn at its next step.`:`This runner delivers posts after the turn ends.`}),a?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(k,{onClick:()=>{o(!1),s.reset()},children:`Keep it running`}),(0,H.jsx)(k,{variant:`primary`,disabled:s.isPending,onClick:()=>{s.mutate()},children:s.isPending?`Stopping…`:`Stop the turn`})]}):(0,H.jsx)(k,{onClick:()=>o(!0),children:`Stop…`})]}):null,s.error===null?null:(0,H.jsx)(`div`,{className:`px-3 pb-3`,children:(0,H.jsx)(R,{error:s.error})})]})}function Ie({member:t,scopes:n,preferred:r,running:i,paused:a,onDone:o}){let{api:s}=e(),c=m(),[l,u]=(0,V.useState)(`manual`),[d,f]=(0,V.useState)(r!==null&&n.includes(r)?r:n[0]??``),[p,h]=(0,V.useState)(``),g=(0,V.useRef)(null);(0,V.useEffect)(()=>g.current?.focus(),[]);let _=D({mutationFn:()=>s.wake({agent:t.name,project:d,kind:l,...p.trim()===``?{}:{reason:p.trim()}}),onSuccess:()=>{c.invalidateQueries({queryKey:[`scheduler`]}),o()}}),v=z(d),y=l===`reflection`?`Asks ${t.name} to reflect at ${v}: consolidate its memory, skills, and profile, and take no new work. It restarts the reflection clock.`:`Starts a turn for ${t.name} at ${v} as soon as the scheduler takes it.`,b=a?` The society is paused, so it waits until you resume.`:i.includes(d)?` ${t.name} is in a turn there now; this one follows it.`:``;return(0,H.jsxs)(`form`,{"aria-label":`Wake ${t.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),_.mutate()},children:[(0,H.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,H.jsxs)(`fieldset`,{className:`flex gap-1`,children:[(0,H.jsx)(`legend`,{className:`sr-only`,children:`Kind of turn`}),[`manual`,`reflection`].map(e=>(0,H.jsxs)(`label`,{className:`cursor-pointer rounded-md px-2.5 py-1 text-xs transition-colors has-focus-visible:ring-2 has-focus-visible:ring-fg-primary/30 ${l===e?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[(0,H.jsx)(`input`,{type:`radio`,name:`kind`,value:e,checked:l===e,onChange:()=>u(e),className:`sr-only`}),e===`manual`?`A turn`:`A reflection`]},e))]}),(0,H.jsxs)(`label`,{className:`ml-auto flex items-center gap-2 text-xs text-fg-tertiary`,children:[`at`,(0,H.jsx)(`select`,{value:d,onChange:e=>f(e.target.value),"aria-label":`Where`,className:`rounded-md bg-surface-2/60 px-2 py-1 text-xs text-fg-primary outline-none`,children:n.map(e=>(0,H.jsx)(`option`,{value:e,children:z(e)},e))})]})]}),(0,H.jsx)(`textarea`,{ref:g,value:p,rows:2,placeholder:l===`reflection`?`Anything to reflect on in particular? Optional.`:`What should it look at? It reads this as the reason it was woken.`,"aria-label":`Reason`,onChange:e=>h(e.target.value),className:`${ae} resize-none`}),(0,H.jsxs)(`p`,{className:`text-[11px] leading-relaxed text-fg-muted`,children:[y,b,` Each turn costs money.`]}),(0,H.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,H.jsx)(k,{onClick:o,children:`Cancel`}),(0,H.jsx)(k,{variant:`primary`,type:`submit`,disabled:_.isPending||d===``,children:_.isPending?`Waking…`:l===`reflection`?`Ask for a reflection`:`Wake ${t.name}`})]}),(0,H.jsx)(R,{error:_.error})]})}var Le={working:`bg-emerald-500/15 text-emerald-300`,queued:`bg-amber-500/15 text-amber-300`,idle:`bg-surface-2 text-fg-tertiary`};function Re({project:e,name:t}){let n=(a(e).data??[]).filter(e=>e.status===`claimed`&&e.claimedBy===t);return n.length===0?null:(0,H.jsx)(`ul`,{className:`mt-1.5 space-y-1`,children:n.map(e=>(0,H.jsx)(`li`,{children:(0,H.jsxs)(s,{to:`/task/$taskId`,params:{taskId:e.id},className:`flex items-center gap-2 rounded-md text-xs text-fg-secondary hover:text-fg-primary`,children:[(0,H.jsx)(`span`,{"aria-hidden":`true`,className:`text-fg-muted`,children:`◇`}),(0,H.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.title}),(0,H.jsx)(`span`,{className:`max-w-[40%] shrink-0 truncate font-mono text-[11px] text-fg-muted`,children:g(e)?.name??e.stage})]})},e.id))})}function ze(){let{name:e}=w({from:`/citizen/$name`}),{scope:t,tab:n,turn:r}=re({from:`/citizen/$name`});return(0,H.jsx)(Ve,{name:e,chosen:t??null,tab:n??`now`,turn:r??null},e)}var Be=[{tab:`now`,label:`Now`},{tab:`turns`,label:`Turns`},{tab:`memory`,label:`Memory`},{tab:`history`,label:`History`}];function Ve({name:e,chosen:r,tab:i,turn:a}){let o=h(),c=x(),l=t(),u=F(),[d,f]=(0,V.useState)(null),p=o.data?.find(t=>t.name===e);if(p===void 0)return(0,H.jsx)(L,{children:o.data===void 0?`Reading the roster…`:`There is no citizen ${e}.`});let m=n(l.data?.running??[]).filter(t=>t.agent===e),g=[...new Set(m.map(e=>e.scope))],_=m.map(e=>j(e.agent,e.scope,e.thread)),v=n(l.data?.pending??[]).find(t=>t.agent===e),y=g.length>0?`working`:v===void 0?`idle`:`queued`,b=N(u,e)[0],S=b?.model??p.lastModel,C=S??p.model??`CLI default`,w=p.model!==void 0&&p.model!==S?p.model:null,T=c.data?.find(e=>e.name===p.role),D=ue(p),O=p.status===`active`&&p.cli!==null;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(ie,{leading:p.cli===null?null:(0,H.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-lg bg-surface-2/70`,children:(0,H.jsx)(E,{cli:p.cli,size:20})}),title:e,subtitle:(0,H.jsxs)(H.Fragment,{children:[p.role,` · `,C,w===null?``:` · set to ${w}`,p.homeRunner===void 0?``:` · on ${p.homeRunner}`,p.status===`retired`?` · retired`:``]}),trailing:(0,H.jsxs)(H.Fragment,{children:[O&&d===null?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(k,{onClick:()=>f(`model`),children:`Model…`}),(0,H.jsx)(k,{onClick:()=>f(`runner`),children:`Runner…`}),(0,H.jsx)(k,{onClick:()=>f(`wake`),children:`Wake…`})]}):null,(0,H.jsx)(`span`,{className:`shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium ${Le[y]}`,children:y})]})}),d===`wake`?(0,H.jsx)(Ie,{member:p,scopes:D,preferred:r?.split(`/`)[0]??b?.scope??null,running:g,paused:l.data?.paused??!1,onDone:()=>f(null)}):d===`model`?(0,H.jsx)(Ae,{member:p,onDone:()=>f(null)}):d===`runner`?(0,H.jsx)(Ne,{member:p,onDone:()=>f(null)}):null,(0,H.jsx)(`nav`,{"aria-label":`Citizen views`,className:`flex gap-1 border-b border-line px-3 py-2`,children:Be.map(t=>(0,H.jsx)(s,{to:`/citizen/$name`,params:{name:e},search:{...r===null?{}:{scope:r},...t.tab===`now`?{}:{tab:t.tab}},replace:!0,"aria-current":t.tab===i?`page`:void 0,className:`rounded-md px-2.5 py-1 text-xs transition-colors ${t.tab===i?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:t.label},t.tab))}),i===`turns`?(0,H.jsx)(De,{name:e,cli:p.cli,opened:a},a):i===`memory`?(0,H.jsx)(we,{member:p,charter:T}):i===`history`?(0,H.jsx)(Ce,{name:e}):(0,H.jsx)(He,{name:e,chosen:r,lastTurnAt:p.lastTurnAt,state:y,runningScopes:g,runningKeys:_,runningTurns:(l.data?.turns??[]).filter(t=>t.agent===e),queuedScope:v?.scope??null})]})}function $(e){return e.toSorted((e,t)=>e.startedAt.localeCompare(t.startedAt))[0]}function He({name:e,chosen:t,lastTurnAt:n,state:r,runningScopes:a,runningKeys:o,runningTurns:c,queuedScope:l}){let u=F(),d=C(5e3),{ref:f,onScroll:p}=oe(),m=N(u,e),h=i(e,1),g=J(e,m.length===0?h.data?.at(-1):void 0),v=T(),y=e=>e.end===null&&o.includes(j(e.agent,e.scope,e.thread)),b=t?.split(`/`)[0]??null,x=(t?.includes(`/`)===!0?m.find(e=>A(e)===t):void 0)??$(m.filter(e=>e.scope===b&&y(e)))??m.find(e=>A(e)===t)??$(m.filter(y))??m[0]??g.turn,S=e=>e.thread===void 0?z(e.scope):`${z(e.scope)} · ${v.get(e.thread)?.title??`a thread`}`,w=x!==void 0&&y(x),E=x?.scope??a[0]??l,D=(x===void 0?void 0:c.find(e=>e.scope===x.scope&&e.thread===x.thread))??(w?void 0:c[0]);return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(`section`,{className:`border-b border-line px-4 py-3 text-xs text-fg-tertiary`,children:[(0,H.jsx)(`p`,{children:w?`In a turn at ${z(x.scope)} for ${x.fromStart?``:`at least `}${M(x.startedAt,d)}`:a.length>0?`In a turn at ${a.map(z).join(` and `)}`:l===null?n===void 0?`No turns yet`:`Last turn ${_(n,d)}`:`Queued for a turn at ${z(l)}`}),E===null||E===`society`?null:(0,H.jsx)(Re,{project:E,name:e})]}),(0,H.jsx)(`div`,{ref:f,onScroll:p,className:`flex-1 overflow-y-auto px-4 py-3`,children:x===void 0?(0,H.jsx)(L,{children:r===`working`?`The turn has not reported a step yet.`:g.loading?`Reading the last turn…`:n===void 0?`${e} has not taken a turn yet.`:`${e}'s last turn kept no steps; Turns lists every finished one.`}):(0,H.jsxs)(H.Fragment,{children:[m.length>1?(0,H.jsx)(`div`,{className:`mb-3 flex flex-wrap gap-1.5`,"aria-label":`Turns by conversation`,children:m.toSorted((e,t)=>A(e).localeCompare(A(t))).map(t=>(0,H.jsxs)(s,{to:`/citizen/$name`,params:{name:e},search:{scope:A(t)},replace:!0,"aria-current":t===x?`true`:void 0,className:`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[11px] transition-colors ${t===x?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[y(t)?(0,H.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-400`}):null,S(t)]},A(t)))}):null,(0,H.jsxs)(`p`,{className:`text-caps`,children:[w?`This turn`:`Last turn`,` · `,S(x),` · started`,` `,x.fromStart?U(x.startedAt):`before the earliest step shown`]}),x.fromStart?null:(0,H.jsxs)(`p`,{className:`mt-1 text-meta`,children:[`Earlier steps of this turn are no longer in the server's live buffer`,w?``:`; Turns has the whole turn`,`.`]}),(0,H.jsx)(G,{steps:x.steps}),(0,H.jsx)(me,{turn:x,running:w,now:d})]})}),D===void 0?null:(0,H.jsx)(Fe,{name:e,turn:D})]})}export{ze as CitizenView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{E as e,H as t,St as n,_n as r,b as i,h as a}from"./format-11lojpK1.js";import{T as o}from"./index-BXq4t0NA.js";import{n as s,t as c}from"./Pane-B-pz52UC.js";import{a as l,i as u}from"./citizen-CYBzbWt-.js";var d=r();function f(e){let t=e.lastModel??e.model??`CLI default`;return e.model!==void 0&&e.model!==t?`${t} · set to ${e.model}`:t}function p(e,t){return e.name.localeCompare(t.name)}function m(e,t){return e.role.localeCompare(t.role)||p(e,t)}function h(){let r=a(),h=e(),g=i();if(r.data===void 0)return(0,d.jsx)(s,{children:`Reading the roster…`});let _=r.data.filter(e=>e.cli!==null),v=_.filter(e=>e.status===`active`).toSorted(m),y=_.filter(e=>e.status!==`active`).toSorted(p),b=new Set(v.map(e=>e.role)).size,x=t(h.data?.running??[]),S=t(h.data?.pending??[]),C=new Map((g.data??[]).flatMap(e=>e.runner===void 0?[]:[[e.slug,e.runner]])),w=e=>{let t=[...new Set(x.filter(t=>t.agent===e.name).map(e=>e.scope))];return t.length>0?{label:`working`,detail:`in a turn at ${t.map(l).join(` and `)}`,tone:`text-emerald-300`}:S.some(t=>t.agent===e.name)?{label:`queued`,detail:`queued for a turn`,tone:`text-amber-300`}:{label:`resting`,detail:`resting`,tone:`text-fg-muted`}};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(c,{title:`Citizens`,subtitle:`${v.length} active in ${b===1?`1 role`:`${b} roles`}${y.length===0?``:` · ${y.length} retired`}`}),(0,d.jsxs)(`div`,{className:`flex-1 overflow-y-auto px-2 py-2`,children:[v.length===0?(0,d.jsx)(`p`,{className:`px-2 py-2 text-meta`,children:`No citizens yet. Ask the concierge for one.`}):null,(0,d.jsx)(`ul`,{className:`grid grid-cols-[auto_auto_auto_minmax(0,max-content)_auto_minmax(3rem,1fr)_auto] gap-x-3`,children:v.map(e=>{let t=w(e),r=f(e),i=e.memberships.length===0?`no projects`:e.memberships.join(`, `),a=u(e,C);return(0,d.jsx)(`li`,{className:`col-span-full grid grid-cols-subgrid`,children:(0,d.jsxs)(n,{to:`/citizen/$name`,params:{name:e.name},className:`col-span-full grid grid-cols-subgrid items-center rounded-lg px-2 py-1.5 text-sm transition-colors hover:bg-surface-2/50`,children:[(0,d.jsx)(`span`,{className:`grid size-4 place-items-center`,children:e.cli===null?null:(0,d.jsx)(o,{cli:e.cli,size:13})}),(0,d.jsx)(`span`,{className:`text-fg-primary`,children:e.name}),(0,d.jsx)(`span`,{className:`text-fg-secondary`,children:e.role}),(0,d.jsx)(`span`,{className:`truncate text-xs text-fg-muted`,title:r,children:r}),(0,d.jsx)(`span`,{className:`text-xs text-fg-muted`,title:a.detail,children:a.label}),(0,d.jsx)(`span`,{className:`truncate text-xs text-fg-muted`,title:i,children:i}),(0,d.jsx)(`span`,{className:`text-right text-xs ${t.tone}`,title:t.detail,children:t.label})]})},e.name)})}),y.length===0?null:(0,d.jsxs)(`p`,{className:`mt-2 border-t border-line px-2 pt-2 text-meta`,children:[`Retired: `,y.map(e=>`${e.name} (${e.role})`).join(`, `)]})]})]})}export{h as CitizensView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{St as e,_n as t,at as n,b as r,p as i,t as a,y as o}from"./format-11lojpK1.js";import{B as s}from"./index-BXq4t0NA.js";import{t as c}from"./Markdown-MZnGPfvk.js";import{n as l,t as u}from"./Pane-B-pz52UC.js";import{t as d}from"./BackLink-DivaHiZ7.js";var f=t(),p=`grid size-7 shrink-0 place-items-center rounded-lg text-fg-tertiary hover:bg-surface-2/70 hover:text-fg-primary`;function m(){let{scope:t,topic:m}=s({from:`/knowledge/$scope/$topic`}),h=i(t),g=r(),_=o(3e4),v=t===n,y=v?`the society`:g.data?.find(e=>e.slug===t)?.name??t,b=h.data?.find(e=>e.topic===m),x=v?(0,f.jsx)(e,{to:`/society`,"aria-label":`Back to the society`,className:p,children:`←`}):(0,f.jsx)(e,{to:`/p/$slug`,params:{slug:t},"aria-label":`Back to ${y}`,className:p,children:`←`});return b===void 0?(0,f.jsx)(l,{children:h.data===void 0?`Reading…`:`${y} has no topic ${m}.`}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(u,{leading:(0,f.jsx)(d,{fallback:x}),title:b.topic,subtitle:`Knowledge of ${y} · written by ${b.updatedBy} ${a(b.updatedAt,_)}`}),(0,f.jsx)(`div`,{className:`flex-1 overflow-y-auto px-4 py-4`,children:(0,f.jsx)(c,{text:b.body})})]})}export{m as KnowledgeView};
|