@kubitnodes/stellaris 0.3.4 → 0.3.6
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 +70 -5
- package/dist/server/index.js +132 -10
- package/package.json +1 -1
- package/web/dist/assets/BackLink-Cr1RWb4K.js +1 -0
- package/web/dist/assets/ChannelView-iK3ug1lV.js +1 -0
- package/web/dist/assets/CitizenView-BiaYYmCh.js +2 -0
- package/web/dist/assets/CitizensView-CFrD6f7m.js +1 -0
- package/web/dist/assets/KnowledgeView-CR3cXdj0.js +1 -0
- package/web/dist/assets/{Markdown-BrvfGmz7.js → Markdown-CYcTTxcR.js} +4 -4
- package/web/dist/assets/MessageItem-DDC_1Jqn.js +1 -0
- package/web/dist/assets/MetricsView-xdvE7pFA.js +1 -0
- package/web/dist/assets/NeedsYouView-I7j_cnda.js +1 -0
- package/web/dist/assets/Overview-DI7LPNEY.js +1 -0
- package/web/dist/assets/{Pane-JzhKR0rO.js → Pane-BNjb76U4.js} +1 -1
- package/web/dist/assets/ProjectView-DYDcDsWg.js +1 -0
- package/web/dist/assets/ProposalView-DrP3Cv9y.js +1 -0
- package/web/dist/assets/ProposalsView-90rufsQN.js +1 -0
- package/web/dist/assets/RunnersView-iMbemuCe.js +1 -0
- package/web/dist/assets/{SocietyView-OCdDJqhz.js → SocietyView-C9FdIFZY.js} +1 -1
- package/web/dist/assets/SubjectThread-Bw6wEJpH.js +1 -0
- package/web/dist/assets/TaskFileView-D0n7kzt2.js +4 -0
- package/web/dist/assets/TaskView-BZ6U_XpQ.js +1 -0
- package/web/dist/assets/TasksView-CtGF3i-n.js +1 -0
- package/web/dist/assets/ThreadCard-FPtAzvNM.js +1 -0
- package/web/dist/assets/{ThreadForms-C4ytMMBB.js → ThreadForms-LFw2EF6r.js} +1 -1
- package/web/dist/assets/ThreadView-DnDx2SCv.js +1 -0
- package/web/dist/assets/citizen-Bm_r8vBY.js +1 -0
- package/web/dist/assets/format-Cj7NW9Y9.js +55 -0
- package/web/dist/assets/index-CthEgIzf.js +23 -0
- package/web/dist/assets/index-D4oCtkuZ.css +2 -0
- package/web/dist/assets/{tasks-Di8iatzY.js → tasks-tFehkpRz.js} +1 -1
- package/web/dist/assets/{useStickyScroll-BPuANcOs.js → useStickyScroll-XrG6M-hT.js} +1 -1
- package/web/dist/index.html +4 -4
- package/web/dist/assets/ChannelView-CZyYu_Zi.js +0 -1
- package/web/dist/assets/CitizenView-JsI89Tn3.js +0 -2
- package/web/dist/assets/CitizensView-7vHTRRIs.js +0 -1
- package/web/dist/assets/KnowledgeView-eBae2Dix.js +0 -1
- package/web/dist/assets/MessageItem-DXU3Ovq1.js +0 -1
- package/web/dist/assets/MetricsView-CxXGHRtN.js +0 -1
- package/web/dist/assets/NeedsYouView-R-oQddyC.js +0 -1
- package/web/dist/assets/Overview-D76LQcxp.js +0 -1
- package/web/dist/assets/ProjectView-vYKWw1Ck.js +0 -1
- package/web/dist/assets/ProposalView-dskJSjhm.js +0 -1
- package/web/dist/assets/ProposalsView-DQW7OmOU.js +0 -1
- package/web/dist/assets/RunnersView-BLwSywI7.js +0 -1
- package/web/dist/assets/SubjectThread-DQNXXY4q.js +0 -1
- package/web/dist/assets/TaskFileView-Bl1vm7Op.js +0 -4
- package/web/dist/assets/TaskView-Bq-vXuc5.js +0 -1
- package/web/dist/assets/TasksView-C1cdPYRc.js +0 -1
- package/web/dist/assets/ThreadCard-CliRbP_c.js +0 -1
- package/web/dist/assets/ThreadView-CvXd68Ml.js +0 -1
- package/web/dist/assets/citizen-TjyiyFqE.js +0 -1
- package/web/dist/assets/format-8m6fdeP8.js +0 -55
- package/web/dist/assets/index-CADeLxUP.js +0 -23
- package/web/dist/assets/index-iNICYkef.css +0 -2
package/dist/cli/index.js
CHANGED
|
@@ -301,11 +301,18 @@ function mayHoldStage(member, task2) {
|
|
|
301
301
|
return !(stage.gate && task2.stages.slice(0, index).some((s) => s.holders.includes(member.name)));
|
|
302
302
|
}
|
|
303
303
|
var ModelNameSchema = z3.string().trim().min(1).max(120).regex(/^[\w.:/[\]-]+$/, "a model name is one word of letters, digits, and . _ : / - [ ]");
|
|
304
|
+
var EffortSchema = z3.string().trim().min(1).max(32).regex(/^[a-z][a-z0-9_-]*$/, "an effort is one lowercase word, such as high");
|
|
305
|
+
var EffortOptionSchema = z3.object({
|
|
306
|
+
id: EffortSchema,
|
|
307
|
+
description: z3.string().default("")
|
|
308
|
+
});
|
|
304
309
|
var ModelOptionSchema = z3.object({
|
|
305
310
|
id: ModelNameSchema,
|
|
306
311
|
name: z3.string(),
|
|
307
312
|
description: z3.string().default(""),
|
|
308
|
-
isDefault: z3.boolean().default(false)
|
|
313
|
+
isDefault: z3.boolean().default(false),
|
|
314
|
+
efforts: z3.array(EffortOptionSchema).default([]),
|
|
315
|
+
defaultEffort: EffortSchema.optional()
|
|
309
316
|
});
|
|
310
317
|
var AgentStatusSchema = z3.enum(["active", "retired"]);
|
|
311
318
|
var AgentSchema = z3.object({
|
|
@@ -313,6 +320,8 @@ var AgentSchema = z3.object({
|
|
|
313
320
|
role: NameSchema,
|
|
314
321
|
cli: CliKindSchema.nullable(),
|
|
315
322
|
model: z3.string().optional(),
|
|
323
|
+
/** The reasoning effort set for the agent's turns; the model's own default applies otherwise. */
|
|
324
|
+
effort: z3.string().optional(),
|
|
316
325
|
/** The runner preferred for the agent's turns where nothing else decides; any runner with its CLI otherwise. */
|
|
317
326
|
homeRunner: NameSchema.optional(),
|
|
318
327
|
memberships: z3.array(NameSchema),
|
|
@@ -334,6 +343,8 @@ var MemberSchema = z3.object({
|
|
|
334
343
|
model: z3.string().optional(),
|
|
335
344
|
/** The model the CLI reported on the citizen's last turn. */
|
|
336
345
|
lastModel: z3.string().optional(),
|
|
346
|
+
/** The reasoning effort configured on the record, if any; the model's own default applies otherwise. */
|
|
347
|
+
effort: z3.string().optional(),
|
|
337
348
|
/** The citizen's own skills, by name. */
|
|
338
349
|
skills: z3.array(NameSchema).default([]),
|
|
339
350
|
memberships: z3.array(NameSchema),
|
|
@@ -845,6 +856,8 @@ var TurnJobSchema = z6.object({
|
|
|
845
856
|
role: NameSchema,
|
|
846
857
|
cli: CliKindSchema,
|
|
847
858
|
model: z6.string().optional(),
|
|
859
|
+
/** The reasoning effort set on the agent; absent for the model's own default. */
|
|
860
|
+
effort: z6.string().optional(),
|
|
848
861
|
/** A project slug, or the society scope. */
|
|
849
862
|
scope: NameSchema,
|
|
850
863
|
/** The thread whose conversation the turn is in; absent for the home conversation. */
|
|
@@ -1078,6 +1091,8 @@ var TurnHistoryEntrySchema = z7.object({
|
|
|
1078
1091
|
trigger: z7.string(),
|
|
1079
1092
|
exitReason: z7.string().nullable(),
|
|
1080
1093
|
costUsd: z7.number(),
|
|
1094
|
+
/** The tokens the turn used; absent for turns logged before turns recorded them. */
|
|
1095
|
+
usage: UsageSchema.optional(),
|
|
1081
1096
|
model: z7.string().nullable(),
|
|
1082
1097
|
summary: z7.string().nullable(),
|
|
1083
1098
|
error: z7.string().nullable(),
|
|
@@ -1261,7 +1276,7 @@ var RunnerConfigSchema = z10.object({
|
|
|
1261
1276
|
});
|
|
1262
1277
|
|
|
1263
1278
|
// packages/shared/dist/version.js
|
|
1264
|
-
var STELLARIS_VERSION = "0.3.
|
|
1279
|
+
var STELLARIS_VERSION = "0.3.6";
|
|
1265
1280
|
|
|
1266
1281
|
// packages/board-core/dist/errors.js
|
|
1267
1282
|
var BoardError = class extends Error {
|
|
@@ -2315,6 +2330,8 @@ var SignInsSchema = z12.object({
|
|
|
2315
2330
|
signIns: z12.array(z12.object({
|
|
2316
2331
|
tokenHash: z12.string().min(1),
|
|
2317
2332
|
login: z12.string().min(1),
|
|
2333
|
+
/** The account's picture at the identity provider; sign-ins from before it have none. */
|
|
2334
|
+
avatarUrl: z12.url().optional(),
|
|
2318
2335
|
createdAt: IsoDateTimeSchema,
|
|
2319
2336
|
expiresAt: IsoDateTimeSchema
|
|
2320
2337
|
})).default([])
|
|
@@ -2325,6 +2342,7 @@ var TurnHistoryPayloadSchema = z12.object({
|
|
|
2325
2342
|
trigger: z12.string().default("manual"),
|
|
2326
2343
|
exitReason: z12.string().nullable().default(null),
|
|
2327
2344
|
costUsd: z12.number().default(0),
|
|
2345
|
+
usage: UsageSchema.optional(),
|
|
2328
2346
|
model: z12.string().nullable().default(null),
|
|
2329
2347
|
summary: z12.string().nullable().default(null),
|
|
2330
2348
|
error: z12.string().nullable().default(null),
|
|
@@ -2934,23 +2952,36 @@ ${charter.purpose}
|
|
|
2934
2952
|
* token, shown once. Only its hash is kept, in `state/sign-ins.json`, so a sign-in outlives a
|
|
2935
2953
|
* restart; it acts as the user, like the user's own token, until it expires or is signed out.
|
|
2936
2954
|
*/
|
|
2937
|
-
async signIn(login, ttlMs) {
|
|
2955
|
+
async signIn(login, ttlMs, avatarUrl) {
|
|
2938
2956
|
return this.mutex.run(async () => {
|
|
2939
2957
|
const token = mintToken();
|
|
2940
2958
|
const now = this.now().getTime();
|
|
2941
2959
|
const record = {
|
|
2942
2960
|
tokenHash: hashToken(token),
|
|
2943
2961
|
login,
|
|
2962
|
+
...avatarUrl === void 0 ? {} : { avatarUrl },
|
|
2944
2963
|
createdAt: new Date(now).toISOString(),
|
|
2945
2964
|
expiresAt: new Date(now + ttlMs).toISOString()
|
|
2946
2965
|
};
|
|
2947
2966
|
const live = (await this.readSignIns()).filter((each) => Date.parse(each.expiresAt) > now);
|
|
2948
2967
|
await writeJson(this.signInsFile(), { signIns: [...live, record] });
|
|
2949
|
-
this.signIns.set(record.tokenHash, {
|
|
2968
|
+
this.signIns.set(record.tokenHash, {
|
|
2969
|
+
login,
|
|
2970
|
+
avatarUrl,
|
|
2971
|
+
expiresAt: Date.parse(record.expiresAt)
|
|
2972
|
+
});
|
|
2950
2973
|
await this.events.append("user.signed_in", USER_NAME, { login });
|
|
2951
2974
|
return token;
|
|
2952
2975
|
});
|
|
2953
2976
|
}
|
|
2977
|
+
/** Who a token signed in as, while its sign-in lasts; null for any other token. */
|
|
2978
|
+
signInOf(token) {
|
|
2979
|
+
const signIn = this.signIns.get(hashToken(token));
|
|
2980
|
+
if (signIn === void 0 || signIn.expiresAt <= this.now().getTime()) {
|
|
2981
|
+
return null;
|
|
2982
|
+
}
|
|
2983
|
+
return { login: signIn.login, avatarUrl: signIn.avatarUrl };
|
|
2984
|
+
}
|
|
2954
2985
|
/** Ends the sign-in a token belongs to; false for a token that is no sign-in's. */
|
|
2955
2986
|
async signOut(token) {
|
|
2956
2987
|
const hash = hashToken(token);
|
|
@@ -2996,7 +3027,11 @@ ${charter.purpose}
|
|
|
2996
3027
|
for (const signIn of await this.readSignIns()) {
|
|
2997
3028
|
const expiresAt = Date.parse(signIn.expiresAt);
|
|
2998
3029
|
if (expiresAt > now) {
|
|
2999
|
-
this.signIns.set(signIn.tokenHash, {
|
|
3030
|
+
this.signIns.set(signIn.tokenHash, {
|
|
3031
|
+
login: signIn.login,
|
|
3032
|
+
avatarUrl: signIn.avatarUrl,
|
|
3033
|
+
expiresAt
|
|
3034
|
+
});
|
|
3000
3035
|
}
|
|
3001
3036
|
}
|
|
3002
3037
|
}
|
|
@@ -4911,6 +4946,7 @@ ${rationale}`}`);
|
|
|
4911
4946
|
session: parsed.session,
|
|
4912
4947
|
exitReason: parsed.exitReason,
|
|
4913
4948
|
costUsd: parsed.costUsd,
|
|
4949
|
+
...parsed.usage === null ? {} : { usage: parsed.usage },
|
|
4914
4950
|
toolCalls: parsed.toolCalls,
|
|
4915
4951
|
model: parsed.model,
|
|
4916
4952
|
summary: parsed.status?.summary ?? null,
|
|
@@ -5367,6 +5403,7 @@ Short, curated, loaded on every turn. Keep entries that change future behavior a
|
|
|
5367
5403
|
resident: charter.resident,
|
|
5368
5404
|
...agent2.model === void 0 ? {} : { model: agent2.model },
|
|
5369
5405
|
...lastModel === void 0 ? {} : { lastModel },
|
|
5406
|
+
...agent2.effort === void 0 ? {} : { effort: agent2.effort },
|
|
5370
5407
|
skills: (await this.listAgentSkills(name)).map((skill) => skill.name),
|
|
5371
5408
|
memberships: agent2.memberships,
|
|
5372
5409
|
subscriptions: agent2.subscriptions,
|
|
@@ -5415,6 +5452,29 @@ Short, curated, loaded on every turn. Keep entries that change future behavior a
|
|
|
5415
5452
|
return next;
|
|
5416
5453
|
});
|
|
5417
5454
|
}
|
|
5455
|
+
/**
|
|
5456
|
+
* Sets the reasoning effort a citizen's turns run with, or clears it for the model's own default.
|
|
5457
|
+
* It applies from the citizen's next turn; the runner starts a warm session afresh when it changes.
|
|
5458
|
+
*/
|
|
5459
|
+
async setAgentEffort(actor, name, effort) {
|
|
5460
|
+
this.assertUser(actor, "only the user may change a citizen's reasoning effort");
|
|
5461
|
+
const chosen = effort === null ? null : EffortSchema.parse(effort);
|
|
5462
|
+
return this.mutex.run(async () => {
|
|
5463
|
+
const current = await this.readAgent(name);
|
|
5464
|
+
if (current.status !== "active" || current.cli === null) {
|
|
5465
|
+
throw new BoardError("INVALID_STATE", `${name} takes no turns, so it has no effort to set`);
|
|
5466
|
+
}
|
|
5467
|
+
const { effort: previous, ...rest } = current;
|
|
5468
|
+
const next = await this.updateAgent(name, () => chosen === null ? rest : { ...rest, effort: chosen });
|
|
5469
|
+
await this.refreshMember(name);
|
|
5470
|
+
await this.events.append("agent.configured", actor.name, {
|
|
5471
|
+
agent: name,
|
|
5472
|
+
effort: chosen,
|
|
5473
|
+
previous: previous ?? null
|
|
5474
|
+
});
|
|
5475
|
+
return next;
|
|
5476
|
+
});
|
|
5477
|
+
}
|
|
5418
5478
|
async updateAgent(name, mutate) {
|
|
5419
5479
|
const current = await this.readAgent(name);
|
|
5420
5480
|
const next = AgentSchema.parse(mutate(current));
|
|
@@ -6255,6 +6315,11 @@ agent.command("model <name> [model]").description("Set the model a member's turn
|
|
|
6255
6315
|
const updated = await board.setAgentModel(board.userActor(), name, model ?? null);
|
|
6256
6316
|
print(updated, () => `${updated.name} runs with ${updated.model ?? "its CLI's default model"} from its next turn`);
|
|
6257
6317
|
});
|
|
6318
|
+
agent.command("effort <name> [effort]").description("Set the reasoning effort a member's turns run with, from its next turn, such as high; no effort means the model's default").action(async (name, effort) => {
|
|
6319
|
+
const board = await open();
|
|
6320
|
+
const updated = await board.setAgentEffort(board.userActor(), name, effort ?? null);
|
|
6321
|
+
print(updated, () => `${updated.name} runs with ${updated.effort === void 0 ? "its model's default effort" : `${updated.effort} effort`} from its next turn`);
|
|
6322
|
+
});
|
|
6258
6323
|
agent.command("retire <name>").description("Retire a member: no more wakes, claims released, token revoked, sessions archived").requiredOption("--reason <text>", "why").action(async (name, opts) => {
|
|
6259
6324
|
const board = await open();
|
|
6260
6325
|
const retired = await board.retireAgent(board.userActor(), { name, reason: opts.reason });
|
package/dist/server/index.js
CHANGED
|
@@ -301,11 +301,18 @@ function mayHoldStage(member, task) {
|
|
|
301
301
|
return !(stage.gate && task.stages.slice(0, index).some((s) => s.holders.includes(member.name)));
|
|
302
302
|
}
|
|
303
303
|
var ModelNameSchema = z3.string().trim().min(1).max(120).regex(/^[\w.:/[\]-]+$/, "a model name is one word of letters, digits, and . _ : / - [ ]");
|
|
304
|
+
var EffortSchema = z3.string().trim().min(1).max(32).regex(/^[a-z][a-z0-9_-]*$/, "an effort is one lowercase word, such as high");
|
|
305
|
+
var EffortOptionSchema = z3.object({
|
|
306
|
+
id: EffortSchema,
|
|
307
|
+
description: z3.string().default("")
|
|
308
|
+
});
|
|
304
309
|
var ModelOptionSchema = z3.object({
|
|
305
310
|
id: ModelNameSchema,
|
|
306
311
|
name: z3.string(),
|
|
307
312
|
description: z3.string().default(""),
|
|
308
|
-
isDefault: z3.boolean().default(false)
|
|
313
|
+
isDefault: z3.boolean().default(false),
|
|
314
|
+
efforts: z3.array(EffortOptionSchema).default([]),
|
|
315
|
+
defaultEffort: EffortSchema.optional()
|
|
309
316
|
});
|
|
310
317
|
var AgentStatusSchema = z3.enum(["active", "retired"]);
|
|
311
318
|
var AgentSchema = z3.object({
|
|
@@ -313,6 +320,8 @@ var AgentSchema = z3.object({
|
|
|
313
320
|
role: NameSchema,
|
|
314
321
|
cli: CliKindSchema.nullable(),
|
|
315
322
|
model: z3.string().optional(),
|
|
323
|
+
/** The reasoning effort set for the agent's turns; the model's own default applies otherwise. */
|
|
324
|
+
effort: z3.string().optional(),
|
|
316
325
|
/** The runner preferred for the agent's turns where nothing else decides; any runner with its CLI otherwise. */
|
|
317
326
|
homeRunner: NameSchema.optional(),
|
|
318
327
|
memberships: z3.array(NameSchema),
|
|
@@ -334,6 +343,8 @@ var MemberSchema = z3.object({
|
|
|
334
343
|
model: z3.string().optional(),
|
|
335
344
|
/** The model the CLI reported on the citizen's last turn. */
|
|
336
345
|
lastModel: z3.string().optional(),
|
|
346
|
+
/** The reasoning effort configured on the record, if any; the model's own default applies otherwise. */
|
|
347
|
+
effort: z3.string().optional(),
|
|
337
348
|
/** The citizen's own skills, by name. */
|
|
338
349
|
skills: z3.array(NameSchema).default([]),
|
|
339
350
|
memberships: z3.array(NameSchema),
|
|
@@ -877,6 +888,8 @@ var TurnJobSchema = z6.object({
|
|
|
877
888
|
role: NameSchema,
|
|
878
889
|
cli: CliKindSchema,
|
|
879
890
|
model: z6.string().optional(),
|
|
891
|
+
/** The reasoning effort set on the agent; absent for the model's own default. */
|
|
892
|
+
effort: z6.string().optional(),
|
|
880
893
|
/** A project slug, or the society scope. */
|
|
881
894
|
scope: NameSchema,
|
|
882
895
|
/** The thread whose conversation the turn is in; absent for the home conversation. */
|
|
@@ -1113,6 +1126,8 @@ var TurnHistoryEntrySchema = z7.object({
|
|
|
1113
1126
|
trigger: z7.string(),
|
|
1114
1127
|
exitReason: z7.string().nullable(),
|
|
1115
1128
|
costUsd: z7.number(),
|
|
1129
|
+
/** The tokens the turn used; absent for turns logged before turns recorded them. */
|
|
1130
|
+
usage: UsageSchema.optional(),
|
|
1116
1131
|
model: z7.string().nullable(),
|
|
1117
1132
|
summary: z7.string().nullable(),
|
|
1118
1133
|
error: z7.string().nullable(),
|
|
@@ -1341,7 +1356,7 @@ var RunnerConfigSchema = z10.object({
|
|
|
1341
1356
|
});
|
|
1342
1357
|
|
|
1343
1358
|
// packages/shared/dist/version.js
|
|
1344
|
-
var STELLARIS_VERSION = "0.3.
|
|
1359
|
+
var STELLARIS_VERSION = "0.3.6";
|
|
1345
1360
|
|
|
1346
1361
|
// packages/board-core/dist/errors.js
|
|
1347
1362
|
var BoardError = class extends Error {
|
|
@@ -2398,6 +2413,8 @@ var SignInsSchema = z12.object({
|
|
|
2398
2413
|
signIns: z12.array(z12.object({
|
|
2399
2414
|
tokenHash: z12.string().min(1),
|
|
2400
2415
|
login: z12.string().min(1),
|
|
2416
|
+
/** The account's picture at the identity provider; sign-ins from before it have none. */
|
|
2417
|
+
avatarUrl: z12.url().optional(),
|
|
2401
2418
|
createdAt: IsoDateTimeSchema,
|
|
2402
2419
|
expiresAt: IsoDateTimeSchema
|
|
2403
2420
|
})).default([])
|
|
@@ -2408,6 +2425,7 @@ var TurnHistoryPayloadSchema = z12.object({
|
|
|
2408
2425
|
trigger: z12.string().default("manual"),
|
|
2409
2426
|
exitReason: z12.string().nullable().default(null),
|
|
2410
2427
|
costUsd: z12.number().default(0),
|
|
2428
|
+
usage: UsageSchema.optional(),
|
|
2411
2429
|
model: z12.string().nullable().default(null),
|
|
2412
2430
|
summary: z12.string().nullable().default(null),
|
|
2413
2431
|
error: z12.string().nullable().default(null),
|
|
@@ -3017,23 +3035,36 @@ ${charter.purpose}
|
|
|
3017
3035
|
* token, shown once. Only its hash is kept, in `state/sign-ins.json`, so a sign-in outlives a
|
|
3018
3036
|
* restart; it acts as the user, like the user's own token, until it expires or is signed out.
|
|
3019
3037
|
*/
|
|
3020
|
-
async signIn(login, ttlMs) {
|
|
3038
|
+
async signIn(login, ttlMs, avatarUrl) {
|
|
3021
3039
|
return this.mutex.run(async () => {
|
|
3022
3040
|
const token = mintToken();
|
|
3023
3041
|
const now = this.now().getTime();
|
|
3024
3042
|
const record = {
|
|
3025
3043
|
tokenHash: hashToken(token),
|
|
3026
3044
|
login,
|
|
3045
|
+
...avatarUrl === void 0 ? {} : { avatarUrl },
|
|
3027
3046
|
createdAt: new Date(now).toISOString(),
|
|
3028
3047
|
expiresAt: new Date(now + ttlMs).toISOString()
|
|
3029
3048
|
};
|
|
3030
3049
|
const live = (await this.readSignIns()).filter((each) => Date.parse(each.expiresAt) > now);
|
|
3031
3050
|
await writeJson(this.signInsFile(), { signIns: [...live, record] });
|
|
3032
|
-
this.signIns.set(record.tokenHash, {
|
|
3051
|
+
this.signIns.set(record.tokenHash, {
|
|
3052
|
+
login,
|
|
3053
|
+
avatarUrl,
|
|
3054
|
+
expiresAt: Date.parse(record.expiresAt)
|
|
3055
|
+
});
|
|
3033
3056
|
await this.events.append("user.signed_in", USER_NAME, { login });
|
|
3034
3057
|
return token;
|
|
3035
3058
|
});
|
|
3036
3059
|
}
|
|
3060
|
+
/** Who a token signed in as, while its sign-in lasts; null for any other token. */
|
|
3061
|
+
signInOf(token) {
|
|
3062
|
+
const signIn = this.signIns.get(hashToken(token));
|
|
3063
|
+
if (signIn === void 0 || signIn.expiresAt <= this.now().getTime()) {
|
|
3064
|
+
return null;
|
|
3065
|
+
}
|
|
3066
|
+
return { login: signIn.login, avatarUrl: signIn.avatarUrl };
|
|
3067
|
+
}
|
|
3037
3068
|
/** Ends the sign-in a token belongs to; false for a token that is no sign-in's. */
|
|
3038
3069
|
async signOut(token) {
|
|
3039
3070
|
const hash = hashToken(token);
|
|
@@ -3079,7 +3110,11 @@ ${charter.purpose}
|
|
|
3079
3110
|
for (const signIn of await this.readSignIns()) {
|
|
3080
3111
|
const expiresAt = Date.parse(signIn.expiresAt);
|
|
3081
3112
|
if (expiresAt > now) {
|
|
3082
|
-
this.signIns.set(signIn.tokenHash, {
|
|
3113
|
+
this.signIns.set(signIn.tokenHash, {
|
|
3114
|
+
login: signIn.login,
|
|
3115
|
+
avatarUrl: signIn.avatarUrl,
|
|
3116
|
+
expiresAt
|
|
3117
|
+
});
|
|
3083
3118
|
}
|
|
3084
3119
|
}
|
|
3085
3120
|
}
|
|
@@ -4994,6 +5029,7 @@ ${rationale}`}`);
|
|
|
4994
5029
|
session: parsed.session,
|
|
4995
5030
|
exitReason: parsed.exitReason,
|
|
4996
5031
|
costUsd: parsed.costUsd,
|
|
5032
|
+
...parsed.usage === null ? {} : { usage: parsed.usage },
|
|
4997
5033
|
toolCalls: parsed.toolCalls,
|
|
4998
5034
|
model: parsed.model,
|
|
4999
5035
|
summary: parsed.status?.summary ?? null,
|
|
@@ -5450,6 +5486,7 @@ Short, curated, loaded on every turn. Keep entries that change future behavior a
|
|
|
5450
5486
|
resident: charter.resident,
|
|
5451
5487
|
...agent.model === void 0 ? {} : { model: agent.model },
|
|
5452
5488
|
...lastModel === void 0 ? {} : { lastModel },
|
|
5489
|
+
...agent.effort === void 0 ? {} : { effort: agent.effort },
|
|
5453
5490
|
skills: (await this.listAgentSkills(name)).map((skill) => skill.name),
|
|
5454
5491
|
memberships: agent.memberships,
|
|
5455
5492
|
subscriptions: agent.subscriptions,
|
|
@@ -5498,6 +5535,29 @@ Short, curated, loaded on every turn. Keep entries that change future behavior a
|
|
|
5498
5535
|
return next;
|
|
5499
5536
|
});
|
|
5500
5537
|
}
|
|
5538
|
+
/**
|
|
5539
|
+
* Sets the reasoning effort a citizen's turns run with, or clears it for the model's own default.
|
|
5540
|
+
* It applies from the citizen's next turn; the runner starts a warm session afresh when it changes.
|
|
5541
|
+
*/
|
|
5542
|
+
async setAgentEffort(actor, name, effort) {
|
|
5543
|
+
this.assertUser(actor, "only the user may change a citizen's reasoning effort");
|
|
5544
|
+
const chosen = effort === null ? null : EffortSchema.parse(effort);
|
|
5545
|
+
return this.mutex.run(async () => {
|
|
5546
|
+
const current = await this.readAgent(name);
|
|
5547
|
+
if (current.status !== "active" || current.cli === null) {
|
|
5548
|
+
throw new BoardError("INVALID_STATE", `${name} takes no turns, so it has no effort to set`);
|
|
5549
|
+
}
|
|
5550
|
+
const { effort: previous, ...rest } = current;
|
|
5551
|
+
const next = await this.updateAgent(name, () => chosen === null ? rest : { ...rest, effort: chosen });
|
|
5552
|
+
await this.refreshMember(name);
|
|
5553
|
+
await this.events.append("agent.configured", actor.name, {
|
|
5554
|
+
agent: name,
|
|
5555
|
+
effort: chosen,
|
|
5556
|
+
previous: previous ?? null
|
|
5557
|
+
});
|
|
5558
|
+
return next;
|
|
5559
|
+
});
|
|
5560
|
+
}
|
|
5501
5561
|
async updateAgent(name, mutate) {
|
|
5502
5562
|
const current = await this.readAgent(name);
|
|
5503
5563
|
const next = AgentSchema.parse(mutate(current));
|
|
@@ -6520,13 +6580,20 @@ var Scheduler = class {
|
|
|
6520
6580
|
if (taskId !== null && !settled) {
|
|
6521
6581
|
await this.wakeStage(taskId, event.actor, now);
|
|
6522
6582
|
}
|
|
6583
|
+
if (taskId !== null) {
|
|
6584
|
+
await this.pruneStageWakes(taskId);
|
|
6585
|
+
}
|
|
6523
6586
|
return;
|
|
6524
6587
|
}
|
|
6525
6588
|
case "task.claimed": {
|
|
6526
6589
|
const taskId = stringOf(payload["taskId"]);
|
|
6527
|
-
if (taskId
|
|
6590
|
+
if (taskId === null) {
|
|
6591
|
+
return;
|
|
6592
|
+
}
|
|
6593
|
+
if (stringOf(payload["thread"]) !== taskId) {
|
|
6528
6594
|
await this.wakeHolder(taskId, event.actor, now);
|
|
6529
6595
|
}
|
|
6596
|
+
await this.pruneStageWakes(taskId);
|
|
6530
6597
|
return;
|
|
6531
6598
|
}
|
|
6532
6599
|
case "task.completing": {
|
|
@@ -6534,6 +6601,7 @@ var Scheduler = class {
|
|
|
6534
6601
|
const project = stringOf(payload["project"]);
|
|
6535
6602
|
if (taskId !== null && project !== null) {
|
|
6536
6603
|
this.completions.set(taskId, { project, actor: event.actor });
|
|
6604
|
+
await this.pruneStageWakes(taskId);
|
|
6537
6605
|
}
|
|
6538
6606
|
return;
|
|
6539
6607
|
}
|
|
@@ -6545,6 +6613,7 @@ var Scheduler = class {
|
|
|
6545
6613
|
return;
|
|
6546
6614
|
}
|
|
6547
6615
|
delete this.state.releaseCounts[taskId];
|
|
6616
|
+
await this.pruneStageWakes(taskId);
|
|
6548
6617
|
if (creator !== null && creator !== event.actor) {
|
|
6549
6618
|
await this.wakeCreator(taskId, project, creator, event.actor, now);
|
|
6550
6619
|
}
|
|
@@ -6555,6 +6624,9 @@ var Scheduler = class {
|
|
|
6555
6624
|
if (taskId !== null && payload["to"] === "abandoned") {
|
|
6556
6625
|
delete this.state.releaseCounts[taskId];
|
|
6557
6626
|
}
|
|
6627
|
+
if (taskId !== null) {
|
|
6628
|
+
await this.pruneStageWakes(taskId);
|
|
6629
|
+
}
|
|
6558
6630
|
return;
|
|
6559
6631
|
}
|
|
6560
6632
|
case "task.released":
|
|
@@ -6769,6 +6841,25 @@ var Scheduler = class {
|
|
|
6769
6841
|
}, now, { id: task.id, task: scope === task.project });
|
|
6770
6842
|
return sessionKey(agent.name, scope, task.id);
|
|
6771
6843
|
}
|
|
6844
|
+
/**
|
|
6845
|
+
* Drops each queued turn made only of stage wakes, one of them for this task, once none of its
|
|
6846
|
+
* stages waits for its citizen any more: as soon as an event about the task could have changed
|
|
6847
|
+
* that, the stage taken by anyone, the plan moved on or reshaped, the task ended, rather than
|
|
6848
|
+
* only at dispatch, so a wake that will not run leaves the queue at once.
|
|
6849
|
+
*/
|
|
6850
|
+
async pruneStageWakes(taskId) {
|
|
6851
|
+
for (const [key, item] of this.pending) {
|
|
6852
|
+
const wakes = item.stageWakes;
|
|
6853
|
+
if (wakes === void 0 || !wakes.some((wake) => wake.taskId === taskId)) {
|
|
6854
|
+
continue;
|
|
6855
|
+
}
|
|
6856
|
+
const due = await this.stillWaiting(item.dispatch.agent, wakes, item.holder === true);
|
|
6857
|
+
if (due === void 0 && this.pending.get(key) === item) {
|
|
6858
|
+
this.pending.delete(key);
|
|
6859
|
+
this.log.info({ agent: item.dispatch.agent, project: item.dispatch.project, taskId }, "dropping stage wake, the stage no longer waits for this agent");
|
|
6860
|
+
}
|
|
6861
|
+
}
|
|
6862
|
+
}
|
|
6772
6863
|
/**
|
|
6773
6864
|
* The first of these stage wakes still due: its task waits, unheld, on a stage the agent may
|
|
6774
6865
|
* hold, or, with `holder`, the agent holds it, having claimed it outside the task's conversation.
|
|
@@ -7974,6 +8065,7 @@ var TurnHost = class {
|
|
|
7974
8065
|
role: agent.role,
|
|
7975
8066
|
cli: agent.cli,
|
|
7976
8067
|
...agent.model === void 0 ? {} : { model: agent.model },
|
|
8068
|
+
...agent.effort === void 0 ? {} : { effort: agent.effort },
|
|
7977
8069
|
scope: dispatch.project,
|
|
7978
8070
|
...thread === void 0 ? {} : { thread: thread.id },
|
|
7979
8071
|
session: recorded ?? null,
|
|
@@ -8929,7 +9021,19 @@ var SIGN_IN_TTL_MS = 30 * 24 * 36e5;
|
|
|
8929
9021
|
var STATE_TTL_MS = 10 * 6e4;
|
|
8930
9022
|
var MAX_STATES = 1e3;
|
|
8931
9023
|
var TokenAnswerSchema = z14.object({ access_token: z14.string().min(1) });
|
|
8932
|
-
var GithubUserSchema = z14.object({
|
|
9024
|
+
var GithubUserSchema = z14.object({
|
|
9025
|
+
login: z14.string().min(1),
|
|
9026
|
+
id: z14.number().int(),
|
|
9027
|
+
avatar_url: z14.string().optional()
|
|
9028
|
+
});
|
|
9029
|
+
function githubAvatar(url) {
|
|
9030
|
+
try {
|
|
9031
|
+
const parsed = new URL(url ?? "");
|
|
9032
|
+
return parsed.protocol === "https:" && parsed.hostname === "avatars.githubusercontent.com" ? parsed.href : void 0;
|
|
9033
|
+
} catch {
|
|
9034
|
+
return void 0;
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
8933
9037
|
function safeNext(next) {
|
|
8934
9038
|
return next !== void 0 && /^\/(?![/\\])/.test(next) ? next : "/";
|
|
8935
9039
|
}
|
|
@@ -8973,6 +9077,7 @@ function githubAuthRoutes(options) {
|
|
|
8973
9077
|
}
|
|
8974
9078
|
let login;
|
|
8975
9079
|
let id;
|
|
9080
|
+
let avatar;
|
|
8976
9081
|
try {
|
|
8977
9082
|
const tokenAnswer = await fetchImpl("https://github.com/login/oauth/access_token", {
|
|
8978
9083
|
method: "POST",
|
|
@@ -8994,7 +9099,9 @@ function githubAuthRoutes(options) {
|
|
|
8994
9099
|
if (!userAnswer.ok) {
|
|
8995
9100
|
throw new Error(`GitHub answered ${userAnswer.status} for the user`);
|
|
8996
9101
|
}
|
|
8997
|
-
|
|
9102
|
+
const user = GithubUserSchema.parse(await userAnswer.json());
|
|
9103
|
+
({ login, id } = user);
|
|
9104
|
+
avatar = githubAvatar(user.avatar_url);
|
|
8998
9105
|
} catch (error) {
|
|
8999
9106
|
options.log?.warn({ error: String(error) }, "GitHub sign-in failed");
|
|
9000
9107
|
return land(c, pending.next, "signin-error=github");
|
|
@@ -9003,7 +9110,7 @@ function githubAuthRoutes(options) {
|
|
|
9003
9110
|
options.log?.warn({ login }, "GitHub sign-in refused a login that is not on the list");
|
|
9004
9111
|
return land(c, pending.next, "signin-error=not-allowed");
|
|
9005
9112
|
}
|
|
9006
|
-
const token = await board2.signIn(login, SIGN_IN_TTL_MS);
|
|
9113
|
+
const token = await board2.signIn(login, SIGN_IN_TTL_MS, avatar);
|
|
9007
9114
|
return land(c, pending.next, `session=${encodeURIComponent(token)}`);
|
|
9008
9115
|
});
|
|
9009
9116
|
return routes;
|
|
@@ -9388,6 +9495,7 @@ var RunnerBodySchema = z15.object({ name: NameSchema });
|
|
|
9388
9495
|
var EnrollmentApprovalSchema = z15.object({ name: NameSchema });
|
|
9389
9496
|
var HomeRunnerBodySchema = z15.object({ runner: NameSchema.nullable() });
|
|
9390
9497
|
var ModelBodySchema = z15.object({ model: ModelNameSchema.nullable() });
|
|
9498
|
+
var EffortBodySchema = z15.object({ effort: EffortSchema.nullable() });
|
|
9391
9499
|
var HistoryLimitSchema = z15.coerce.number().int().min(1).max(500);
|
|
9392
9500
|
var ChannelBodySchema = z15.object({
|
|
9393
9501
|
project: NameSchema.nullable().default(null),
|
|
@@ -9429,7 +9537,16 @@ function createApp(deps) {
|
|
|
9429
9537
|
};
|
|
9430
9538
|
const api = new Hono3();
|
|
9431
9539
|
api.use("*", authenticate);
|
|
9432
|
-
api.get("/me", (c) =>
|
|
9540
|
+
api.get("/me", (c) => {
|
|
9541
|
+
const signIn = board2.signInOf(bearer2(c) ?? "");
|
|
9542
|
+
return c.json(signIn === null ? c.get("actor") : {
|
|
9543
|
+
...c.get("actor"),
|
|
9544
|
+
signIn: {
|
|
9545
|
+
login: signIn.login,
|
|
9546
|
+
avatarUrl: signIn.avatarUrl ?? `https://github.com/${encodeURIComponent(signIn.login)}.png`
|
|
9547
|
+
}
|
|
9548
|
+
});
|
|
9549
|
+
});
|
|
9433
9550
|
api.delete("/sign-in", async (c) => c.json({ signedOut: await board2.signOut(bearer2(c) ?? "") }));
|
|
9434
9551
|
api.get("/society", async (c) => c.json(await board2.society()));
|
|
9435
9552
|
api.get("/agents", async (c) => c.json((await board2.listAgents()).map(({ tokenHash: _hash, ...agent }) => agent)));
|
|
@@ -9503,6 +9620,11 @@ function createApp(deps) {
|
|
|
9503
9620
|
const { tokenHash: _hash, ...agent } = await board2.setAgentModel(c.get("actor"), c.req.param("name"), body.model);
|
|
9504
9621
|
return c.json(agent);
|
|
9505
9622
|
});
|
|
9623
|
+
api.put("/agents/:name/effort", async (c) => {
|
|
9624
|
+
const body = EffortBodySchema.parse(await c.req.json());
|
|
9625
|
+
const { tokenHash: _hash, ...agent } = await board2.setAgentEffort(c.get("actor"), c.req.param("name"), body.effort);
|
|
9626
|
+
return c.json(agent);
|
|
9627
|
+
});
|
|
9506
9628
|
api.put("/agents/:name/runner", async (c) => {
|
|
9507
9629
|
const body = HomeRunnerBodySchema.parse(await c.req.json());
|
|
9508
9630
|
const { tokenHash: _hash, ...agent } = await board2.setAgentRunner(c.get("actor"), c.req.param("name"), body.runner);
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as e,ln as t,wt as n}from"./format-Cj7NW9Y9.js";import{L as r,S as i,n as a,r as o,t as s}from"./index-CthEgIzf.js";var c=t(),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:t}){let u=n(),d=r({select:e=>e.location.state.__TSR_index}),f=o(),p=i(),m=e(),h=a(f,d);if(h===null)return t;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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{D as e,F as t,Ht as n,R as r,b as i,h as a,ln as o,pn as s,un as c,y as l}from"./format-Cj7NW9Y9.js";import{I as u,V as d,c as f,i as p}from"./index-CthEgIzf.js";import{t as m}from"./MessageItem-DDC_1Jqn.js";import{n as h,t as g}from"./Pane-BNjb76U4.js";import{n as _}from"./ThreadCard-FPtAzvNM.js";import{i as v}from"./ThreadForms-LFw2EF6r.js";import{t as y}from"./useStickyScroll-XrG6M-hT.js";var b=s(c(),1),x=o();function S(){let{_splat:e=`general`}=d({from:`/c/$`});return(0,x.jsx)(C,{channel:e},e)}function C({channel:o}){let{api:s}=e(),c=n({queryKey:[`channel`,o],queryFn:()=>s.channel(o)}),d=t(),S=a(),C=i(),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=(d.data??[]).filter(e=>e.channel===o).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,d.data,o]),O=c.data?.at(-1)?.id??null;(0,b.useEffect)(()=>u(o,O),[o,O]);let{ref:k,onScroll:A}=y(),[j,M]=o.split(`/`),N=M??j??o,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:o,onDone:()=>E(!1)}):null,(0,x.jsx)(`div`,{ref:k,onScroll:A,className:`flex-1 overflow-y-auto py-2`,children:c.error instanceof r&&c.error.status===404?(0,x.jsxs)(h,{children:[`There is no channel `,o,`.`]}):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:o},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,T as s,a as c,cn as l,ct as u,d,f,g as p,h as m,ln as h,pn as g,t as _,u as v,un as y,v as b,w as x,y as S}from"./format-Cj7NW9Y9.js";import{B as C,H as w,R as T,S as E,T as D,V as O,_ as ee,c as k,f as A,g as te,h as ne,i as re,m as j,p as M,v as N,x as P,y as F}from"./index-CthEgIzf.js";import{t as I}from"./Markdown-CYcTTxcR.js";import{n as L,t as ie}from"./Pane-BNjb76U4.js";import{n as ae,r as R}from"./ThreadForms-LFw2EF6r.js";import{t as oe}from"./useStickyScroll-XrG6M-hT.js";import{a as z,c as se,i as B,l as V,n as ce,o as H,s as le,t as ue}from"./citizen-Bm_r8vBY.js";var U=g(y(),1),W=h(),de={completed:`completed`,timeout:`timed out`,error:`failed`,interrupted:`was interrupted`,blocked:`was blocked`,stopped:`was stopped by you`};function G(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1})}function K({label:e,tone:t,children:n}){return(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`p`,{className:`px-0.5 pb-0.5 text-[10px] tracking-wider text-fg-muted uppercase`,children:e}),(0,W.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 fe({step:e,open:t}){if(e.kind===`say`)return(0,W.jsx)(`li`,{className:`py-1.5 text-sm`,title:G(e.at),children:(0,W.jsx)(I,{text:e.text})});if(e.kind===`error`)return(0,W.jsx)(`li`,{className:`py-1 font-mono text-xs break-words text-red-400`,title:G(e.at),children:e.message});if(e.kind===`steer`)return(0,W.jsx)(`li`,{children:(0,W.jsxs)(`details`,{open:t,className:`group rounded-md open:bg-surface-2/30`,children:[(0,W.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,W.jsx)(`span`,{"aria-hidden":`true`,className:`grid w-3 shrink-0 place-items-center text-sky-300`,children:`↳`}),(0,W.jsxs)(`span`,{className:`shrink-0 text-fg-tertiary`,children:[`Took `,ne(e.posts.length)]}),(0,W.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,W.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-fg-muted`,children:G(e.at)})]}),(0,W.jsx)(`ul`,{className:`space-y-1.5 px-1.5 pb-1.5`,children:e.posts.map(e=>(0,W.jsxs)(`li`,{className:`rounded-md bg-surface-0/40 px-2.5 py-2`,children:[(0,W.jsxs)(`p`,{className:`flex gap-1.5 text-meta`,children:[(0,W.jsx)(`span`,{className:`text-fg-secondary`,children:e.author}),(0,W.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`in `,e.where]}),e.at===``?null:(0,W.jsx)(`span`,{className:`ml-auto shrink-0 font-mono`,children:G(e.at)})]}),(0,W.jsx)(`div`,{className:`mt-1 text-sm`,children:(0,W.jsx)(I,{text:e.body})})]},`${e.at}-${e.author}`))})]})});let n=e.ok===null?(0,W.jsx)(`span`,{"aria-label":`running`,className:`size-1.5 animate-pulse rounded-full bg-amber-300`}):e.ok?(0,W.jsx)(`span`,{"aria-label":`succeeded`,className:`text-[11px] text-emerald-400`,children:`✓`}):(0,W.jsx)(`span`,{"aria-label":`failed`,className:`text-[11px] text-red-400`,children:`✕`});return(0,W.jsx)(`li`,{children:(0,W.jsxs)(`details`,{open:t,className:`group rounded-md open:bg-surface-2/30`,children:[(0,W.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,W.jsx)(`span`,{className:`grid w-3 shrink-0 place-items-center`,children:n}),(0,W.jsx)(`span`,{className:`shrink-0 font-mono text-fg-tertiary`,children:te(e.name)}),(0,W.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-fg-secondary`,children:e.summary}),(0,W.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-fg-muted`,children:G(e.at)})]}),(0,W.jsxs)(`div`,{className:`space-y-1.5 px-1.5 pb-1.5`,children:[(0,W.jsx)(K,{label:`Input`,tone:`text-fg-secondary`,children:e.detail}),e.output===null?null:(0,W.jsx)(K,{label:e.ok===!1?`Returned an error`:`Returned`,tone:e.ok===!1?`text-red-300`:`text-fg-tertiary`,children:e.output})]})]})})}function q({steps:e}){let[t,n]=(0,U.useState)(!1),r=e.filter(e=>e.kind===`tool`).length;return e.length===0?(0,W.jsx)(`p`,{className:`mt-2 text-meta`,children:`No steps yet.`}):(0,W.jsxs)(W.Fragment,{children:[r===0?null:(0,W.jsxs)(`p`,{className:`mt-2 flex items-center gap-2 text-meta`,children:[r===1?`1 tool call`:`${r} tool calls`,(0,W.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,W.jsx)(`ol`,{className:`mt-1 space-y-0.5`,children:e.map(e=>(0,W.jsx)(fe,{step:e,open:t},e.seq))})]})}function pe({turn:e,running:t,now:n}){return e.end===null?t?(0,W.jsxs)(`p`,{className:`mt-3 flex items-center gap-2 text-meta`,"aria-live":`polite`,children:[(0,W.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-400`}),`Working · last step `,_(e.lastAt,n)]}):(0,W.jsx)(`p`,{className:`mt-3 text-meta`,children:`The turn ended without a report.`}):(0,W.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,W.jsxs)(`p`,{className:`text-caps`,children:[`The turn `,de[e.end.exitReason],` `,_(e.end.at,n),e.fromStart?` · ${M(e.startedAt,Date.parse(e.end.at))}`:``]}),e.end.summary===null?null:(0,W.jsx)(`p`,{className:`mt-1 text-sm text-fg-secondary`,children:e.end.summary})]})}var me=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,W.jsxs)(`div`,{children:[(0,W.jsxs)(`p`,{className:`text-xs text-fg-secondary`,children:[e.path,e.status===`modified`?``:(0,W.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,e.status]})]}),e.patch===null?(0,W.jsx)(`p`,{className:`mt-1 text-meta`,children:`A binary file; its contents are not shown.`}):e.patch===``?(0,W.jsx)(`p`,{className:`mt-1 text-meta`,children:`Empty.`}):(0,W.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,W.jsx)(`span`,{className:`block whitespace-pre-wrap break-words ${ye(e)}`,children:e===``?` `:e},t))}),e.truncated?(0,W.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,W.jsxs)(`div`,{className:`space-y-3 px-4 pt-1 pb-3`,children:[(0,W.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,W.jsx)(T,{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,W.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,G(t.at)]})]}),n.data===void 0?(0,W.jsx)(`p`,{className:`text-meta`,children:n.isError?`Could not read the change.`:`Reading the change…`}):n.data.map(e=>(0,W.jsx)(be,{file:e},e.path))]})}function Se({name:e,change:t,now:n}){let[r,i]=(0,U.useState)(!1),a=t.files.length===0?t.subject:ve(t);return(0,W.jsx)(`li`,{className:`border-b border-line/60 last:border-b-0`,children:(0,W.jsxs)(`details`,{className:`group`,onToggle:e=>i(e.currentTarget.open),children:[(0,W.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,W.jsxs)(`span`,{className:`flex items-center gap-2 text-xs`,children:[(0,W.jsx)(`span`,{className:`shrink-0 text-fg-muted`,children:he[t.kind]}),(0,W.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-fg-secondary`,children:a}),(0,W.jsx)(`span`,{className:`shrink-0 text-fg-muted`,children:_(t.at,n)}),(0,W.jsx)(`span`,{"aria-hidden":`true`,className:`shrink-0 text-[10px] text-fg-muted transition-transform group-open:rotate-90`,children:`▸`})]})}),r?(0,W.jsx)(xe,{name:e,change:t}):null]})})}function Ce({name:e}){let[t,n]=(0,U.useState)(me),r=f(e,t),i=S(3e4);if(r.data===void 0)return(0,W.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,W.jsxs)(L,{children:[e,`'s home has no history yet; it starts with the citizen's first turn.`]}):(0,W.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[(0,W.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,W.jsx)(`ol`,{children:a.map(t=>(0,W.jsx)(Se,{name:e,change:t,now:i},t.commit))}),o?(0,W.jsx)(`button`,{type:`button`,onClick:()=>n(t+me),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:`Show earlier changes`}):null]})}function J({title:e,children:t}){return(0,W.jsxs)(`section`,{className:`border-t border-line pt-4 first:border-t-0 first:pt-0`,children:[(0,W.jsx)(`h3`,{className:`text-section`,children:e}),(0,W.jsx)(`div`,{className:`mt-2`,children:t})]})}function we({member:e,charter:t}){let n=p(e.name),r=c(e.name),i=d(e.name),a=S(3e4);return(0,W.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,W.jsxs)(J,{title:`Edits to reconcile`,children:[(0,W.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,W.jsx)(`ul`,{className:`mt-2 space-y-1.5`,children:i.data.map(e=>(0,W.jsxs)(`li`,{className:`text-sm`,children:[(0,W.jsx)(`span`,{className:`text-fg-primary`,children:e.file}),(0,W.jsxs)(`span`,{className:`text-meta`,children:[` `,`· `,e.path.slice(e.path.lastIndexOf(`/`)+1),` · left`,` `,_(e.since,a)]})]},e.path))})]}),(0,W.jsx)(J,{title:`Profile`,children:e.profile.trim()===``?(0,W.jsx)(`p`,{className:`text-meta`,children:`No profile yet. The citizen writes its own profile.md.`}):(0,W.jsx)(I,{text:V(e.profile,`Profile`)})}),(0,W.jsx)(J,{title:`Core memory`,children:n.data===void 0?(0,W.jsx)(`p`,{className:`text-meta`,children:`Reading…`}):n.data.body.trim()===``?(0,W.jsx)(`p`,{className:`text-meta`,children:`Empty. Every turn loads this file in full.`}):(0,W.jsx)(I,{text:V(n.data.body,`Core memory`)})}),(0,W.jsx)(J,{title:`Own skills`,children:r.data===void 0?(0,W.jsx)(`p`,{className:`text-meta`,children:`Reading…`}):r.data.length===0?(0,W.jsx)(`p`,{className:`text-meta`,children:`None yet.`}):(0,W.jsx)(`ul`,{className:`space-y-1.5`,children:r.data.map(e=>(0,W.jsxs)(`li`,{className:`text-sm`,children:[(0,W.jsx)(`span`,{className:`text-fg-primary`,children:e.name}),e.summary===``?null:(0,W.jsxs)(`span`,{className:`text-fg-secondary`,children:[` · `,e.summary]})]},e.name))})}),t===void 0?null:(0,W.jsxs)(J,{title:`Charter of ${t.name}`,children:[(0,W.jsx)(`p`,{className:`text-sm text-fg-secondary`,children:t.purpose}),(0,W.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,W.jsx)(`p`,{className:`mt-2 flex flex-wrap gap-1`,children:t.verbs.map(e=>(0,W.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 Te(e,t){let n=r(e,t?.turnId??null);return{turn:(0,U.useMemo)(()=>t===void 0||n.data===void 0?void 0:ee(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 Ee({name:e,entry:t,now:n,opened:r}){let[i,a]=(0,U.useState)(r),o=(0,U.useRef)(null);(0,U.useEffect)(()=>{r&&o.current?.scrollIntoView({block:`start`})},[r]);let s=E(),c=le(t),l=t.thread===void 0?null:s.get(t.thread)?.title??`a thread`,u=t.error??t.summary??``,d=t.error===null?`text-fg-secondary`:`text-red-300`;return(0,W.jsx)(`li`,{ref:o,className:`border-b border-line/60 last:border-b-0`,children:(0,W.jsxs)(`details`,{className:`group`,open:i,onToggle:e=>a(e.currentTarget.open),children:[(0,W.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,W.jsxs)(`span`,{className:`flex items-center gap-2 text-xs`,children:[(0,W.jsxs)(`span`,{className:`min-w-0 truncate text-fg-secondary`,children:[B(t.project),l===null?``:` · ${l}`]}),(0,W.jsx)(`span`,{className:`text-fg-muted`,children:t.trigger}),(0,W.jsxs)(`span`,{className:`min-w-0 flex-1 truncate text-fg-muted`,children:[ue(t),` `,_(t.ts,n)]}),(0,W.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-fg-tertiary`,title:t.usage===void 0?void 0:z(t.usage),children:[c,t.toolCalls===void 0?null:`${t.toolCalls} tools`,t.usage===void 0?null:H(t.usage)].filter(e=>e!==null).join(` · `)}),(0,W.jsx)(`span`,{"aria-hidden":`true`,className:`shrink-0 text-[10px] text-fg-muted transition-transform group-open:rotate-90`,children:`▸`})]}),u.trim()===``?null:(0,W.jsx)(`span`,{className:`mt-1 line-clamp-2 block text-xs leading-relaxed group-open:hidden ${d}`,children:(0,W.jsx)(P,{text:u,links:!1})})]}),i?(0,W.jsx)(De,{name:e,entry:t,text:u,tone:d}):null]})})}function De({name:e,entry:t,text:n,tone:r}){let i=Te(e,t);return(0,W.jsxs)(`div`,{className:`px-4 pt-1 pb-3`,children:[n.trim()===``?null:(0,W.jsx)(`p`,{className:`text-xs leading-relaxed whitespace-pre-wrap ${r}`,children:(0,W.jsx)(P,{text:n})}),(0,W.jsx)(`div`,{className:`mt-2`,children:t.turnId===void 0?(0,W.jsx)(`p`,{className:`text-meta`,children:`This turn ran before turns kept their steps.`}):i.loading?(0,W.jsx)(`p`,{className:`text-meta`,children:`Reading the steps…`}):i.turn===void 0?(0,W.jsx)(`p`,{className:`text-meta`,children:`No steps were kept for this turn.`}):(0,W.jsxs)(W.Fragment,{children:[t.startedAt===void 0?null:(0,W.jsxs)(`p`,{className:`text-caps`,children:[`Started `,G(t.startedAt)]}),(0,W.jsx)(q,{steps:i.turn.steps})]})})]})}function Oe({name:e,opened:t}){let[n,r]=(0,U.useState)(Y),a=i(e,n),o=S(3e4);if(a.data===void 0)return(0,W.jsx)(L,{children:`Reading the turns…`});let s=a.data.toReversed();if(s.length===0)return(0,W.jsxs)(L,{children:[e,` has not finished a turn yet.`]});let c=ce(s),l=c.usage===null?``:` · ${H(c.usage)}${c.withUsage<c.turns?` over ${c.withUsage} of them`:``}`;return(0,W.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[(0,W.jsxs)(`p`,{className:`px-4 pt-3 pb-1 text-meta`,title:c.usage===null?void 0:z(c.usage),children:[c.turns===1?`1 turn`:`${c.turns} turns`,c.failed===0?``:`, ${c.failed} not completed`,l]}),t!==null&&!s.some(e=>e.turnId===t)?(0,W.jsx)(`p`,{className:`px-4 pb-1 text-meta`,children:a.data.length===n?`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,W.jsx)(`ol`,{children:s.map(n=>(0,W.jsx)(Ee,{name:e,entry:n,now:o,opened:t!==null&&n.turnId===t},n.id))}),a.data.length===n?(0,W.jsxs)(`button`,{type:`button`,onClick:()=>r(n+Y),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:[`Show `,Y,` earlier turns`]}):null]})}function ke(e){return e===void 0?``:`${e.name}${e.id===null?``:` · ${e.id}`}`}function X({label:e,choices:t,value:n,onChange:r,listClassName:i=`inset-x-0`}){let[a,o]=(0,U.useState)(!1),s=(0,U.useRef)(null),c=(0,U.useRef)(null),l=(0,U.useRef)([]),u=t.findIndex(e=>e.value===n);(0,U.useEffect)(()=>{if(!a)return;l.current[Math.max(u,0)]?.focus();let e=e=>{e.target instanceof Node&&s.current?.contains(e.target)===!0||o(!1)};return window.addEventListener(`pointerdown`,e),()=>window.removeEventListener(`pointerdown`,e)},[a,u]);let d=e=>{if(e.key===`Escape`){e.stopPropagation(),o(!1),c.current?.focus();return}if(e.key!==`ArrowDown`&&e.key!==`ArrowUp`)return;e.preventDefault();let n=(l.current.findIndex(e=>e===document.activeElement)+(e.key===`ArrowDown`?1:-1)+t.length)%t.length;l.current[n]?.focus()},f=t[u];return(0,W.jsxs)(`div`,{ref:s,className:`relative min-w-0 flex-1`,children:[(0,W.jsxs)(`button`,{ref:c,type:`button`,"aria-label":`${e}: ${ke(f)}`,"aria-expanded":a,onClick:()=>o(!a),onKeyDown:a?d: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,W.jsxs)(`span`,{className:`min-w-0 flex-1 truncate text-left`,children:[f?.name,f?.id===null||f===void 0?null:(0,W.jsxs)(`span`,{className:`text-fg-tertiary`,children:[` · `,f.id]})]}),(0,W.jsx)(`span`,{"aria-hidden":`true`,className:`text-[10px] text-fg-muted transition-transform ${a?`rotate-180`:``}`,children:`▾`})]}),a?(0,W.jsx)(`div`,{className:`absolute ${i} 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,W.jsxs)(`button`,{ref:e=>{l.current[t]=e},type:`button`,"aria-current":i?`true`:void 0,onKeyDown:d,onClick:()=>{r(e.value),o(!1),c.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,W.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`span`,{className:`block truncate text-xs text-fg-secondary`,children:[e.name,e.id===null?null:(0,W.jsxs)(`span`,{className:`text-fg-tertiary`,children:[` · `,e.id]})]}),e.description===``?null:(0,W.jsx)(`span`,{className:`block truncate text-[11px] text-fg-muted`,children:e.description})]}),(0,W.jsx)(`span`,{"aria-hidden":`true`,className:`w-3 shrink-0 pt-px text-[11px] text-fg-primary`,children:i?`✓`:``})]},e.value)})}):null]})}var Z=``,Q=``;function Ae(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 je(e,t){return[{value:Q,name:`Default`,id:e?.defaultEffort??null,description:`Whatever the model runs unset.`},...(e?.efforts??[]).map(e=>({value:e.id,name:e.id,id:null,description:e.description})),...t===null?[]:[{value:t,name:t,id:null,description:`Not in the model's list.`}]]}function Me({member:t,onDone:n}){let{api:r}=e(),i=l(),a=b(t.cli),s=t.model??Z,c=t.effort??Q,[u,d]=(0,U.useState)(s),[f,p]=(0,U.useState)(c),m=w({mutationFn:async()=>{u!==s&&await r.setModel(t.name,u===Z?null:u),f!==c&&await r.setEffort(t.name,f===Q?null:f)},onSettled:()=>void i.invalidateQueries({queryKey:[`members`]}),onSuccess:n}),h=a.data??[],g=t.model!==void 0&&!h.some(e=>e.id===t.model)?t.model:null,_=e=>h.find(t=>e===Z?t.isDefault:t.id===e),v=_(u)?.efforts??[],y=f!==Q&&!v.some(e=>e.id===f)?f:null,x=e=>{d(e);let t=_(e)?.efforts??[];f!==Q&&!t.some(e=>e.id===f)&&p(Q)},S=u!==s||f!==c;return(0,W.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(),m.mutate()},children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[a.isPending?(0,W.jsxs)(`p`,{className:`min-w-0 flex-1 truncate text-meta`,children:[`Asking `,t.cli,` for its models…`]}):a.error===null?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(X,{label:`Model`,choices:Ae(h,g),value:u,onChange:x}),v.length===0&&y===null?null:(0,W.jsx)(`div`,{className:`flex w-32 shrink-0`,children:(0,W.jsx)(X,{label:`Effort`,choices:je(_(u),y),value:f,onChange:p,listClassName:`right-0 w-64`})})]}):(0,W.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,W.jsx)(k,{onClick:n,children:`Cancel`}),(0,W.jsx)(k,{variant:`primary`,type:`submit`,disabled:m.isPending||!S||a.error!==null,children:m.isPending?`Saving…`:`Save`})]}),(0,W.jsx)(R,{error:m.error})]})}var $=``;function Ne(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 Pe(e,t){return[{value:$,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:Ne(e,t)}))]}function Fe({member:t,onDone:n}){let{api:r}=e(),i=l(),a=s(),o=t.homeRunner??$,[c,u]=(0,U.useState)(o),d=w({mutationFn:()=>r.setRunner(t.name,c===$?null:c),onSuccess:()=>{i.invalidateQueries({queryKey:[`members`]}),n()}});return(0,W.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(),d.mutate()},children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[a.data===void 0?(0,W.jsx)(`p`,{className:`min-w-0 flex-1 truncate text-meta`,children:`Reading the runners…`}):(0,W.jsx)(X,{label:`Runner`,choices:Pe(a.data,t),value:c,onChange:u}),(0,W.jsx)(k,{onClick:n,children:`Cancel`}),(0,W.jsx)(k,{variant:`primary`,type:`submit`,disabled:d.isPending||c===o,children:d.isPending?`Saving…`:`Run here`})]}),(0,W.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,W.jsx)(R,{error:d.error})]})}function Ie(e){return e.thread===void 0?{channel:e.channel??(e.scope===`society`?`general`:`${e.scope}/general`)}:{threadId:e.thread}}function Le({name:t,turn:n}){let{api:r}=e(),i=l(),[a,o]=(0,U.useState)(!1),s=w({mutationFn:()=>r.stopTurn(n.turnId),onSuccess:()=>{o(!1),i.invalidateQueries({queryKey:[`scheduler`]})}});return(0,W.jsxs)(`div`,{className:`border-t border-line`,children:[(0,W.jsx)(re,{target:Ie(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,W.jsxs)(`div`,{className:`flex items-center gap-2 px-3 pb-3`,children:[(0,W.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,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(k,{onClick:()=>{o(!1),s.reset()},children:`Keep it running`}),(0,W.jsx)(k,{variant:`primary`,disabled:s.isPending,onClick:()=>{s.mutate()},children:s.isPending?`Stopping…`:`Stop the turn`})]}):(0,W.jsx)(k,{onClick:()=>o(!0),children:`Stop…`})]}):null,s.error===null?null:(0,W.jsx)(`div`,{className:`px-3 pb-3`,children:(0,W.jsx)(R,{error:s.error})})]})}function Re({member:t,scopes:n,preferred:r,running:i,paused:a,onDone:o}){let{api:s}=e(),c=l(),[u,d]=(0,U.useState)(`manual`),[f,p]=(0,U.useState)(r!==null&&n.includes(r)?r:n[0]??``),[m,h]=(0,U.useState)(``),g=(0,U.useRef)(null);(0,U.useEffect)(()=>g.current?.focus(),[]);let _=w({mutationFn:()=>s.wake({agent:t.name,project:f,kind:u,...m.trim()===``?{}:{reason:m.trim()}}),onSuccess:()=>{c.invalidateQueries({queryKey:[`scheduler`]}),o()}}),v=B(f),y=u===`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(f)?` ${t.name} is in a turn there now; this one follows it.`:``;return(0,W.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,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsxs)(`fieldset`,{className:`flex gap-1`,children:[(0,W.jsx)(`legend`,{className:`sr-only`,children:`Kind of turn`}),[`manual`,`reflection`].map(e=>(0,W.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 ${u===e?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[(0,W.jsx)(`input`,{type:`radio`,name:`kind`,value:e,checked:u===e,onChange:()=>d(e),className:`sr-only`}),e===`manual`?`A turn`:`A reflection`]},e))]}),(0,W.jsxs)(`label`,{className:`ml-auto flex items-center gap-2 text-xs text-fg-tertiary`,children:[`at`,(0,W.jsx)(`select`,{value:f,onChange:e=>p(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,W.jsx)(`option`,{value:e,children:B(e)},e))})]})]}),(0,W.jsx)(`textarea`,{ref:g,value:m,rows:2,placeholder:u===`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,W.jsxs)(`p`,{className:`text-[11px] leading-relaxed text-fg-muted`,children:[y,b,` Each turn costs money.`]}),(0,W.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,W.jsx)(k,{onClick:o,children:`Cancel`}),(0,W.jsx)(k,{variant:`primary`,type:`submit`,disabled:_.isPending||f===``,children:_.isPending?`Waking…`:u===`reflection`?`Ask for a reflection`:`Wake ${t.name}`})]}),(0,W.jsx)(R,{error:_.error})]})}var ze={working:`bg-emerald-500/15 text-emerald-300`,queued:`bg-amber-500/15 text-amber-300`,idle:`bg-surface-2 text-fg-tertiary`};function Be({project:e,name:t}){let n=(a(e).data??[]).filter(e=>e.status===`claimed`&&e.claimedBy===t);return n.length===0?null:(0,W.jsx)(`ul`,{className:`mt-1.5 space-y-1`,children:n.map(e=>(0,W.jsx)(`li`,{children:(0,W.jsxs)(T,{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,W.jsx)(`span`,{"aria-hidden":`true`,className:`text-fg-muted`,children:`◇`}),(0,W.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.title}),(0,W.jsx)(`span`,{className:`max-w-[40%] shrink-0 truncate font-mono text-[11px] text-fg-muted`,children:u(e)?.name??e.stage})]})},e.id))})}function Ve(){let{name:e}=O({from:`/citizen/$name`}),{scope:t,tab:n,turn:r}=C({from:`/citizen/$name`});return(0,W.jsx)(Ue,{name:e,chosen:t??null,tab:n??`now`,turn:r??null},e)}var He=[{tab:`now`,label:`Now`},{tab:`turns`,label:`Turns`},{tab:`memory`,label:`Memory`},{tab:`history`,label:`History`}];function Ue({name:e,chosen:r,tab:i,turn:a}){let o=m(),s=x(),c=t(),l=F(),[u,d]=(0,U.useState)(null),f=o.data?.find(t=>t.name===e);if(f===void 0)return(0,W.jsx)(L,{children:o.data===void 0?`Reading the roster…`:`There is no citizen ${e}.`});let p=n(c.data?.running??[]).filter(t=>t.agent===e),h=[...new Set(p.map(e=>e.scope))],g=p.map(e=>j(e.agent,e.scope,e.thread)),_=n(c.data?.pending??[]).find(t=>t.agent===e),v=h.length>0?`working`:_===void 0?`idle`:`queued`,y=N(l,e)[0],b=y?.model??f.lastModel,S=b??f.model??`CLI default`,C=f.model!==void 0&&f.model!==b?f.model:null,w=s.data?.find(e=>e.name===f.role),E=se(f),O=f.status===`active`&&f.cli!==null;return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(ie,{leading:f.cli===null?null:(0,W.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-lg bg-surface-2/70`,children:(0,W.jsx)(D,{cli:f.cli,size:20})}),title:e,subtitle:(0,W.jsxs)(W.Fragment,{children:[f.role,` · `,S,C===null?``:` · set to ${C}`,f.effort===void 0?``:` · ${f.effort} effort`,f.homeRunner===void 0?``:` · on ${f.homeRunner}`,f.status===`retired`?` · retired`:``]}),trailing:(0,W.jsxs)(W.Fragment,{children:[O&&u===null?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(k,{onClick:()=>d(`model`),children:`Model…`}),(0,W.jsx)(k,{onClick:()=>d(`runner`),children:`Runner…`}),(0,W.jsx)(k,{onClick:()=>d(`wake`),children:`Wake…`})]}):null,(0,W.jsx)(`span`,{className:`shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium ${ze[v]}`,children:v})]})}),u===`wake`?(0,W.jsx)(Re,{member:f,scopes:E,preferred:r?.split(`/`)[0]??y?.scope??null,running:h,paused:c.data?.paused??!1,onDone:()=>d(null)}):u===`model`?(0,W.jsx)(Me,{member:f,onDone:()=>d(null)}):u===`runner`?(0,W.jsx)(Fe,{member:f,onDone:()=>d(null)}):null,(0,W.jsx)(`nav`,{"aria-label":`Citizen views`,className:`flex gap-1 border-b border-line px-3 py-2`,children:He.map(t=>(0,W.jsx)(T,{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,W.jsx)(Oe,{name:e,opened:a},a):i===`memory`?(0,W.jsx)(we,{member:f,charter:w}):i===`history`?(0,W.jsx)(Ce,{name:e}):(0,W.jsx)(Ge,{name:e,chosen:r,lastTurnAt:f.lastTurnAt,state:v,runningScopes:h,runningKeys:g,runningTurns:(c.data?.turns??[]).filter(t=>t.agent===e),queuedScope:_?.scope??null})]})}function We(e){return e.toSorted((e,t)=>e.startedAt.localeCompare(t.startedAt))[0]}function Ge({name:e,chosen:t,lastTurnAt:n,state:r,runningScopes:a,runningKeys:o,runningTurns:s,queuedScope:c}){let l=F(),u=S(5e3),{ref:d,onScroll:f}=oe(),p=N(l,e),m=i(e,1),h=Te(e,p.length===0?m.data?.at(-1):void 0),g=E(),v=e=>e.end===null&&o.includes(j(e.agent,e.scope,e.thread)),y=t?.split(`/`)[0]??null,b=(t?.includes(`/`)===!0?p.find(e=>A(e)===t):void 0)??We(p.filter(e=>e.scope===y&&v(e)))??p.find(e=>A(e)===t)??We(p.filter(v))??p[0]??h.turn,x=e=>e.thread===void 0?B(e.scope):`${B(e.scope)} · ${g.get(e.thread)?.title??`a thread`}`,C=b!==void 0&&v(b),w=b?.scope??a[0]??c,D=(b===void 0?void 0:s.find(e=>e.scope===b.scope&&e.thread===b.thread))??(C?void 0:s[0]);return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`section`,{className:`border-b border-line px-4 py-3 text-xs text-fg-tertiary`,children:[(0,W.jsx)(`p`,{children:C?`In a turn at ${B(b.scope)} for ${b.fromStart?``:`at least `}${M(b.startedAt,u)}`:a.length>0?`In a turn at ${a.map(B).join(` and `)}`:c===null?n===void 0?`No turns yet`:`Last turn ${_(n,u)}`:`Queued for a turn at ${B(c)}`}),w===null||w===`society`?null:(0,W.jsx)(Be,{project:w,name:e})]}),(0,W.jsx)(`div`,{ref:d,onScroll:f,className:`flex-1 overflow-y-auto px-4 py-3`,children:b===void 0?(0,W.jsx)(L,{children:r===`working`?`The turn has not reported a step yet.`:h.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,W.jsxs)(W.Fragment,{children:[p.length>1?(0,W.jsx)(`div`,{className:`mb-3 flex flex-wrap gap-1.5`,"aria-label":`Turns by conversation`,children:p.toSorted((e,t)=>A(e).localeCompare(A(t))).map(t=>(0,W.jsxs)(T,{to:`/citizen/$name`,params:{name:e},search:{scope:A(t)},replace:!0,"aria-current":t===b?`true`:void 0,className:`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[11px] transition-colors ${t===b?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[v(t)?(0,W.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-400`}):null,x(t)]},A(t)))}):null,(0,W.jsxs)(`p`,{className:`text-caps`,children:[C?`This turn`:`Last turn`,` · `,x(b),` · started`,` `,b.fromStart?G(b.startedAt):`before the earliest step shown`]}),b.fromStart?null:(0,W.jsxs)(`p`,{className:`mt-1 text-meta`,children:[`Earlier steps of this turn are no longer in the server's live buffer`,C?``:`; Turns has the whole turn`,`.`]}),(0,W.jsx)(q,{steps:b.steps}),(0,W.jsx)(pe,{turn:b,running:C,now:u})]})}),D===void 0?null:(0,W.jsx)(Le,{name:e,turn:D})]})}export{Ve as CitizenView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{E as e,H as t,b as n,h as r,ln as i}from"./format-Cj7NW9Y9.js";import{R as a,T as o}from"./index-CthEgIzf.js";import{n as s,t as c}from"./Pane-BNjb76U4.js";import{i as l,r as u}from"./citizen-Bm_r8vBY.js";var d=i();function f(e){let t=e.lastModel??e.model??`CLI default`,n=e.model!==void 0&&e.model!==t?`${t} · set to ${e.model}`:t;return e.effort===void 0?n:`${n} · ${e.effort}`}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 i=r(),h=e(),g=n();if(i.data===void 0)return(0,d.jsx)(s,{children:`Reading the roster…`});let _=i.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),n=f(e),r=e.memberships.length===0?`no projects`:e.memberships.join(`, `),i=u(e,C);return(0,d.jsx)(`li`,{className:`col-span-full grid grid-cols-subgrid`,children:(0,d.jsxs)(a,{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:n,children:n}),(0,d.jsx)(`span`,{className:`text-xs text-fg-muted`,title:i.detail,children:i.label}),(0,d.jsx)(`span`,{className:`truncate text-xs text-fg-muted`,title:r,children:r}),(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{b as e,ln as t,ot as n,p as r,t as i,y as a}from"./format-Cj7NW9Y9.js";import{R as o,V as s}from"./index-CthEgIzf.js";import{t as c}from"./Markdown-CYcTTxcR.js";import{n as l,t as u}from"./Pane-BNjb76U4.js";import{t as d}from"./BackLink-Cr1RWb4K.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=r(t),g=e(),_=a(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)(o,{to:`/society`,"aria-label":`Back to the society`,className:p,children:`←`}):(0,f.jsx)(o,{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} ${i(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};
|