@kubitnodes/stellaris 0.3.15 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/cli/index.js +96 -19
  2. package/dist/server/index.js +115 -19
  3. package/package.json +1 -1
  4. package/web/dist/assets/BackLink-CssfJ-vJ.js +1 -0
  5. package/web/dist/assets/{ChannelForms-b6eKogvP.js → ChannelForms-B3XwkJj_.js} +1 -1
  6. package/web/dist/assets/ChannelView-B3qNylz5.js +2 -0
  7. package/web/dist/assets/CitizenView-BUeC52q2.js +2 -0
  8. package/web/dist/assets/{CitizensView-Dq3V4mpg.js → CitizensView-BSWYcQ-Q.js} +1 -1
  9. package/web/dist/assets/{CliIcon-DxDvRRcX.js → CliIcon-CFObB9XW.js} +1 -1
  10. package/web/dist/assets/CronsView-BBIx84f7.js +1 -0
  11. package/web/dist/assets/{KnowledgeView-ndWDlRoP.js → KnowledgeView-C8r5hAa_.js} +1 -1
  12. package/web/dist/assets/Markdown-BO_bF8WD.js +32 -0
  13. package/web/dist/assets/{MessageItem-Dk1m5NaR.js → MessageItem-BkDlfhQC.js} +1 -1
  14. package/web/dist/assets/MetricsView-DqAQ4th0.js +1 -0
  15. package/web/dist/assets/NeedsYouView-D2Z-iLdT.js +1 -0
  16. package/web/dist/assets/Overview-DThLwb0l.js +1 -0
  17. package/web/dist/assets/{Pane-CODhA5zE.js → Pane-DHXhVwfI.js} +1 -1
  18. package/web/dist/assets/{Picker-DB-wxloY.js → Picker-CQQ7hj8T.js} +1 -1
  19. package/web/dist/assets/{ProjectView-CH-nqrAo.js → ProjectView-DOtPYF6z.js} +1 -1
  20. package/web/dist/assets/{ProposalView-D-E0Hzdr.js → ProposalView-BpeiCg46.js} +1 -1
  21. package/web/dist/assets/{ProposalsView-Bmuq8Qnh.js → ProposalsView-BJg4ZsTy.js} +1 -1
  22. package/web/dist/assets/{RunnersView-N4iUU4FM.js → RunnersView-DOW8xq-J.js} +1 -1
  23. package/web/dist/assets/SocietyView-CbIpCGhP.js +1 -0
  24. package/web/dist/assets/{SubjectThread-akZdGCfo.js → SubjectThread-Do5As1cO.js} +1 -1
  25. package/web/dist/assets/TaskFileView-CPwEmR6p.js +4 -0
  26. package/web/dist/assets/TaskView-q6Kn30K7.js +3 -0
  27. package/web/dist/assets/{TasksView-CncU8UNJ.js → TasksView-CT9Cui_C.js} +1 -1
  28. package/web/dist/assets/ThreadCard-DsIkg4Br.js +1 -0
  29. package/web/dist/assets/ThreadForms-BPowHd4M.js +1 -0
  30. package/web/dist/assets/{ThreadView-DrwqggME.js → ThreadView-BZ2nKfyD.js} +1 -1
  31. package/web/dist/assets/{citizen-BRSvyK2X.js → citizen-DFaT61S1.js} +1 -1
  32. package/web/dist/assets/{compose-D7DOz6kC.js → compose-96HAETM2.js} +1 -1
  33. package/web/dist/assets/{format-BORdp4w-.js → format-Cp_C4ygr.js} +1 -1
  34. package/web/dist/assets/{governance-WrDQawLN.js → governance-BbogC_X-.js} +1 -1
  35. package/web/dist/assets/index-BXHV32GA.js +23 -0
  36. package/web/dist/assets/index-BoTts74M.css +2 -0
  37. package/web/dist/assets/{link-1v5lugnf.js → link-DIpiSYJj.js} +1 -1
  38. package/web/dist/assets/{tasks-C-9dAYQV.js → tasks-C1wf85BJ.js} +1 -1
  39. package/web/dist/assets/useMatch-DYOY33wl.js +1 -0
  40. package/web/dist/assets/{useStickyScroll-CE7dyz0Q.js → useStickyScroll-7ZZcyLI0.js} +1 -1
  41. package/web/dist/index.html +9 -9
  42. package/web/dist/assets/BackLink-hLg9AYSp.js +0 -1
  43. package/web/dist/assets/ChannelView-CHvr0c9I.js +0 -1
  44. package/web/dist/assets/CitizenView-DlqilbFH.js +0 -2
  45. package/web/dist/assets/CronsView-CBiPaq-C.js +0 -1
  46. package/web/dist/assets/Markdown-BMm7unnl.js +0 -31
  47. package/web/dist/assets/MetricsView-B31t_Q2z.js +0 -1
  48. package/web/dist/assets/NeedsYouView-d8_ydJI9.js +0 -1
  49. package/web/dist/assets/Overview-D-6YP-tf.js +0 -1
  50. package/web/dist/assets/SocietyView-fSkmFC3z.js +0 -1
  51. package/web/dist/assets/TaskFileView-DM_JjQQx.js +0 -4
  52. package/web/dist/assets/TaskView-JLLJKQ0_.js +0 -3
  53. package/web/dist/assets/ThreadCard-8OB70j9B.js +0 -1
  54. package/web/dist/assets/ThreadForms-RnrV7V5X.js +0 -1
  55. package/web/dist/assets/index-Dw96wkep.css +0 -2
  56. package/web/dist/assets/index-ww_EHgVF.js +0 -23
  57. package/web/dist/assets/useMatch-CyeFfbcR.js +0 -1
package/dist/cli/index.js CHANGED
@@ -396,6 +396,13 @@ var MessageStepSchema = z4.union([TaskStepSchema, ProposalStepSchema]);
396
396
  function isTaskStep(step) {
397
397
  return "stage" in step;
398
398
  }
399
+ var KnowledgeNoticeSchema = z4.object({
400
+ kind: z4.literal("knowledge"),
401
+ action: z4.enum(["written", "updated", "removed"]),
402
+ topic: NameSchema,
403
+ project: NameSchema.nullable()
404
+ });
405
+ var MessageNoticeSchema = z4.discriminatedUnion("kind", [KnowledgeNoticeSchema]);
399
406
  var MessageFrontmatterSchema = z4.object({
400
407
  id: UlidSchema,
401
408
  author: NameSchema,
@@ -407,6 +414,8 @@ var MessageFrontmatterSchema = z4.object({
407
414
  closes: UlidSchema.optional(),
408
415
  /** On a post a task verb made in the task's thread, or a decision in a proposal's: the step it recorded. */
409
416
  step: MessageStepSchema.optional(),
417
+ /** On a post a verb made about its work, such as a knowledge topic's note: what it records. */
418
+ notice: MessageNoticeSchema.optional(),
410
419
  ts: IsoDateTimeSchema,
411
420
  mentions: z4.array(NameSchema)
412
421
  });
@@ -1291,6 +1300,30 @@ var BranchChangesSchema = z7.object({
1291
1300
  files: z7.array(BranchFileChangeSchema),
1292
1301
  total: z7.number().int().nonnegative()
1293
1302
  });
1303
+ var BranchDiffReadSchema = z7.object({
1304
+ repo: ProjectRepoSchema,
1305
+ branch: BranchNameSchema,
1306
+ path: BranchPathSchema.min(1)
1307
+ });
1308
+ var BranchFileDiffSchema = z7.object({
1309
+ head: BranchCommitSchema,
1310
+ path: BranchPathSchema,
1311
+ status: BranchFileChangeSchema.shape.status,
1312
+ patch: z7.string().nullable(),
1313
+ truncated: z7.boolean()
1314
+ });
1315
+ function patchHunks(patch, limit) {
1316
+ if (/^Binary files .* differ$/m.test(patch)) {
1317
+ return { patch: null, truncated: false };
1318
+ }
1319
+ const start = patch.search(/^@@/m);
1320
+ const hunks = start === -1 ? "" : patch.slice(start);
1321
+ if (hunks.length <= limit) {
1322
+ return { patch: hunks, truncated: false };
1323
+ }
1324
+ const cut = hunks.lastIndexOf("\n", limit);
1325
+ return { patch: hunks.slice(0, cut === -1 ? limit : cut), truncated: true };
1326
+ }
1294
1327
  var WorkspaceConversationSchema = z7.discriminatedUnion("kind", [
1295
1328
  z7.object({ kind: z7.literal("thread"), id: UlidSchema }),
1296
1329
  z7.object({ kind: z7.literal("channel"), scope: NameSchema, name: NameSchema })
@@ -1317,6 +1350,8 @@ var RunnerMessageSchema = z7.discriminatedUnion("type", [
1317
1350
  request: z7.string().min(1),
1318
1351
  read: BranchChangesReadSchema
1319
1352
  }),
1353
+ /** Answered with a `BranchFileDiff`, or null when the branch does not exist or left the path alone. */
1354
+ z7.object({ type: z7.literal("diff"), request: z7.string().min(1), read: BranchDiffReadSchema }),
1320
1355
  /** Answered with whether the CLI accepted it; that it took it comes as a `steered` event. */
1321
1356
  z7.object({
1322
1357
  type: z7.literal("steer"),
@@ -1660,7 +1695,7 @@ var RunnerConfigSchema = z11.object({
1660
1695
  });
1661
1696
 
1662
1697
  // packages/shared/dist/version.js
1663
- var STELLARIS_VERSION = "0.3.15";
1698
+ var STELLARIS_VERSION = "0.3.17";
1664
1699
 
1665
1700
  // packages/board-core/dist/errors.js
1666
1701
  var BoardError = class extends Error {
@@ -2015,18 +2050,6 @@ function lineCount(value) {
2015
2050
  function fileStatus(letter) {
2016
2051
  return letter === "A" ? "added" : letter === "D" ? "deleted" : "modified";
2017
2052
  }
2018
- function hunksOf(patch) {
2019
- if (/^Binary files .* differ$/m.test(patch)) {
2020
- return { patch: null, truncated: false };
2021
- }
2022
- const start = patch.search(/^@@/m);
2023
- const hunks = start === -1 ? "" : patch.slice(start);
2024
- if (hunks.length <= PATCH_LIMIT_CHARS) {
2025
- return { patch: hunks, truncated: false };
2026
- }
2027
- const cut = hunks.lastIndexOf("\n", PATCH_LIMIT_CHARS);
2028
- return { patch: hunks.slice(0, cut === -1 ? PATCH_LIMIT_CHARS : cut), truncated: true };
2029
- }
2030
2053
  async function git(args, cwd) {
2031
2054
  const result = await execa("git", [...BOARD_IDENTITY, ...args], {
2032
2055
  cwd,
@@ -2165,7 +2188,8 @@ var HomeRepos = class {
2165
2188
  if (others.length > 0 && (status !== "added" || conflictCopyOf(file) === null)) {
2166
2189
  continue;
2167
2190
  }
2168
- files.push({ path: file, status, ...hunksOf(await read(home, [...range, "--", file])) });
2191
+ const patch = await read(home, [...range, "--", file]);
2192
+ files.push({ path: file, status, ...patchHunks(patch, PATCH_LIMIT_CHARS) });
2169
2193
  }
2170
2194
  return files;
2171
2195
  }
@@ -2850,6 +2874,12 @@ var KNOWLEDGE_REMOVAL = "knowledge-removal-granted";
2850
2874
  var CHANNEL_CONVERSATIONS = "channel-conversations";
2851
2875
  var DASHBOARD_UPDATES = "dashboard-updates-granted";
2852
2876
  var CRON_VERBS = "cron-verbs-granted";
2877
+ var KNOWLEDGE_NOTICES = "knowledge-notices";
2878
+ var KnowledgeEventSchema = z13.object({
2879
+ topic: NameSchema,
2880
+ project: NameSchema.nullable(),
2881
+ replaced: z13.boolean().optional()
2882
+ });
2853
2883
  var CRON_VERB_NAMES = ["create_cron", "update_cron", "remove_cron"];
2854
2884
  var OLD_DASHBOARD_LINE = "Agents may edit this file. It is rendered by the board UI.";
2855
2885
  var DASHBOARD_LINE = "The project's members keep this page current with update_dashboard.";
@@ -3053,7 +3083,8 @@ var Board = class _Board {
3053
3083
  KNOWLEDGE_REMOVAL,
3054
3084
  CHANNEL_CONVERSATIONS,
3055
3085
  DASHBOARD_UPDATES,
3056
- CRON_VERBS
3086
+ CRON_VERBS,
3087
+ KNOWLEDGE_NOTICES
3057
3088
  ].filter((name) => !applied.includes(name));
3058
3089
  if (pending.length === 0) {
3059
3090
  return;
@@ -3095,8 +3126,49 @@ var Board = class _Board {
3095
3126
  if (pending.includes(CRON_VERBS)) {
3096
3127
  await this.grantToEveryRole(CRON_VERB_NAMES);
3097
3128
  }
3129
+ if (pending.includes(KNOWLEDGE_NOTICES)) {
3130
+ await this.noticeKnowledgeNotes();
3131
+ }
3098
3132
  await writeJson(file, { applied: [...applied, ...pending] });
3099
3133
  }
3134
+ /**
3135
+ * Gives each knowledge note from before notes carried their notice the notice it would carry
3136
+ * now. The event log, not the note's words, says which post is one: a knowledge verb appends
3137
+ * its event and then its note under the mutex, so a note is the post right after such an event,
3138
+ * by the same actor, at the top of the general channel of the topic's place. A post written to
3139
+ * look like a note follows no such event and is left as it is.
3140
+ */
3141
+ async noticeKnowledgeNotes() {
3142
+ let before;
3143
+ for (const event of await this.events.readSince(null, Number.POSITIVE_INFINITY)) {
3144
+ const verb = before;
3145
+ before = event;
3146
+ if (event.type !== "message.posted" || verb === void 0 || verb.actor !== event.actor || verb.type !== "knowledge.written" && verb.type !== "knowledge.removed") {
3147
+ continue;
3148
+ }
3149
+ const knowledge2 = KnowledgeEventSchema.safeParse(verb.payload);
3150
+ const id = UlidSchema.safeParse(event.payload["id"]);
3151
+ if (!knowledge2.success || !id.success || (event.payload["thread"] ?? null) !== null || event.payload["channel"] !== channelRef(knowledge2.data.project, "general")) {
3152
+ continue;
3153
+ }
3154
+ const { topic, project: project2, replaced } = knowledge2.data;
3155
+ const file = this.paths.messageFile(this.paths.channelDir(channelRef(project2, "general")), id.data, event.actor);
3156
+ if (!await exists(file)) {
3157
+ continue;
3158
+ }
3159
+ const { data, body, error } = await readLooseMarkdown(file);
3160
+ if (error !== null || data["notice"] !== void 0) {
3161
+ continue;
3162
+ }
3163
+ const notice = {
3164
+ kind: "knowledge",
3165
+ action: verb.type === "knowledge.removed" ? "removed" : replaced === true ? "updated" : "written",
3166
+ topic,
3167
+ project: project2
3168
+ };
3169
+ await writeMarkdown(file, { ...data, notice }, body);
3170
+ }
3171
+ }
3100
3172
  /**
3101
3173
  * Grants `verb` once to every charter granting `write_knowledge`, the work roles' charters in
3102
3174
  * practice; seed roles have it from their seed.
@@ -4456,7 +4528,12 @@ ${task2.body}`;
4456
4528
  replaced
4457
4529
  });
4458
4530
  const where = args.project === null ? "general" : channelRef(args.project, "general");
4459
- await this.appendMessage(actor.name, where, `Knowledge ${replaced ? "updated" : "written"}: ${args.topic}. It is under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`);
4531
+ await this.appendMessage(actor.name, where, `Knowledge ${replaced ? "updated" : "written"}: ${args.topic}. It is under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`, {
4532
+ kind: "knowledge",
4533
+ action: replaced ? "updated" : "written",
4534
+ topic: args.topic,
4535
+ project: args.project
4536
+ });
4460
4537
  return { ...data, body: args.body };
4461
4538
  });
4462
4539
  }
@@ -4489,7 +4566,7 @@ ${task2.body}`;
4489
4566
  project: args.project
4490
4567
  });
4491
4568
  const where = args.project === null ? "general" : channelRef(args.project, "general");
4492
- await this.appendMessage(actor.name, where, `Knowledge removed: ${args.topic}. It is no longer under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`);
4569
+ await this.appendMessage(actor.name, where, `Knowledge removed: ${args.topic}. It is no longer under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`, { kind: "knowledge", action: "removed", topic: args.topic, project: args.project });
4493
4570
  return removed;
4494
4571
  });
4495
4572
  }
@@ -7112,9 +7189,9 @@ ${charter.purpose}
7112
7189
  return { agent: agent2, releasedTasks };
7113
7190
  }
7114
7191
  /** Writes one message and its event. Callers hold the mutex and have authorized the author. */
7115
- async appendMessage(author, channel, body) {
7192
+ async appendMessage(author, channel, body, notice) {
7116
7193
  await this.assertChannelOpen(channel);
7117
- return this.writeMessage(this.paths.channelDir(channel), { author, channel }, body);
7194
+ return this.writeMessage(this.paths.channelDir(channel), { author, channel, ...notice === void 0 ? {} : { notice } }, body);
7118
7195
  }
7119
7196
  /** A thread's message carries the thread's channel; a caller naming another channel is refused. */
7120
7197
  async appendThreadMessage(author, threadId, body, options = {}) {
@@ -411,6 +411,13 @@ var MessageStepSchema = z4.union([TaskStepSchema, ProposalStepSchema]);
411
411
  function isTaskStep(step) {
412
412
  return "stage" in step;
413
413
  }
414
+ var KnowledgeNoticeSchema = z4.object({
415
+ kind: z4.literal("knowledge"),
416
+ action: z4.enum(["written", "updated", "removed"]),
417
+ topic: NameSchema,
418
+ project: NameSchema.nullable()
419
+ });
420
+ var MessageNoticeSchema = z4.discriminatedUnion("kind", [KnowledgeNoticeSchema]);
414
421
  var MessageFrontmatterSchema = z4.object({
415
422
  id: UlidSchema,
416
423
  author: NameSchema,
@@ -422,6 +429,8 @@ var MessageFrontmatterSchema = z4.object({
422
429
  closes: UlidSchema.optional(),
423
430
  /** On a post a task verb made in the task's thread, or a decision in a proposal's: the step it recorded. */
424
431
  step: MessageStepSchema.optional(),
432
+ /** On a post a verb made about its work, such as a knowledge topic's note: what it records. */
433
+ notice: MessageNoticeSchema.optional(),
425
434
  ts: IsoDateTimeSchema,
426
435
  mentions: z4.array(NameSchema)
427
436
  });
@@ -1354,6 +1363,30 @@ var BranchChangesSchema = z7.object({
1354
1363
  files: z7.array(BranchFileChangeSchema),
1355
1364
  total: z7.number().int().nonnegative()
1356
1365
  });
1366
+ var BranchDiffReadSchema = z7.object({
1367
+ repo: ProjectRepoSchema,
1368
+ branch: BranchNameSchema,
1369
+ path: BranchPathSchema.min(1)
1370
+ });
1371
+ var BranchFileDiffSchema = z7.object({
1372
+ head: BranchCommitSchema,
1373
+ path: BranchPathSchema,
1374
+ status: BranchFileChangeSchema.shape.status,
1375
+ patch: z7.string().nullable(),
1376
+ truncated: z7.boolean()
1377
+ });
1378
+ function patchHunks(patch, limit2) {
1379
+ if (/^Binary files .* differ$/m.test(patch)) {
1380
+ return { patch: null, truncated: false };
1381
+ }
1382
+ const start = patch.search(/^@@/m);
1383
+ const hunks = start === -1 ? "" : patch.slice(start);
1384
+ if (hunks.length <= limit2) {
1385
+ return { patch: hunks, truncated: false };
1386
+ }
1387
+ const cut = hunks.lastIndexOf("\n", limit2);
1388
+ return { patch: hunks.slice(0, cut === -1 ? limit2 : cut), truncated: true };
1389
+ }
1357
1390
  var WorkspaceConversationSchema = z7.discriminatedUnion("kind", [
1358
1391
  z7.object({ kind: z7.literal("thread"), id: UlidSchema }),
1359
1392
  z7.object({ kind: z7.literal("channel"), scope: NameSchema, name: NameSchema })
@@ -1386,6 +1419,8 @@ var RunnerMessageSchema = z7.discriminatedUnion("type", [
1386
1419
  request: z7.string().min(1),
1387
1420
  read: BranchChangesReadSchema
1388
1421
  }),
1422
+ /** Answered with a `BranchFileDiff`, or null when the branch does not exist or left the path alone. */
1423
+ z7.object({ type: z7.literal("diff"), request: z7.string().min(1), read: BranchDiffReadSchema }),
1389
1424
  /** Answered with whether the CLI accepted it; that it took it comes as a `steered` event. */
1390
1425
  z7.object({
1391
1426
  type: z7.literal("steer"),
@@ -1787,7 +1822,7 @@ var RunnerConfigSchema = z11.object({
1787
1822
  });
1788
1823
 
1789
1824
  // packages/shared/dist/version.js
1790
- var STELLARIS_VERSION = "0.3.15";
1825
+ var STELLARIS_VERSION = "0.3.17";
1791
1826
 
1792
1827
  // packages/board-core/dist/errors.js
1793
1828
  var BoardError = class extends Error {
@@ -2145,18 +2180,6 @@ function lineCount(value) {
2145
2180
  function fileStatus(letter) {
2146
2181
  return letter === "A" ? "added" : letter === "D" ? "deleted" : "modified";
2147
2182
  }
2148
- function hunksOf(patch) {
2149
- if (/^Binary files .* differ$/m.test(patch)) {
2150
- return { patch: null, truncated: false };
2151
- }
2152
- const start = patch.search(/^@@/m);
2153
- const hunks = start === -1 ? "" : patch.slice(start);
2154
- if (hunks.length <= PATCH_LIMIT_CHARS) {
2155
- return { patch: hunks, truncated: false };
2156
- }
2157
- const cut = hunks.lastIndexOf("\n", PATCH_LIMIT_CHARS);
2158
- return { patch: hunks.slice(0, cut === -1 ? PATCH_LIMIT_CHARS : cut), truncated: true };
2159
- }
2160
2183
  async function git(args, cwd) {
2161
2184
  const result = await execa("git", [...BOARD_IDENTITY, ...args], {
2162
2185
  cwd,
@@ -2295,7 +2318,8 @@ var HomeRepos = class {
2295
2318
  if (others.length > 0 && (status !== "added" || conflictCopyOf(file) === null)) {
2296
2319
  continue;
2297
2320
  }
2298
- files.push({ path: file, status, ...hunksOf(await read(home, [...range, "--", file])) });
2321
+ const patch = await read(home, [...range, "--", file]);
2322
+ files.push({ path: file, status, ...patchHunks(patch, PATCH_LIMIT_CHARS) });
2299
2323
  }
2300
2324
  return files;
2301
2325
  }
@@ -2980,6 +3004,12 @@ var KNOWLEDGE_REMOVAL = "knowledge-removal-granted";
2980
3004
  var CHANNEL_CONVERSATIONS = "channel-conversations";
2981
3005
  var DASHBOARD_UPDATES = "dashboard-updates-granted";
2982
3006
  var CRON_VERBS = "cron-verbs-granted";
3007
+ var KNOWLEDGE_NOTICES = "knowledge-notices";
3008
+ var KnowledgeEventSchema = z13.object({
3009
+ topic: NameSchema,
3010
+ project: NameSchema.nullable(),
3011
+ replaced: z13.boolean().optional()
3012
+ });
2983
3013
  var CRON_VERB_NAMES = ["create_cron", "update_cron", "remove_cron"];
2984
3014
  var OLD_DASHBOARD_LINE = "Agents may edit this file. It is rendered by the board UI.";
2985
3015
  var DASHBOARD_LINE = "The project's members keep this page current with update_dashboard.";
@@ -3183,7 +3213,8 @@ var Board = class _Board {
3183
3213
  KNOWLEDGE_REMOVAL,
3184
3214
  CHANNEL_CONVERSATIONS,
3185
3215
  DASHBOARD_UPDATES,
3186
- CRON_VERBS
3216
+ CRON_VERBS,
3217
+ KNOWLEDGE_NOTICES
3187
3218
  ].filter((name) => !applied.includes(name));
3188
3219
  if (pending.length === 0) {
3189
3220
  return;
@@ -3225,8 +3256,49 @@ var Board = class _Board {
3225
3256
  if (pending.includes(CRON_VERBS)) {
3226
3257
  await this.grantToEveryRole(CRON_VERB_NAMES);
3227
3258
  }
3259
+ if (pending.includes(KNOWLEDGE_NOTICES)) {
3260
+ await this.noticeKnowledgeNotes();
3261
+ }
3228
3262
  await writeJson(file, { applied: [...applied, ...pending] });
3229
3263
  }
3264
+ /**
3265
+ * Gives each knowledge note from before notes carried their notice the notice it would carry
3266
+ * now. The event log, not the note's words, says which post is one: a knowledge verb appends
3267
+ * its event and then its note under the mutex, so a note is the post right after such an event,
3268
+ * by the same actor, at the top of the general channel of the topic's place. A post written to
3269
+ * look like a note follows no such event and is left as it is.
3270
+ */
3271
+ async noticeKnowledgeNotes() {
3272
+ let before;
3273
+ for (const event of await this.events.readSince(null, Number.POSITIVE_INFINITY)) {
3274
+ const verb = before;
3275
+ before = event;
3276
+ if (event.type !== "message.posted" || verb === void 0 || verb.actor !== event.actor || verb.type !== "knowledge.written" && verb.type !== "knowledge.removed") {
3277
+ continue;
3278
+ }
3279
+ const knowledge = KnowledgeEventSchema.safeParse(verb.payload);
3280
+ const id = UlidSchema.safeParse(event.payload["id"]);
3281
+ if (!knowledge.success || !id.success || (event.payload["thread"] ?? null) !== null || event.payload["channel"] !== channelRef(knowledge.data.project, "general")) {
3282
+ continue;
3283
+ }
3284
+ const { topic, project, replaced } = knowledge.data;
3285
+ const file = this.paths.messageFile(this.paths.channelDir(channelRef(project, "general")), id.data, event.actor);
3286
+ if (!await exists(file)) {
3287
+ continue;
3288
+ }
3289
+ const { data, body, error } = await readLooseMarkdown(file);
3290
+ if (error !== null || data["notice"] !== void 0) {
3291
+ continue;
3292
+ }
3293
+ const notice = {
3294
+ kind: "knowledge",
3295
+ action: verb.type === "knowledge.removed" ? "removed" : replaced === true ? "updated" : "written",
3296
+ topic,
3297
+ project
3298
+ };
3299
+ await writeMarkdown(file, { ...data, notice }, body);
3300
+ }
3301
+ }
3230
3302
  /**
3231
3303
  * Grants `verb` once to every charter granting `write_knowledge`, the work roles' charters in
3232
3304
  * practice; seed roles have it from their seed.
@@ -4586,7 +4658,12 @@ ${task.body}`;
4586
4658
  replaced
4587
4659
  });
4588
4660
  const where = args.project === null ? "general" : channelRef(args.project, "general");
4589
- await this.appendMessage(actor.name, where, `Knowledge ${replaced ? "updated" : "written"}: ${args.topic}. It is under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`);
4661
+ await this.appendMessage(actor.name, where, `Knowledge ${replaced ? "updated" : "written"}: ${args.topic}. It is under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`, {
4662
+ kind: "knowledge",
4663
+ action: replaced ? "updated" : "written",
4664
+ topic: args.topic,
4665
+ project: args.project
4666
+ });
4590
4667
  return { ...data, body: args.body };
4591
4668
  });
4592
4669
  }
@@ -4619,7 +4696,7 @@ ${task.body}`;
4619
4696
  project: args.project
4620
4697
  });
4621
4698
  const where = args.project === null ? "general" : channelRef(args.project, "general");
4622
- await this.appendMessage(actor.name, where, `Knowledge removed: ${args.topic}. It is no longer under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`);
4699
+ await this.appendMessage(actor.name, where, `Knowledge removed: ${args.topic}. It is no longer under knowledge/${args.topic}.md${args.project === null ? " of the society" : ""}.`, { kind: "knowledge", action: "removed", topic: args.topic, project: args.project });
4623
4700
  return removed;
4624
4701
  });
4625
4702
  }
@@ -7242,9 +7319,9 @@ ${charter.purpose}
7242
7319
  return { agent, releasedTasks };
7243
7320
  }
7244
7321
  /** Writes one message and its event. Callers hold the mutex and have authorized the author. */
7245
- async appendMessage(author, channel, body) {
7322
+ async appendMessage(author, channel, body, notice) {
7246
7323
  await this.assertChannelOpen(channel);
7247
- return this.writeMessage(this.paths.channelDir(channel), { author, channel }, body);
7324
+ return this.writeMessage(this.paths.channelDir(channel), { author, channel, ...notice === void 0 ? {} : { notice } }, body);
7248
7325
  }
7249
7326
  /** A thread's message carries the thread's channel; a caller naming another channel is refused. */
7250
7327
  async appendThreadMessage(author, threadId, body, options = {}) {
@@ -10747,6 +10824,18 @@ var RunnerHub = class {
10747
10824
  }
10748
10825
  return changes;
10749
10826
  }
10827
+ /**
10828
+ * What a branch of a project's repository did to one file since it left the default branch, read
10829
+ * on the runner the project lives on, with the same refusals as `branchChanges`.
10830
+ */
10831
+ async branchDiff(project, branch, path10) {
10832
+ const { seat, repo } = await this.projectSeat(project, "branchChanges", "list changes");
10833
+ const diff = BranchFileDiffSchema.nullable().parse(await this.request(seat, (request) => ({ type: "diff", request, read: { repo, branch, path: path10 } }), FILE_TIMEOUT_MS));
10834
+ if (diff === null) {
10835
+ throw new BoardError("NOT_FOUND", `${branch} did not change ${path10}`);
10836
+ }
10837
+ return diff;
10838
+ }
10750
10839
  /** The models a CLI offers, asked of a connected runner that has it; none when no runner has it. */
10751
10840
  /**
10752
10841
  * The connected runner a model list for `cli` comes from: the first of `prefer` that has the CLI,
@@ -11681,6 +11770,13 @@ function createApp(deps) {
11681
11770
  }
11682
11771
  return c.json(await deps.runners.branchChanges(task.project, `task/${task.id}`));
11683
11772
  });
11773
+ api.get("/tasks/:id/diff/:path{.+}", async (c) => {
11774
+ const { task } = await board2.findTask(UlidSchema.parse(c.req.param("id")));
11775
+ if (deps.runners === void 0) {
11776
+ throw new BoardError("NOT_FOUND", "this board has no runners to read a task's branch from");
11777
+ }
11778
+ return c.json(await deps.runners.branchDiff(task.project, `task/${task.id}`, BranchPathSchema.parse(c.req.param("path"))));
11779
+ });
11684
11780
  api.get("/tasks/:id/files/:path{.+}", (c) => taskFile(c, c.req.param("path")));
11685
11781
  api.get("/threads", async (c) => c.json(await board2.listThreads()));
11686
11782
  api.get("/requests", async (c) => c.json(await board2.listRequests()));
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "codex",
9
9
  "multi-agent"
10
10
  ],
11
- "version": "0.3.15",
11
+ "version": "0.3.17",
12
12
  "license": "MIT",
13
13
  "homepage": "https://github.com/kr4t0n/stellaris",
14
14
  "repository": {
@@ -0,0 +1 @@
1
+ import{Lt as e,Sn as t,x as n}from"./format-Cp_C4ygr.js";import{D as r,n as i,r as a,t as o,v as s}from"./index-BXHV32GA.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=e(),d=r({select:e=>e.location.state.__TSR_index}),f=a(),p=s(),m=n(),h=i(f,d);if(h===null)return t;let g=o(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{Sn as e,Tn as t,bn as n,k as r,t as i,xn as a}from"./format-BORdp4w-.js";import{c as o,l as s,s as c}from"./compose-D7DOz6kC.js";import{t as l}from"./link-1v5lugnf.js";import{n as u,r as d}from"./ThreadForms-RnrV7V5X.js";var f=t(e(),1),p=a();function m({project:e,onDone:t}){let{api:i}=r(),a=n(),l=o(),[m,h]=(0,f.useState)(``),[g,_]=(0,f.useState)(``),v=(0,f.useRef)(null);(0,f.useEffect)(()=>v.current?.focus(),[]);let y=s({mutationFn:()=>i.createChannel({project:e,name:m.trim(),purpose:g.trim()}),onSuccess:async e=>{await a.invalidateQueries({queryKey:[`channels`]}),t(),await l({to:`/c/$`,params:{_splat:e}})}});return(0,p.jsxs)(`form`,{"aria-label":`New channel`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),y.mutate()},children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`div`,{className:`w-40 shrink-0`,children:(0,p.jsx)(`input`,{ref:v,value:m,maxLength:64,spellCheck:!1,"aria-label":`Channel name`,placeholder:`release-0-4`,onChange:e=>h(e.target.value),className:`${u} font-mono`})}),(0,p.jsx)(`input`,{value:g,"aria-label":`Purpose`,placeholder:`What the channel is for`,onChange:e=>_(e.target.value),className:`${u} min-w-0 flex-1`}),(0,p.jsx)(c,{onClick:t,children:`Cancel`}),(0,p.jsx)(c,{variant:`primary`,type:`submit`,disabled:y.isPending||m.trim()===``||g.trim()===``,children:y.isPending?`Opening…`:`Open`})]}),(0,p.jsx)(`p`,{className:`text-meta`,children:e===null?`Announced in the society's general, and followed by whoever subscribes to it; you read every channel without following one.`:`Announced in ${e}'s general, where its members choose to follow it; you read every channel without following one. Tasks filed in it hang their threads here, and it is archived once its tasks are done.`}),(0,p.jsx)(d,{error:y.error})]})}function h({channel:e,onDone:t}){let{api:i}=r(),a=n(),[o,l]=(0,f.useState)(``),m=s({mutationFn:()=>i.archiveChannel({channel:e,reason:o.trim()}),onSuccess:async()=>{await a.invalidateQueries({queryKey:[`channels`]}),t()}});return(0,p.jsxs)(`form`,{"aria-label":`Archive the channel`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),m.mutate()},children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`input`,{value:o,"aria-label":`Reason`,placeholder:`Why its work is done`,onChange:e=>l(e.target.value),className:`${u} min-w-0 flex-1`}),(0,p.jsx)(c,{onClick:t,children:`Cancel`}),(0,p.jsx)(c,{variant:`primary`,type:`submit`,disabled:m.isPending||o.trim()===``,children:m.isPending?`Archiving…`:`Archive channel`})]}),(0,p.jsx)(`p`,{className:`text-meta`,children:`Its open threads close, nobody follows it, and nothing more is posted or filed here; its posts, threads, and tasks stay readable. The board refuses while a task filed here is in play.`}),(0,p.jsx)(d,{error:m.error})]})}function g({channels:e,now:t}){return e.length===0?(0,p.jsx)(`p`,{className:`text-meta`,children:`No channels.`}):(0,p.jsx)(`ul`,{className:`space-y-1`,children:e.map(e=>(0,p.jsxs)(`li`,{children:[(0,p.jsxs)(l,{to:`/c/$`,params:{_splat:e.ref},className:`text-sm hover:text-fg-primary ${e.archived===void 0?`text-fg-secondary`:`text-fg-tertiary`}`,children:[`# `,e.name]}),(0,p.jsxs)(`span`,{className:`text-meta`,children:[` `,`· `,e.messages,` messages`,e.archived===void 0?``:` · archived ${i(e.archived.at,t)}`]})]},e.ref))})}export{g as n,m as r,h as t};
1
+ import{Cn as e,En as t,Sn as n,k as r,t as i,xn as a}from"./format-Cp_C4ygr.js";import{c as o,l as s,s as c}from"./compose-96HAETM2.js";import{t as l}from"./link-DIpiSYJj.js";import{n as u,r as d}from"./ThreadForms-BPowHd4M.js";var f=t(e(),1),p=n();function m({project:e,onDone:t}){let{api:n}=r(),i=a(),l=o(),[m,h]=(0,f.useState)(``),[g,_]=(0,f.useState)(``),v=(0,f.useRef)(null);(0,f.useEffect)(()=>v.current?.focus(),[]);let y=s({mutationFn:()=>n.createChannel({project:e,name:m.trim(),purpose:g.trim()}),onSuccess:async e=>{await i.invalidateQueries({queryKey:[`channels`]}),t(),await l({to:`/c/$`,params:{_splat:e}})}});return(0,p.jsxs)(`form`,{"aria-label":`New channel`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),y.mutate()},children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`div`,{className:`w-40 shrink-0`,children:(0,p.jsx)(`input`,{ref:v,value:m,maxLength:64,spellCheck:!1,"aria-label":`Channel name`,placeholder:`release-0-4`,onChange:e=>h(e.target.value),className:`${u} font-mono`})}),(0,p.jsx)(`input`,{value:g,"aria-label":`Purpose`,placeholder:`What the channel is for`,onChange:e=>_(e.target.value),className:`${u} min-w-0 flex-1`}),(0,p.jsx)(c,{onClick:t,children:`Cancel`}),(0,p.jsx)(c,{variant:`primary`,type:`submit`,disabled:y.isPending||m.trim()===``||g.trim()===``,children:y.isPending?`Opening…`:`Open`})]}),(0,p.jsx)(`p`,{className:`text-meta`,children:e===null?`Announced in the society's general, and followed by whoever subscribes to it; you read every channel without following one.`:`Announced in ${e}'s general, where its members choose to follow it; you read every channel without following one. Tasks filed in it hang their threads here, and it is archived once its tasks are done.`}),(0,p.jsx)(d,{error:y.error})]})}function h({channel:e,onDone:t}){let{api:n}=r(),i=a(),[o,l]=(0,f.useState)(``),m=s({mutationFn:()=>n.archiveChannel({channel:e,reason:o.trim()}),onSuccess:async()=>{await i.invalidateQueries({queryKey:[`channels`]}),t()}});return(0,p.jsxs)(`form`,{"aria-label":`Archive the channel`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),m.mutate()},children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`input`,{value:o,"aria-label":`Reason`,placeholder:`Why its work is done`,onChange:e=>l(e.target.value),className:`${u} min-w-0 flex-1`}),(0,p.jsx)(c,{onClick:t,children:`Cancel`}),(0,p.jsx)(c,{variant:`primary`,type:`submit`,disabled:m.isPending||o.trim()===``,children:m.isPending?`Archiving…`:`Archive channel`})]}),(0,p.jsx)(`p`,{className:`text-meta`,children:`Its open threads close, nobody follows it, and nothing more is posted or filed here; its posts, threads, and tasks stay readable. The board refuses while a task filed here is in play.`}),(0,p.jsx)(d,{error:m.error})]})}function g({channels:e,now:t}){return e.length===0?(0,p.jsx)(`p`,{className:`text-meta`,children:`No channels.`}):(0,p.jsx)(`ul`,{className:`space-y-1`,children:e.map(e=>(0,p.jsxs)(`li`,{children:[(0,p.jsxs)(l,{to:`/c/$`,params:{_splat:e.ref},className:`text-sm hover:text-fg-primary ${e.archived===void 0?`text-fg-secondary`:`text-fg-tertiary`}`,children:[`# `,e.name]}),(0,p.jsxs)(`span`,{className:`text-meta`,children:[` `,`· `,e.messages,` messages`,e.archived===void 0?``:` · archived ${i(e.archived.at,t)}`]})]},e.ref))})}export{g as n,m as r,h as t};
@@ -0,0 +1,2 @@
1
+ import{Cn as e,En as t,R as n,Sn as r,V as i,_ as a,b as o,c as s,ht as c,k as l,t as u,tn as d,x as f}from"./format-Cp_C4ygr.js";import{s as p}from"./compose-96HAETM2.js";import{t as m}from"./link-DIpiSYJj.js";import{S as h,i as g,k as _,s as v}from"./index-BXHV32GA.js";import{i as y}from"./ThreadForms-BPowHd4M.js";import{t as b}from"./ChannelForms-B3XwkJj_.js";import{t as x}from"./MessageItem-BkDlfhQC.js";import{n as S,t as C}from"./Pane-DHXhVwfI.js";import{n as w}from"./ThreadCard-DsIkg4Br.js";import{t as T}from"./useStickyScroll-7ZZcyLI0.js";var E=t(e(),1);function D(e,t){let n=e.notices.at(-1);return n!==void 0&&n.kind===`knowledge`&&t.kind===`knowledge`&&n.action!==`removed`&&t.action===`updated`&&n.topic===t.topic&&n.project===t.project}function O(e,t){let n=[],r=null;for(let i of e){let e=t(i),a=e?.notice;e===void 0||a===void 0?(n.push({kind:`item`,item:i}),r=null):r!==null&&D(r,a)?(r.messages.push(e),r.notices.push(a)):(r={messages:[e],notices:[a]},n.push({kind:`notices`,run:r}))}return n}function k(e){let[t]=e,n=e.length-1;return t===void 0||t.action===`removed`?{did:`removed`,times:null}:t.action===`written`?{did:`wrote`,times:n===0?null:`then updated it ${n===1?`once`:`${n} times`}`}:{did:`updated`,times:n===0?null:`${e.length} times`}}function A(e){let t=[...new Set(e)];return t.length<=2?t.join(` and `):`${t.slice(0,-1).join(`, `)}, and ${t.at(-1)??``}`}var j=r();function M(){return(0,j.jsx)(`svg`,{viewBox:`0 0 16 16`,"aria-hidden":`true`,className:`size-3.5`,children:(0,j.jsx)(`path`,{d:`M8 4.2C6.4 3 4.4 2.8 2.2 3.4v9.2c2.2-.6 4.2-.4 5.8.8m0-9.2c1.6-1.2 3.6-1.4 5.8-.8v9.2c-2.2-.6-4.2-.4-5.8.8m0-9.2v9.2`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.2`,strokeLinejoin:`round`})})}function N({notices:e}){let[t]=e;if(t===void 0)return null;let{did:n,times:r}=k(e);return(0,j.jsxs)(j.Fragment,{children:[n,` knowledge`,` `,t.action===`removed`?(0,j.jsx)(`span`,{className:`text-fg-secondary`,children:t.topic}):(0,j.jsx)(m,{to:`/knowledge/$scope/$topic`,params:{scope:t.project??`society`,topic:t.topic},className:`text-fg-secondary hover:text-fg-primary`,children:t.topic}),r===null?null:` · ${r}`]})}function P(e){let t=e.notices.filter(e=>e.kind===`knowledge`);return{mark:(0,j.jsx)(M,{}),text:(0,j.jsx)(N,{notices:t})}}function F({run:e,now:t}){let n=v(),r=e.messages.at(-1);if(r===void 0)return null;let{mark:i,text:a}=P(e);return(0,j.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-1 text-meta`,children:[(0,j.jsx)(`span`,{className:`grid w-7 shrink-0 place-items-center text-fg-muted`,children:i}),(0,j.jsxs)(`p`,{className:`min-w-0 flex-1 truncate`,children:[A(e.messages.map(e=>n(e.author))),` `,a]}),(0,j.jsx)(`time`,{dateTime:r.ts,title:e.messages.map(e=>`${n(e.author)} ${e.ts}`).join(`
2
+ `),className:`shrink-0`,children:u(r.ts,t)})]})}function I(){let{_splat:e=`general`}=_({from:`/c/$`});return(0,j.jsx)(L,{channel:e},e)}function L({channel:e}){let{api:t}=l(),r=d({queryKey:[`channel`,e],queryFn:()=>t.channel(e)}),m=n(),_=a(),v=f(),D=s(),k=o(3e4),[A,M]=(0,E.useState)(!1),[N,P]=(0,E.useState)(!1),I=(0,E.useMemo)(()=>{let t=(r.data??[]).map(e=>({kind:`message`,at:e.ts,id:e.id,message:e})),n=(m.data??[]).filter(t=>t.channel===e).map(e=>({kind:`thread`,at:e.openedAt,id:e.id,thread:e}));return[...t,...n].toSorted((e,t)=>e.at.localeCompare(t.at)||e.id.localeCompare(t.id))},[r.data,m.data,e]),L=(0,E.useMemo)(()=>O(I,e=>e.kind===`message`?e.message:void 0),[I]),R=r.data?.at(-1)?.id??null;(0,E.useEffect)(()=>h(e,R),[e,R]);let{ref:z,onScroll:B}=T(),[V,H]=e.split(`/`),U=H??V??e,W=H===void 0?void 0:v.data?.find(e=>e.slug===V),G=H===void 0?`society`:W?.name??V,K=D.data?.find(t=>t.ref===e)?.archived,q=W?.archived!==void 0||K!==void 0,J=!q&&!c(H===void 0?null:V??null,U),Y=I.filter(e=>e.kind===`thread`&&e.thread.state===`open`);return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(C,{title:`# ${U}`,subtitle:`${G} · ${r.data?.length??0} messages${Y.length>0?` · ${Y.length} open threads`:``}`,trailing:A||N||q?null:(0,j.jsxs)(j.Fragment,{children:[J?(0,j.jsx)(p,{onClick:()=>P(!0),children:`Archive…`}):null,(0,j.jsx)(p,{onClick:()=>M(!0),children:`New thread`})]})}),A?(0,j.jsx)(y,{channel:e,onDone:()=>M(!1)}):null,N?(0,j.jsx)(b,{channel:e,onDone:()=>P(!1)}):null,(0,j.jsx)(`div`,{ref:z,onScroll:B,className:`flex-1 overflow-y-auto py-2`,children:r.error instanceof i&&r.error.status===404?(0,j.jsxs)(S,{children:[`There is no channel `,e,`.`]}):r.data===void 0?(0,j.jsx)(S,{children:`Reading the channel…`}):I.length===0?(0,j.jsx)(S,{children:`Nothing has been said here yet.`}):L.map(e=>{if(e.kind===`notices`){let t=e.run.messages[0]?.id??``;return(0,j.jsx)(F,{run:e.run,now:k},t)}let{item:t}=e;return t.kind===`message`?(0,j.jsx)(x,{message:t.message,members:_.data,now:k},t.id):(0,j.jsx)(w,{thread:t.thread,now:k},t.id)})}),r.data===void 0?null:K===void 0?q?(0,j.jsxs)(`p`,{className:`border-t border-line px-4 py-3 text-meta`,children:[G,` is archived, so its channels are read-only.`]}):(0,j.jsx)(g,{target:{channel:e},placeholder:`Message #${U}`}):(0,j.jsxs)(`p`,{className:`border-t border-line px-4 py-3 text-meta`,children:[`Archived `,u(K.at,k),` by `,K.by,`: `,K.reason,`. Its posts, threads, and tasks stay readable; nothing more is posted or filed here.`]})]})}export{I as ChannelView};
@@ -0,0 +1,2 @@
1
+ import{B as e,Cn as t,D as n,E as r,En as i,G as a,L as o,Sn as s,T as c,V as l,_ as u,a as d,b as f,f as p,k as m,kt as h,l as g,m as _,o as v,p as y,pt as b,t as x,v as S,xn as C,z as w}from"./format-Cp_C4ygr.js";import{l as T,s as E}from"./compose-96HAETM2.js";import{t as D}from"./link-DIpiSYJj.js";import{t as ee}from"./CliIcon-CFObB9XW.js";import{O,_ as k,c as A,d as j,f as te,h as M,i as ne,k as re,l as N,m as P,p as ie,u as ae,v as oe}from"./index-BXHV32GA.js";import{n as se,r as F}from"./ThreadForms-BPowHd4M.js";import{t as I}from"./Markdown-BO_bF8WD.js";import{n as L,t as ce}from"./Pane-DHXhVwfI.js";import{t as le}from"./useStickyScroll-7ZZcyLI0.js";import{a as R,c as ue,i as de,l as fe,n as pe,o as z,s as B,t as me,u as V}from"./citizen-DFaT61S1.js";import{n as H}from"./Picker-CQQ7hj8T.js";var U=i(t(),1),W=s(),he={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 ge({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 `,j(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)(ge,{step:e,open:t},e.seq))})]})}function _e({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 `,x(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 `,he[e.end.exitReason],` `,x(e.end.at,n),e.fromStart?` · ${N(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 J=30,ve={turn:`turn`,board:`board`,merge:`both kept`},ye={turn:`Changed by a turn`,board:`Written by the board`,merge:`Both versions kept`};function be(e){return e.status===`added`?`new`:e.status===`deleted`?`deleted`:e.added===null||e.removed===null?`binary`:`+${e.added} −${e.removed}`}function xe(e){return e.files.map(e=>`${e.path} ${be(e)}`).join(`, `)}function Se(e){return e.startsWith(`@@`)||e.startsWith(`\\`)?`text-fg-muted`:e.startsWith(`+`)?`text-emerald-300`:e.startsWith(`-`)?`text-red-300`:`text-fg-tertiary`}function Ce({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 ${Se(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 we({name:e,change:t}){let n=p(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)(D,{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)(Ce,{file:e},e.path))]})}function Te({name:e,change:t,now:n}){let[r,i]=(0,U.useState)(!1),a=t.files.length===0?t.subject:xe(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":`${ye[t.kind]} ${x(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:ve[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:x(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)(we,{name:e,change:t}):null]})})}function Ee({name:e}){let[t,n]=(0,U.useState)(J),r=_(e,t),i=f(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)(Te,{name:e,change:t,now:i},t.commit))}),o?(0,W.jsx)(`button`,{type:`button`,onClick:()=>n(t+J),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:`Show earlier changes`}):null]})}function Y({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 De({member:e,charter:t}){let n=S(e.name),r=v(e.name),i=y(e.name),a=f(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)(Y,{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`,` `,x(e.since,a)]})]},e.path))})]}),(0,W.jsx)(Y,{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)(Y,{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)(Y,{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)(Y,{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 Oe(e,t){let n=w(e,t?.turnId??null);return{turn:(0,U.useMemo)(()=>t===void 0||n.data===void 0?void 0:ie(n.data,e,t.project,t),[t,n.data,e]),loading:t?.turnId!==void 0&&n.isPending,missing:t!==void 0&&(t.turnId===void 0||n.isError)}}var X=50;function ke({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=oe(),c=ue(t),l=t.thread===void 0?t.channel===void 0?null:`#${t.channel}`: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:[R(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:[me(t),` `,x(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:B(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)(k,{text:u,links:!1})})]}),i?(0,W.jsx)(Ae,{name:e,entry:t,text:u,tone:d}):null]})})}function Ae({name:e,entry:t,text:n,tone:r}){let i=Oe(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)(k,{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 je({name:t,opened:n}){let[r,i]=(0,U.useState)(X),a=e(t,r),o=f(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:[t,` has not finished a turn yet.`]});let c=pe(s),l=c.usage===null?``:` · ${B(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]}),n!==null&&!s.some(e=>e.turnId===n)?(0,W.jsx)(`p`,{className:`px-4 pb-1 text-meta`,children:a.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,W.jsx)(`ol`,{children:s.map(e=>(0,W.jsx)(ke,{name:t,entry:e,now:o,opened:n!==null&&e.turnId===n},e.id))}),a.data.length===r?(0,W.jsxs)(`button`,{type:`button`,onClick:()=>i(r+X),className:`px-4 py-3 text-xs text-fg-tertiary hover:text-fg-primary`,children:[`Show `,X,` earlier turns`]}):null]})}var Z=``,Q=``;function Me(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 Ne(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 Pe({member:e,onDone:t}){let{api:n}=m(),r=C(),i=d(e.name),a=e.model??Z,o=e.effort??Q,[s,c]=(0,U.useState)(a),[u,f]=(0,U.useState)(o),p=T({mutationFn:async()=>{s!==a&&await n.setModel(e.name,s===Z?null:s),u!==o&&await n.setEffort(e.name,u===Q?null:u)},onSettled:()=>void r.invalidateQueries({queryKey:[`members`]}),onSuccess:t}),h=i.data?.models??[],g=e.model!==void 0&&!h.some(t=>t.id===e.model)?e.model:null,_=e=>h.find(t=>e===Z?t.isDefault:t.id===e),v=_(s)?.efforts??[],y=u!==Q&&!v.some(e=>e.id===u)?u:null,b=e=>{c(e);let t=_(e)?.efforts??[];u!==Q&&!t.some(e=>e.id===u)&&f(Q)},x=s!==a||u!==o;return(0,W.jsxs)(`form`,{"aria-label":`Model of ${e.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),p.mutate()},children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[i.isPending?(0,W.jsxs)(`p`,{className:`min-w-0 flex-1 truncate text-meta`,children:[`Asking `,e.cli,` for its models…`]}):i.error===null?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(H,{label:`Model`,choices:Me(h,g),value:s,onChange:b}),v.length===0&&y===null?null:(0,W.jsx)(`div`,{className:`flex w-32 shrink-0`,children:(0,W.jsx)(H,{label:`Effort`,choices:Ne(_(s),y),value:u,onChange:f,listClassName:`right-0 w-64`})})]}):(0,W.jsxs)(`p`,{role:`alert`,className:`min-w-0 flex-1 truncate text-xs text-red-400`,children:[e.cli,` did not list its models:`,` `,i.error instanceof l?i.error.message:`the board server did not answer`]}),(0,W.jsx)(E,{onClick:t,children:`Cancel`}),(0,W.jsx)(E,{variant:`primary`,type:`submit`,disabled:p.isPending||!x||i.error!==null,children:p.isPending?`Saving…`:`Save`})]}),i.data===void 0?null:(0,W.jsxs)(`p`,{className:`text-meta`,children:[`As `,i.data.cli,` on `,i.data.runner,` lists them, where this citizen's turns run.`]}),(0,W.jsx)(F,{error:p.error})]})}var $=``;function Fe(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 Ie(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:Fe(e,t)}))]}function Le({member:e,onDone:t}){let{api:n}=m(),i=C(),a=r(),o=e.homeRunner??$,[s,c]=(0,U.useState)(o),l=T({mutationFn:()=>n.setRunner(e.name,s===$?null:s),onSuccess:()=>{i.invalidateQueries({queryKey:[`members`]}),t()}});return(0,W.jsxs)(`form`,{"aria-label":`Runner of ${e.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),l.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)(H,{label:`Runner`,choices:Ie(a.data,e),value:s,onChange:c}),(0,W.jsx)(E,{onClick:t,children:`Cancel`}),(0,W.jsx)(E,{variant:`primary`,type:`submit`,disabled:l.isPending||s===o,children:l.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)(F,{error:l.error})]})}function Re(e){if(e.thread!==void 0)return{threadId:e.thread};let t=e.scope===`society`?null:e.scope;return e.channel===void 0?{channel:e.askedIn??h(t,`general`)}:{channel:h(t,e.channel)}}function ze({name:e,turn:t}){let{api:n}=m(),r=C(),[i,a]=(0,U.useState)(!1),o=T({mutationFn:()=>n.stopTurn(t.turnId),onSuccess:()=>{a(!1),r.invalidateQueries({queryKey:[`scheduler`]})}});return(0,W.jsxs)(`div`,{className:`border-t border-line`,children:[(0,W.jsx)(ne,{target:Re(t),initialText:`@${e} `,placeholder:t.steerable?`Message ${e} while it works`:`Message ${e} for its next turn`,className:`px-3 pt-3 pb-2`},t.turnId),t.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:i?`Ends the turn now. What it was shown counts as read; its stages stay held.`:t.steerable?`Posts reach the turn at its next step.`:`This runner delivers posts after the turn ends.`}),i?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(E,{onClick:()=>{a(!1),o.reset()},children:`Keep it running`}),(0,W.jsx)(E,{variant:`primary`,disabled:o.isPending,onClick:()=>{o.mutate()},children:o.isPending?`Stopping…`:`Stop the turn`})]}):(0,W.jsx)(E,{onClick:()=>a(!0),children:`Stop…`})]}):null,o.error===null?null:(0,W.jsx)(`div`,{className:`px-3 pb-3`,children:(0,W.jsx)(F,{error:o.error})})]})}function Be({member:e,scopes:t,preferred:n,running:r,paused:i,onDone:a}){let{api:o}=m(),s=C(),[c,l]=(0,U.useState)(`manual`),[u,d]=(0,U.useState)(n!==null&&t.includes(n)?n:t[0]??``),[f,p]=(0,U.useState)(``),h=(0,U.useRef)(null);(0,U.useEffect)(()=>h.current?.focus(),[]);let g=T({mutationFn:()=>o.wake({agent:e.name,project:u,kind:c,...f.trim()===``?{}:{reason:f.trim()}}),onSuccess:()=>{s.invalidateQueries({queryKey:[`scheduler`]}),a()}}),_=R(u),v=c===`reflection`?`Asks ${e.name} to reflect at ${_}: consolidate its memory, skills, and profile, and take no new work. It restarts the reflection clock.`:`Starts a turn for ${e.name} at ${_} as soon as the scheduler takes it.`,y=i?` The society is paused, so it waits until you resume.`:r.includes(u)?` ${e.name} is in a turn there now; this one follows it.`:``;return(0,W.jsxs)(`form`,{"aria-label":`Wake ${e.name}`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),g.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 ${c===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:c===e,onChange:()=>l(e),className:`sr-only`}),e===`manual`?`A turn`:`A reflection`]},e))]}),(0,W.jsxs)(`div`,{className:`ml-auto flex w-52 items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`shrink-0 text-xs text-fg-tertiary`,children:`at`}),(0,W.jsx)(H,{label:`Where`,choices:de(t),value:u,onChange:d})]})]}),(0,W.jsx)(`textarea`,{ref:h,value:f,rows:2,placeholder:c===`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=>p(e.target.value),className:`${se} resize-none`}),(0,W.jsxs)(`p`,{className:`text-[11px] leading-relaxed text-fg-muted`,children:[v,y,` Each turn costs money.`]}),(0,W.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,W.jsx)(E,{onClick:a,children:`Cancel`}),(0,W.jsx)(E,{variant:`primary`,type:`submit`,disabled:g.isPending||u===``,children:g.isPending?`Waking…`:c===`reflection`?`Ask for a reflection`:`Wake ${e.name}`})]}),(0,W.jsx)(F,{error:g.error})]})}var Ve={working:`bg-emerald-500/15 text-emerald-300`,queued:`bg-amber-500/15 text-amber-300`,idle:`bg-surface-2 text-fg-tertiary`};function He({project:e,name:t}){let n=(o(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)(D,{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:b(e)?.name??e.stage})]})},e.id))})}function Ue(){let{name:e}=re({from:`/citizen/$name`}),{scope:t,tab:n,turn:r}=O({from:`/citizen/$name`});return(0,W.jsx)(Ge,{name:e,chosen:t??null,tab:n??`now`,turn:r??null},e)}var We=[{tab:`now`,label:`Now`},{tab:`turns`,label:`Turns`},{tab:`memory`,label:`Memory`},{tab:`history`,label:`History`}];function Ge({name:e,chosen:t,tab:r,turn:i}){let o=u(),s=c(),l=n(),d=M(),f=g(),[p,m]=(0,U.useState)(null),h=o.data?.find(t=>t.name===e);if(h===void 0)return(0,W.jsx)(L,{children:o.data===void 0?`Reading the roster…`:`There is no citizen ${e}.`});let _=a(l.data?.running??[]).filter(t=>t.agent===e),v=[...new Set(_.map(e=>e.scope))],y=_.map(e=>ae(e.agent,e.scope,e)),b=a(l.data?.pending??[]).find(t=>t.agent===e),x=v.length>0?`working`:b===void 0?`idle`:`queued`,S=P(d,e)[0],C=S?.model??h.lastModel,w=C??h.model??`CLI default`,T=h.model!==void 0&&h.model!==C?h.model:null,O=s.data?.find(e=>e.name===h.role),k=fe(h),A=h.status===`active`&&h.cli!==null,j=(f.data??[]).filter(t=>t.agent===e&&t.ended===void 0).length;return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(ce,{leading:h.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)(ee,{cli:h.cli,size:20})}),title:e,subtitle:(0,W.jsxs)(W.Fragment,{children:[h.role,` · `,w,T===null?``:` · set to ${T}`,h.effort===void 0?``:` · ${h.effort} effort`,h.homeRunner===void 0?``:` · on ${h.homeRunner}`,h.status===`retired`?` · retired`:``]}),trailing:(0,W.jsxs)(W.Fragment,{children:[j===0?null:(0,W.jsx)(D,{to:`/crons`,search:{agent:e},className:`inline-flex h-7 shrink-0 items-center rounded-md px-3 text-xs text-fg-tertiary transition-colors hover:bg-surface-2/70 hover:text-fg-primary focus-visible:ring-2 focus-visible:ring-fg-primary/30 focus-visible:outline-none`,children:j===1?`1 cron`:`${j} crons`}),A&&p===null?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(E,{onClick:()=>m(`model`),children:`Model…`}),(0,W.jsx)(E,{onClick:()=>m(`runner`),children:`Runner…`}),(0,W.jsx)(E,{onClick:()=>m(`wake`),children:`Wake…`})]}):null,(0,W.jsx)(`span`,{className:`shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium ${Ve[x]}`,children:x})]})}),p===`wake`?(0,W.jsx)(Be,{member:h,scopes:k,preferred:t?.split(`/`)[0]??S?.scope??null,running:v,paused:l.data?.paused??!1,onDone:()=>m(null)}):p===`model`?(0,W.jsx)(Pe,{member:h,onDone:()=>m(null)}):p===`runner`?(0,W.jsx)(Le,{member:h,onDone:()=>m(null)}):null,(0,W.jsx)(`nav`,{"aria-label":`Citizen views`,className:`flex gap-1 border-b border-line px-3 py-2`,children:We.map(n=>(0,W.jsx)(D,{to:`/citizen/$name`,params:{name:e},search:{...t===null?{}:{scope:t},...n.tab===`now`?{}:{tab:n.tab}},replace:!0,"aria-current":n.tab===r?`page`:void 0,className:`rounded-md px-2.5 py-1 text-xs transition-colors ${n.tab===r?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:n.label},n.tab))}),r===`turns`?(0,W.jsx)(je,{name:e,opened:i},i):r===`memory`?(0,W.jsx)(De,{member:h,charter:O}):r===`history`?(0,W.jsx)(Ee,{name:e}):(0,W.jsx)(qe,{name:e,chosen:t,lastTurnAt:h.lastTurnAt,state:x,runningScopes:v,runningKeys:y,runningTurns:(l.data?.turns??[]).filter(t=>t.agent===e),queuedScope:b?.scope??null})]})}function Ke(e){return e.toSorted((e,t)=>e.startedAt.localeCompare(t.startedAt))[0]}function qe({name:t,chosen:n,lastTurnAt:r,state:i,runningScopes:a,runningKeys:o,runningTurns:s,queuedScope:c}){let l=M(),u=f(5e3),{ref:d,onScroll:p}=le(),m=P(l,t),h=e(t,1),g=Oe(t,m.length===0?h.data?.at(-1):void 0),_=oe(),v=e=>e.end===null&&o.includes(ae(e.agent,e.scope,e)),y=n?.split(`/`)[0]??null,b=(n?.includes(`/`)===!0?m.find(e=>A(e)===n):void 0)??Ke(m.filter(e=>e.scope===y&&v(e)))??m.find(e=>A(e)===n)??Ke(m.filter(v))??m[0]??g.turn,S=e=>e.thread===void 0?e.channel===void 0?R(e.scope):`${R(e.scope)} · #${e.channel}`:`${R(e.scope)} · ${_.get(e.thread)?.title??`a thread`}`,C=b!==void 0&&v(b),w=b?.scope??a[0]??c,T=(b===void 0?void 0:s.find(e=>e.scope===b.scope&&e.thread===b.thread&&e.channel===b.channel))??(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 ${R(b.scope)} for ${b.fromStart?``:`at least `}${N(b.startedAt,u)}`:a.length>0?`In a turn at ${a.map(R).join(` and `)}`:c===null?r===void 0?`No turns yet`:`Last turn ${x(r,u)}`:`Queued for a turn at ${R(c)}`}),w===null||w===`society`?null:(0,W.jsx)(He,{project:w,name:t})]}),(0,W.jsx)(`div`,{ref:d,onScroll:p,className:`flex-1 overflow-y-auto px-4 py-3`,children:b===void 0?(0,W.jsx)(L,{children:i===`working`?`The turn has not reported a step yet.`:g.loading?`Reading the last turn…`:r===void 0?`${t} has not taken a turn yet.`:`${t}'s last turn kept no steps; Turns lists every finished one.`}):(0,W.jsxs)(W.Fragment,{children:[m.length>1?(0,W.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(e=>(0,W.jsxs)(D,{to:`/citizen/$name`,params:{name:t},search:{scope:A(e)},replace:!0,"aria-current":e===b?`true`:void 0,className:`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[11px] transition-colors ${e===b?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[v(e)?(0,W.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-400`}):null,S(e)]},A(e)))}):null,(0,W.jsxs)(`p`,{className:`text-caps`,children:[C?`This turn`:`Last turn`,` · `,S(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)(_e,{turn:b,running:C,now:u})]})}),T===void 0?null:(0,W.jsx)(ze,{name:t,turn:T})]})}export{Ue as CitizenView};
@@ -1 +1 @@
1
- import{D as e,W as t,_ as n,x as r,xn as i}from"./format-BORdp4w-.js";import{t as a}from"./link-1v5lugnf.js";import{t as o}from"./CliIcon-DxDvRRcX.js";import{n as s,t as c}from"./Pane-CODhA5zE.js";import{a as l,r as u}from"./citizen-BRSvyK2X.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=n(),h=e(),g=r();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};
1
+ import{D as e,G as t,Sn as n,_ as r,x as i}from"./format-Cp_C4ygr.js";import{t as a}from"./link-DIpiSYJj.js";import{t as o}from"./CliIcon-CFObB9XW.js";import{n as s,t as c}from"./Pane-DHXhVwfI.js";import{a as l,r as u}from"./citizen-DFaT61S1.js";var d=n();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 n=r(),h=e(),g=i();if(n.data===void 0)return(0,d.jsx)(s,{children:`Reading the roster…`});let _=n.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};
@@ -1 +1 @@
1
- import{xn as e}from"./format-BORdp4w-.js";var t=`M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656`,n={claude:{label:`Claude Code`,path:`M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z`,fill:`#D97757`,accent:`#fb923c`},codex:{label:`Codex`,path:`M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z`,fill:`#f5f5f5`,accent:`#10b981`}},r=e();function i({cli:e,size:t=16}){let i=n[e];return(0,r.jsx)(`svg`,{viewBox:`0 0 24 24`,width:t,height:t,"aria-hidden":`true`,className:`shrink-0`,children:(0,r.jsx)(`path`,{d:i.path,fill:i.fill,fillRule:`evenodd`,clipRule:`evenodd`})})}export{n,t as r,i as t};
1
+ import{Sn as e}from"./format-Cp_C4ygr.js";var t=`M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656`,n={claude:{label:`Claude Code`,path:`M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z`,fill:`#D97757`,accent:`#fb923c`},codex:{label:`Codex`,path:`M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z`,fill:`#f5f5f5`,accent:`#10b981`}},r=e();function i({cli:e,size:t=16}){let i=n[e];return(0,r.jsx)(`svg`,{viewBox:`0 0 24 24`,width:t,height:t,"aria-hidden":`true`,className:`shrink-0`,children:(0,r.jsx)(`path`,{d:i.path,fill:i.fill,fillRule:`evenodd`,clipRule:`evenodd`})})}export{n,t as r,i as t};
@@ -0,0 +1 @@
1
+ import{Cn as e,Ct as t,En as n,M as r,R as i,Sn as a,_ as o,b as s,dt as c,k as l,l as u,t as d,x as f,xn as p}from"./format-Cp_C4ygr.js";import{l as m,s as h}from"./compose-96HAETM2.js";import{t as g}from"./link-DIpiSYJj.js";import{t as _}from"./CliIcon-CFObB9XW.js";import{C as v,E as y,O as b,T as x,w as S}from"./index-BXHV32GA.js";import{a as C,o as w,r as T}from"./ThreadForms-BPowHd4M.js";import{t as E}from"./Markdown-BO_bF8WD.js";import{n as D,t as O}from"./Pane-DHXhVwfI.js";import{a as k,i as A,l as j}from"./citizen-DFaT61S1.js";import{n as M,r as N,t as P}from"./Picker-CQQ7hj8T.js";var F=n(e(),1),I=a(),L=[`UTC`,...Intl.supportedValuesOf(`timeZone`).filter(e=>e!==`UTC`)],R=50;function z(e,t){let n=new Intl.DateTimeFormat(`en-US`,{timeZone:e,timeZoneName:`longOffset`}).formatToParts(t).find(e=>e.type===`timeZoneName`)?.value??``;return n===`GMT`?`UTC`:n.replace(`GMT`,`UTC`)}function B({value:e,onChange:t,label:n,placeholder:r}){let[i,a]=(0,F.useState)(!1),[o,s]=(0,F.useState)(0),c=(0,F.useRef)(null),l=(0,F.useRef)([]),u=e.trim().toLowerCase(),d=(0,F.useMemo)(()=>(u===``?L:L.filter(e=>e.toLowerCase().includes(u))).slice(0,R),[u]),f=(0,F.useMemo)(()=>new Date,[]);(0,F.useEffect)(()=>{i&&l.current[o]?.scrollIntoView({block:`nearest`})},[i,o]),(0,F.useEffect)(()=>{if(!i)return;let e=e=>{e.target instanceof Node&&c.current?.contains(e.target)===!0||a(!1)};return window.addEventListener(`click`,e),()=>window.removeEventListener(`click`,e)},[i]);let p=e=>{t(e),a(!1)};return(0,I.jsxs)(`div`,{ref:c,className:`relative min-w-0 flex-1`,children:[(0,I.jsx)(`input`,{"aria-label":n,value:e,spellCheck:!1,autoComplete:`off`,placeholder:r,onChange:e=>{t(e.target.value),s(0),a(!0)},onClick:()=>a(!0),onKeyDown:e=>{if(e.key===`ArrowDown`||e.key===`ArrowUp`){if(e.preventDefault(),!i){a(!0);return}let t=e.key===`ArrowDown`?1:-1;s(e=>(e+t+d.length)%Math.max(d.length,1));return}if(e.key===`Enter`&&i&&d[o]!==void 0){e.preventDefault(),p(d[o]);return}if(e.key===`Tab`){a(!1);return}e.key===`Escape`&&i&&(e.preventDefault(),e.stopPropagation(),a(!1))},className:w}),i&&d.length>0&&(d.length!==1||d[0]!==e)?(0,I.jsx)(`div`,{className:`max-h-48 ${P}`,children:d.map((e,t)=>(0,I.jsxs)(`button`,{ref:e=>{l.current[t]=e},type:`button`,tabIndex:-1,"aria-current":t===o?`true`:void 0,onPointerDown:e=>e.preventDefault(),onPointerEnter:()=>s(t),onClick:()=>p(e),className:N(t===o),children:[(0,I.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-fg-secondary`,children:e}),(0,I.jsx)(`span`,{className:`shrink-0 text-[11px] text-fg-muted`,children:z(e,f)})]},e))}):null]})}function V({word:e,children:t}){return(0,I.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-center gap-1.5`,children:[(0,I.jsx)(`span`,{className:`shrink-0 text-xs text-fg-tertiary`,children:e}),t]})}function H(e,n){return t(typeof e==`string`?new Date(e):e,n)}function U({cron:e}){let t=i(),n=S(e);if(n.kind===`thread`){let e=t.data?.find(e=>e.id===n.id)?.title??n.id;return(0,I.jsxs)(g,{to:`/thread/$threadId`,params:{threadId:n.id},className:`truncate hover:text-fg-primary`,children:[`thread “`,e,`”`]})}return n.kind===`channel`?(0,I.jsxs)(g,{to:`/c/$`,params:{_splat:n.ref},className:`hover:text-fg-primary`,children:[`#`,n.ref]}):(0,I.jsxs)(`span`,{children:[`home at `,k(n.scope)]})}function W({cron:e,next:t,member:n,zone:r,now:i,focused:a}){let o=(0,F.useRef)(null);(0,F.useEffect)(()=>{a&&o.current!==null&&(o.current.open=!0,o.current.scrollIntoView({block:`nearest`}))},[a]);let{api:s}=l(),c=p(),[u,f]=(0,F.useState)(!1),[v,y]=(0,F.useState)(``),b=()=>void c.invalidateQueries({queryKey:[`crons`]}),S=m({mutationFn:t=>s.pauseCron(e.id,t),onSuccess:b}),C=m({mutationFn:()=>s.removeCron(e.id,v.trim()),onSuccess:b}),D=`at`in e.schedule?`once, ${H(e.schedule.at,r)}`:`${e.schedule.cron} · ${e.schedule.timezone??r}`,O=e.ended===void 0?e.paused===void 0?t===null?`no time to come`:t.getTime()<=i?`due, waiting for its turn`:d(t.toISOString(),i):`paused`:`ended ${d(e.ended.at,i)}`,k=x(e);return(0,I.jsx)(`li`,{className:`rounded-lg ${a?`bg-surface-2/30`:``}`,children:(0,I.jsxs)(`details`,{ref:o,className:`group`,children:[(0,I.jsxs)(`summary`,{className:`cursor-pointer list-none rounded-lg px-2 py-2 hover:bg-surface-2/40 focus-visible:ring-2 focus-visible:ring-fg-primary/30 focus-visible:outline-none`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 text-sm`,children:[n?.cli===void 0||n.cli===null?null:(0,I.jsx)(_,{cli:n.cli,size:13}),(0,I.jsx)(`span`,{className:`shrink-0 text-fg-secondary`,children:e.agent}),(0,I.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-fg-primary`,children:e.title}),(0,I.jsx)(`span`,{className:`shrink-0 text-xs ${e.paused===void 0?`text-fg-muted`:`text-amber-300`}`,title:t===null?void 0:`${H(t,r)}, ${r}`,children:O})]}),(0,I.jsxs)(`p`,{className:`mt-0.5 flex items-baseline gap-1.5 truncate text-meta`,children:[(0,I.jsx)(`span`,{children:D}),(0,I.jsx)(`span`,{"aria-hidden":`true`,children:`·`}),(0,I.jsx)(U,{cron:e}),e.lastRun===void 0?null:(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`span`,{"aria-hidden":`true`,children:`·`}),(0,I.jsxs)(`span`,{children:[`last turn `,e.lastRun.outcome,` `,d(e.lastRun.at,i)]})]}),k?(0,I.jsxs)(`span`,{className:`text-amber-300`,children:[`· `,e.failures,` failed in a row`]}):null]})]}),(0,I.jsxs)(`div`,{className:`space-y-3 px-2 pt-1 pb-3`,children:[(0,I.jsx)(`div`,{className:`rounded-lg bg-surface-2/30 px-3 py-2`,children:(0,I.jsx)(E,{text:e.note})}),(0,I.jsxs)(`p`,{className:`text-meta`,children:[`Set by `,e.createdBy,` `,d(e.createdAt,i),e.lastFiredAt===void 0?``:` · fired last ${H(e.lastFiredAt,r)}`,e.ended===void 0?``:` · ended by ${e.ended.by}: ${e.ended.reason}`]}),t===null?null:(0,I.jsxs)(`p`,{className:`text-meta`,children:[`Next `,H(t,r),` (`,r,`)`]}),e.lastRun===void 0?null:(0,I.jsx)(g,{to:`/citizen/$name`,params:{name:e.agent},search:{tab:`turns`,turn:e.lastRun.turnId},className:`text-meta underline-offset-2 hover:text-fg-primary hover:underline`,children:`Open its last turn`}),e.ended===void 0?u?(0,I.jsxs)(`form`,{"aria-label":`Remove ${e.title}`,className:`space-y-2`,onSubmit:e=>{e.preventDefault(),C.mutate()},children:[(0,I.jsx)(`input`,{value:v,"aria-label":`Why it ends`,placeholder:`Why it ends, which the cron keeps`,onChange:e=>y(e.target.value),className:w}),(0,I.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,I.jsx)(h,{onClick:()=>f(!1),children:`Cancel`}),(0,I.jsx)(h,{variant:`primary`,type:`submit`,disabled:C.isPending||v.trim()===``,children:C.isPending?`Removing…`:`Remove cron`})]}),(0,I.jsx)(T,{error:C.error})]}):(0,I.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,I.jsx)(h,{onClick:()=>S.mutate(e.paused===void 0),disabled:S.isPending,children:e.paused===void 0?`Pause`:`Resume`}),(0,I.jsx)(h,{onClick:()=>f(!0),children:`Remove…`}),(0,I.jsx)(T,{error:S.error})]}):null]})]})})}function G({zone:e,onDone:t}){let{api:n}=l(),r=p(),[i,a]=(0,F.useState)(e),o=new Intl.DateTimeFormat().resolvedOptions().timeZone,s=m({mutationFn:()=>n.setTimezone(i.trim()),onSuccess:()=>{r.invalidateQueries({queryKey:[`society`]}),r.invalidateQueries({queryKey:[`crons`]}),t()}});return(0,I.jsxs)(`form`,{"aria-label":`Time zone`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),s.mutate()},children:[(0,I.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,I.jsx)(B,{value:i,onChange:a,label:`Society time zone`}),o===i?null:(0,I.jsxs)(h,{onClick:()=>a(o),children:[`Use `,o]})]}),(0,I.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-muted`,children:`Crons that name no zone are read in it, so their times move with it, and every turn's prompt tells the time in it.`}),(0,I.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,I.jsx)(h,{onClick:t,children:`Cancel`}),(0,I.jsx)(h,{variant:`primary`,type:`submit`,disabled:s.isPending||i.trim()===``||i.trim()===e,children:s.isPending?`Saving…`:`Save`})]}),(0,I.jsx)(T,{error:s.error})]})}function K({members:e,preferred:t,zone:n,onDone:i}){let{api:a}=l(),o=p(),u=f(),d=r(),[g,_]=(0,F.useState)(e.find(e=>e.name===t)?.name??e[0]?.name??``),v=e.find(e=>e.name===g),b=v===void 0?[]:j(v),[x,S]=(0,F.useState)(b[0]??`society`),[E,D]=(0,F.useState)(``),[O,k]=(0,F.useState)(`repeats`),[N,P]=(0,F.useState)(`0 9 * * 1-5`),[L,R]=(0,F.useState)(``),[z,U]=(0,F.useState)(``),[W,G]=(0,F.useState)(``),[K,q]=(0,F.useState)(``),J=(0,F.useRef)(null);(0,F.useEffect)(()=>J.current?.focus(),[]);let Y=s(3e4),ee=(x===`society`?d.data?.channels??[]:u.data?.find(e=>e.slug===x)?.channels??[]).filter(e=>e!==`general`),X=O===`repeats`?{cron:N,...L.trim()===``?{}:{timezone:L.trim()}}:{at:z===``?``:new Date(z).toISOString()},Z=y(O===`once`&&z===``?{at:`invalid`}:X,n,new Date(Y)),Q=O===`repeats`?L.trim()===``?n:L.trim():n,$=m({mutationFn:()=>a.createCron({agent:g,title:W.trim(),note:K.trim(),project:x,...E===``?{}:{channel:E},...X}),onSuccess:()=>{o.invalidateQueries({queryKey:[`crons`]}),i()}});return(0,I.jsxs)(`form`,{"aria-label":`New cron`,className:`space-y-2 border-b border-line bg-surface-2/20 p-3`,onSubmit:e=>{e.preventDefault(),$.mutate()},children:[(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,I.jsx)(V,{word:`wakes`,children:(0,I.jsx)(M,{label:`Citizen`,choices:e.map(e=>({value:e.name,name:e.name,id:e.role,description:e.memberships.length===0?`in no project`:`in ${e.memberships.join(`, `)}`})),value:g,onChange:t=>{let n=e.find(e=>e.name===t);_(t),S(n===void 0?c:j(n)[0]??`society`),D(``)}})}),(0,I.jsx)(V,{word:`at`,children:(0,I.jsx)(M,{label:`Where`,choices:A(b),value:x,onChange:e=>{S(e),D(``)}})}),(0,I.jsx)(V,{word:`in`,children:(0,I.jsx)(M,{label:`Conversation`,choices:[{value:``,name:`its home`,id:null,description:`general, and work tied to no other channel`},...ee.map(e=>({value:e,name:`#${e}`,id:null,description:`a workstream's own conversation`}))],value:E,onChange:D})})]}),(0,I.jsx)(`input`,{ref:J,value:W,maxLength:120,"aria-label":`Title`,placeholder:`Title, such as Morning report`,onChange:e=>G(e.target.value),className:w}),(0,I.jsx)(`textarea`,{value:K,rows:3,"aria-label":`Note`,placeholder:`What to do when it fires; the citizen reads this in every turn it starts.`,onChange:e=>q(e.target.value),className:C}),(0,I.jsxs)(`fieldset`,{className:`flex gap-1`,children:[(0,I.jsx)(`legend`,{className:`sr-only`,children:`How often`}),[`repeats`,`once`].map(e=>(0,I.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 ${O===e?`bg-surface-2 text-fg-primary`:`text-fg-tertiary hover:bg-surface-2/60 hover:text-fg-primary`}`,children:[(0,I.jsx)(`input`,{type:`radio`,name:`kind`,value:e,checked:O===e,onChange:()=>k(e),className:`sr-only`}),e===`repeats`?`Repeats`:`Once`]},e))]}),O===`repeats`?(0,I.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,I.jsx)(`div`,{className:`w-44 shrink-0`,children:(0,I.jsx)(`input`,{value:N,spellCheck:!1,"aria-label":`Cron expression`,placeholder:`minute hour day month weekday`,onChange:e=>P(e.target.value),className:w})}),(0,I.jsx)(B,{value:L,onChange:R,label:`Its time zone`,placeholder:`${n}, the society's`})]}):(0,I.jsx)(`input`,{type:`datetime-local`,value:z,"aria-label":`When, in this browser's time`,onChange:e=>U(e.target.value),className:w}),(0,I.jsxs)(`p`,{"aria-live":`polite`,className:`text-xs leading-relaxed text-fg-muted`,children:[`error`in Z?(0,I.jsx)(`span`,{className:`text-amber-300`,children:Z.error}):(0,I.jsxs)(I.Fragment,{children:[Z.times.length===1?`Fires `:`Fires next `,Z.times.map(e=>H(e,Q)).join(`, `),` (`,Q,`).`]}),` `,`Each fire is a turn for `,g===``?`the citizen`:g,`, which costs money.`]}),(0,I.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[(0,I.jsx)(h,{onClick:i,children:`Cancel`}),(0,I.jsx)(h,{variant:`primary`,type:`submit`,disabled:$.isPending||g===``||W.trim()===``||K.trim()===``||`error`in Z,children:$.isPending?`Setting…`:`Set cron`})]}),(0,I.jsx)(T,{error:$.error})]})}function q(){let{agent:e,cron:t}=b({from:`/crons`}),n=u(),i=o(),a=r(),c=s(3e4),[l,d]=(0,F.useState)(null),f=a.data?.timezone??`UTC`,p=(n.data??[]).filter(t=>e===void 0||t.agent===e),m=v(p,f),_=p.filter(x).length,y=(i.data??[]).filter(e=>e.status===`active`&&e.cli!==null),S=e=>i.data?.find(t=>t.name===e);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(O,{title:e===void 0?`Crons`:`Crons of ${e}`,subtitle:[`${m.active.length} running`,...m.paused.length===0?[]:[`${m.paused.length} paused`],..._===0?[]:[`${_} failing`],`times in ${f}`].join(` · `),trailing:l===null?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(h,{onClick:()=>d(`zone`),children:`Time zone…`}),(0,I.jsx)(h,{onClick:()=>d(`new`),disabled:y.length===0,children:`New cron…`})]}):null}),l===`new`?(0,I.jsx)(K,{members:y,preferred:e,zone:f,onDone:()=>d(null)}):l===`zone`?(0,I.jsx)(G,{zone:f,onDone:()=>d(null)}):null,(0,I.jsxs)(`div`,{className:`flex-1 overflow-y-auto px-2 py-2`,children:[e===void 0?null:(0,I.jsx)(g,{to:`/crons`,className:`block px-2 pb-2 text-meta hover:text-fg-primary`,children:`Show every citizen's crons`}),n.error!==null&&n.data===void 0?(0,I.jsxs)(D,{children:[`The board server did not list its crons (`,n.error.message,`); one older than this interface has none.`]}):n.data===void 0?(0,I.jsx)(D,{children:`Reading the crons…`}):m.active.length+m.paused.length+m.ended.length===0?(0,I.jsx)(`p`,{className:`px-2 py-2 text-meta`,children:`No crons yet. A citizen sets one with create_cron when it needs to come back to something later; you can set one for any citizen here.`}):null,m.active.length===0?null:(0,I.jsx)(`ul`,{"aria-label":`Running`,className:`space-y-0.5`,children:m.active.map(({cron:e,next:n})=>(0,I.jsx)(W,{cron:e,next:n,member:S(e.agent),zone:f,now:c,focused:e.id===t},e.id))}),m.paused.length===0?null:(0,I.jsxs)(`section`,{"aria-label":`Paused`,className:`mt-3`,children:[(0,I.jsx)(`h3`,{className:`px-2 pb-1 text-section`,children:`Paused`}),(0,I.jsx)(`ul`,{className:`space-y-0.5`,children:m.paused.map(e=>(0,I.jsx)(W,{cron:e,next:null,member:S(e.agent),zone:f,now:c,focused:e.id===t},e.id))})]}),m.ended.length===0?null:(0,I.jsxs)(`details`,{className:`mt-3`,open:m.ended.some(e=>e.id===t),children:[(0,I.jsxs)(`summary`,{className:`cursor-pointer px-2 pb-1 text-section`,children:[`Ended (`,m.ended.length,`)`]}),(0,I.jsx)(`ul`,{"aria-label":`Ended`,className:`space-y-0.5`,children:m.ended.map(e=>(0,I.jsx)(W,{cron:e,next:null,member:S(e.agent),zone:f,now:c,focused:e.id===t},e.id))})]})]})]})}export{q as CronsView};