@kubitnodes/stellaris 0.3.22 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/cli/index.js +556 -413
- package/dist/server/index.js +666 -473
- package/package.json +1 -1
- package/web/dist/assets/BackLink-DGYs80bb.js +1 -0
- package/web/dist/assets/{Button-Yoe21NQ2.js → Button-f4jgBZY1.js} +1 -1
- package/web/dist/assets/{ChannelForms-55otlg-m.js → ChannelForms-q9zdj4p2.js} +1 -1
- package/web/dist/assets/{ChannelView-DJvLzg0N.js → ChannelView-CGs_aWL3.js} +2 -2
- package/web/dist/assets/{CitizenView-m1K2aTvK.js → CitizenView-gcIo_sKt.js} +2 -2
- package/web/dist/assets/CitizensView-DZ7S8vnJ.js +1 -0
- package/web/dist/assets/{CliIcon-DbMYJdlU.js → CliIcon-CLHaA65A.js} +1 -1
- package/web/dist/assets/{CronsView-B4kXk5Ld.js → CronsView-1wns6Uwv.js} +1 -1
- package/web/dist/assets/{KnowledgeView-aSGxDDKy.js → KnowledgeView-Cxfi2-Pt.js} +1 -1
- package/web/dist/assets/Markdown-BhtIFcWc.js +30 -0
- package/web/dist/assets/MessageItem-Bk9eBp1U.js +1 -0
- package/web/dist/assets/MetricsView-CTEH6rJn.js +1 -0
- package/web/dist/assets/NeedsYouView-2VNqH2Sb.js +1 -0
- package/web/dist/assets/{Overview-BveU1yJj.js → Overview-CS9HCSmm.js} +1 -1
- package/web/dist/assets/{Pane-CLjdfBMM.js → Pane-CJYRVkwh.js} +1 -1
- package/web/dist/assets/{Picker-CXOe5Xdu.js → Picker-DoxCN6C7.js} +1 -1
- package/web/dist/assets/{ProjectView-oa4Z46ED.js → ProjectView-CJ3r4UdN.js} +1 -1
- package/web/dist/assets/ProposalView-DLn9dNPp.js +2 -0
- package/web/dist/assets/{ProposalsView-BZHivSEm.js → ProposalsView-B-cOxTsQ.js} +1 -1
- package/web/dist/assets/{Quota-BC7dpnwd.js → Quota-Bo7UdWTV.js} +1 -1
- package/web/dist/assets/{RunnersView-BrJF-aLU.js → RunnersView-DlQruhwp.js} +1 -1
- package/web/dist/assets/{SocietyView-C1yosPuf.js → SocietyView-Bl4ErnV8.js} +1 -1
- package/web/dist/assets/{StickyList-7tAlUDCN.js → StickyList-MVP34ytV.js} +1 -1
- package/web/dist/assets/{SubjectThread-CCq6ZAnR.js → SubjectThread-BFFnHxIF.js} +1 -1
- package/web/dist/assets/{TaskFileView-BEXQJQQ6.js → TaskFileView-GZ0eQFUb.js} +2 -2
- package/web/dist/assets/{TaskView-Cfhb7NuO.js → TaskView-DppFelLW.js} +2 -2
- package/web/dist/assets/{TasksView-3XljXcoi.js → TasksView-DDNXzeG4.js} +1 -1
- package/web/dist/assets/{ThreadForms-D2y5dXSC.js → ThreadForms-C846TvtS.js} +1 -1
- package/web/dist/assets/{ThreadItem-DeIhhmyu.js → ThreadItem-C8cou6wD.js} +1 -1
- package/web/dist/assets/{ThreadView-CbUnt9WL.js → ThreadView-DvSGDYoD.js} +1 -1
- package/web/dist/assets/{citizen--bqux6i_.js → citizen-B2Dlbcpe.js} +1 -1
- package/web/dist/assets/{compose-DNc3_c5x.js → compose-BmqQmcZH.js} +1 -1
- package/web/dist/assets/{format-B6fjC0_a.js → format-DT52SbbR.js} +1 -1
- package/web/dist/assets/{governance-RBQ4Lam0.js → governance-Cr5OlQnw.js} +1 -1
- package/web/dist/assets/index-BTVy_xFF.js +23 -0
- package/web/dist/assets/index-DzV6CCnG.css +2 -0
- package/web/dist/assets/{mentions-B2Qchd_6.js → mentions-D5hNgtg6.js} +1 -1
- package/web/dist/assets/{tasks-DCUj5w_d.js → tasks-R3YgpYTe.js} +1 -1
- package/web/dist/assets/useMatch-pEF6RJ6Q.js +1 -0
- package/web/dist/index.html +9 -9
- package/web/dist/assets/BackLink-CD-iuy-h.js +0 -1
- package/web/dist/assets/CitizensView-BeTgmrKE.js +0 -1
- package/web/dist/assets/Markdown-c9bCCLHg.js +0 -30
- package/web/dist/assets/MessageItem-DKJKMqs-.js +0 -1
- package/web/dist/assets/MetricsView-D2TTry5O.js +0 -1
- package/web/dist/assets/NeedsYouView-C3celRei.js +0 -1
- package/web/dist/assets/ProposalView-B4T-EoX9.js +0 -2
- package/web/dist/assets/index-CyCty7a2.js +0 -23
- package/web/dist/assets/index-GRqxKN35.css +0 -2
- package/web/dist/assets/useMatch-CfbBQirn.js +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Command } from "commander";
|
|
|
9
9
|
import { chmod as chmod2, cp, mkdir as mkdir4, readdir as readdir3, readFile as readFile4, rename as rename3, rm as rm2, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
10
10
|
import path6 from "node:path";
|
|
11
11
|
import { decodeTime, monotonicFactory } from "ulid";
|
|
12
|
-
import { z as
|
|
12
|
+
import { z as z16 } from "zod";
|
|
13
13
|
|
|
14
14
|
// packages/shared/dist/ids.js
|
|
15
15
|
import { z } from "zod";
|
|
@@ -64,7 +64,8 @@ var VERB_NAMES = [
|
|
|
64
64
|
"create_cron",
|
|
65
65
|
"update_cron",
|
|
66
66
|
"remove_cron",
|
|
67
|
-
"remove_skill"
|
|
67
|
+
"remove_skill",
|
|
68
|
+
"upload_image"
|
|
68
69
|
];
|
|
69
70
|
var VerbNameSchema = z2.enum(VERB_NAMES);
|
|
70
71
|
var CharterTriggerSchema = z2.enum(["user_post", "ops_event", "heartbeat"]);
|
|
@@ -93,6 +94,7 @@ var USER_ROLE = "user";
|
|
|
93
94
|
var USER_NAME = "user";
|
|
94
95
|
var MEMBER_VERBS = [
|
|
95
96
|
"post_message",
|
|
97
|
+
"upload_image",
|
|
96
98
|
"read_inbox",
|
|
97
99
|
"search",
|
|
98
100
|
"open_thread",
|
|
@@ -985,130 +987,169 @@ var DecisionSchema = z5.object({
|
|
|
985
987
|
});
|
|
986
988
|
|
|
987
989
|
// packages/shared/dist/verbs.js
|
|
990
|
+
import { z as z7 } from "zod";
|
|
991
|
+
|
|
992
|
+
// packages/shared/dist/images.js
|
|
988
993
|
import { z as z6 } from "zod";
|
|
989
|
-
var
|
|
990
|
-
var
|
|
991
|
-
|
|
994
|
+
var IMAGE_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
995
|
+
var ImageTypeSchema = z6.enum(["png", "jpeg", "gif", "webp"]);
|
|
996
|
+
function startsWith(bytes, prefix, at = 0) {
|
|
997
|
+
for (let index = 0; index < prefix.length; index += 1) {
|
|
998
|
+
if (bytes[at + index] !== prefix[index]) {
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
return true;
|
|
1003
|
+
}
|
|
1004
|
+
var ascii = (text) => new TextEncoder().encode(text);
|
|
1005
|
+
function imageTypeOf(bytes) {
|
|
1006
|
+
if (startsWith(bytes, [137, 80, 78, 71, 13, 10, 26, 10])) {
|
|
1007
|
+
return "png";
|
|
1008
|
+
}
|
|
1009
|
+
if (startsWith(bytes, [255, 216, 255])) {
|
|
1010
|
+
return "jpeg";
|
|
1011
|
+
}
|
|
1012
|
+
if (startsWith(bytes, ascii("GIF87a")) || startsWith(bytes, ascii("GIF89a"))) {
|
|
1013
|
+
return "gif";
|
|
1014
|
+
}
|
|
1015
|
+
if (startsWith(bytes, ascii("RIFF")) && startsWith(bytes, ascii("WEBP"), 8)) {
|
|
1016
|
+
return "webp";
|
|
1017
|
+
}
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
var ImagePathSchema = z6.string().min(1).max(4096).refine((value) => !value.includes("\0"), { message: "a path with no NUL character" });
|
|
1021
|
+
var IMAGE_SCHEME = "image:";
|
|
1022
|
+
var UploadedImageSchema = z6.object({
|
|
1023
|
+
id: UlidSchema,
|
|
1024
|
+
type: ImageTypeSchema,
|
|
1025
|
+
size: z6.number().int().positive(),
|
|
1026
|
+
markdown: z6.string()
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
// packages/shared/dist/verbs.js
|
|
1030
|
+
var MomentSchema = z7.iso.datetime({ offset: true });
|
|
1031
|
+
var CronTitleSchema = z7.string().trim().min(1).max(120);
|
|
1032
|
+
var CronNoteSchema = z7.string().trim().min(1).max(4e3);
|
|
992
1033
|
var VerbInputs = {
|
|
993
|
-
post_message:
|
|
1034
|
+
post_message: z7.object({
|
|
994
1035
|
/** Required outside a thread; in one it may be left out, and must otherwise be the thread's. */
|
|
995
1036
|
channel: ChannelRefSchema.optional(),
|
|
996
|
-
body:
|
|
1037
|
+
body: z7.string().min(1),
|
|
997
1038
|
thread_id: UlidSchema.optional()
|
|
998
1039
|
}),
|
|
999
|
-
read_inbox:
|
|
1040
|
+
read_inbox: z7.object({
|
|
1000
1041
|
since_cursor: UlidSchema.nullable().optional(),
|
|
1001
|
-
limit:
|
|
1002
|
-
advance:
|
|
1042
|
+
limit: z7.number().int().positive().max(200).default(50),
|
|
1043
|
+
advance: z7.boolean().default(true)
|
|
1003
1044
|
}),
|
|
1004
|
-
search:
|
|
1005
|
-
query:
|
|
1045
|
+
search: z7.object({
|
|
1046
|
+
query: z7.string().min(1),
|
|
1006
1047
|
project: NameSchema.optional(),
|
|
1007
1048
|
channel: ChannelRefSchema.optional(),
|
|
1008
|
-
limit:
|
|
1049
|
+
limit: z7.number().int().positive().max(100).default(20)
|
|
1009
1050
|
}),
|
|
1010
1051
|
/** On a task or a proposal, whose id the thread takes, or on a channel with a title. */
|
|
1011
|
-
open_thread:
|
|
1052
|
+
open_thread: z7.object({
|
|
1012
1053
|
task_id: UlidSchema.optional(),
|
|
1013
1054
|
proposal_id: UlidSchema.optional(),
|
|
1014
1055
|
channel: ChannelRefSchema.optional(),
|
|
1015
|
-
title:
|
|
1056
|
+
title: z7.string().min(1).max(200).optional()
|
|
1016
1057
|
}),
|
|
1017
|
-
close_thread:
|
|
1018
|
-
create_task:
|
|
1058
|
+
close_thread: z7.object({ thread_id: UlidSchema, summary: z7.string().min(1) }),
|
|
1059
|
+
create_task: z7.object({
|
|
1019
1060
|
project: NameSchema,
|
|
1020
|
-
title:
|
|
1021
|
-
body:
|
|
1061
|
+
title: z7.string().min(1).max(200),
|
|
1062
|
+
body: z7.string().default(""),
|
|
1022
1063
|
parent_id: UlidSchema.optional(),
|
|
1023
|
-
required_capabilities:
|
|
1064
|
+
required_capabilities: z7.array(z7.string()).default([]),
|
|
1024
1065
|
/** The plan; without it the task gets one stage, work, that anyone in the project may take. */
|
|
1025
|
-
stages:
|
|
1066
|
+
stages: z7.array(PlanStageSchema).min(1).optional(),
|
|
1026
1067
|
/** A channel of the project the task belongs to, such as a release's; its thread opens there. */
|
|
1027
1068
|
channel: NameSchema.default("general")
|
|
1028
1069
|
}),
|
|
1029
|
-
claim_task:
|
|
1030
|
-
release_task:
|
|
1031
|
-
update_task:
|
|
1070
|
+
claim_task: z7.object({ task_id: UlidSchema }),
|
|
1071
|
+
release_task: z7.object({ task_id: UlidSchema }),
|
|
1072
|
+
update_task: z7.object({
|
|
1032
1073
|
task_id: UlidSchema,
|
|
1033
1074
|
/** Move the task back to this earlier stage. */
|
|
1034
1075
|
stage: StageIdSchema.optional(),
|
|
1035
|
-
status:
|
|
1076
|
+
status: z7.enum(["abandoned"]).optional(),
|
|
1036
1077
|
/** Posted to the task's thread as the caller, marked with the step when the task moved. */
|
|
1037
|
-
note:
|
|
1038
|
-
blocked_by:
|
|
1078
|
+
note: z7.string().min(1).optional(),
|
|
1079
|
+
blocked_by: z7.array(UlidSchema).optional(),
|
|
1039
1080
|
/**
|
|
1040
1081
|
* The pull request a `ghpr` task lands through, on its project's repository, with the merge
|
|
1041
1082
|
* commit's subject and body; null unlinks it.
|
|
1042
1083
|
*/
|
|
1043
|
-
pull_request:
|
|
1084
|
+
pull_request: z7.object({
|
|
1044
1085
|
url: PullRequestUrlSchema,
|
|
1045
1086
|
merge_subject: MergeSubjectSchema.optional(),
|
|
1046
|
-
merge_body:
|
|
1087
|
+
merge_body: z7.string().max(2e4).optional()
|
|
1047
1088
|
}).nullable().optional()
|
|
1048
1089
|
}),
|
|
1049
|
-
get_task:
|
|
1050
|
-
subscribe:
|
|
1051
|
-
unsubscribe:
|
|
1052
|
-
propose:
|
|
1090
|
+
get_task: z7.object({ task_id: UlidSchema }),
|
|
1091
|
+
subscribe: z7.object({ channel: ChannelRefSchema }),
|
|
1092
|
+
unsubscribe: z7.object({ channel: ChannelRefSchema }),
|
|
1093
|
+
propose: z7.object({
|
|
1053
1094
|
kind: ProposalKindSchema,
|
|
1054
|
-
charter:
|
|
1055
|
-
rationale:
|
|
1095
|
+
charter: z7.record(z7.string(), z7.unknown()),
|
|
1096
|
+
rationale: z7.string().default("")
|
|
1056
1097
|
}),
|
|
1057
|
-
approve:
|
|
1058
|
-
reject:
|
|
1059
|
-
create_project:
|
|
1098
|
+
approve: z7.object({ proposal_id: UlidSchema, reason: z7.string().optional() }),
|
|
1099
|
+
reject: z7.object({ proposal_id: UlidSchema, reason: z7.string().min(1) }),
|
|
1100
|
+
create_project: z7.object({
|
|
1060
1101
|
slug: NameSchema,
|
|
1061
|
-
name:
|
|
1062
|
-
repo:
|
|
1102
|
+
name: z7.string().min(1).optional(),
|
|
1103
|
+
repo: z7.string().min(1).nullable().default(null),
|
|
1063
1104
|
default_branch: DefaultBranchSchema.default("main"),
|
|
1064
1105
|
on_done: CompletionEffectSchema.optional()
|
|
1065
1106
|
}),
|
|
1066
|
-
join_project:
|
|
1067
|
-
leave_project:
|
|
1068
|
-
write_knowledge:
|
|
1107
|
+
join_project: z7.object({ project: NameSchema, agent: NameSchema.optional() }),
|
|
1108
|
+
leave_project: z7.object({ project: NameSchema, agent: NameSchema.optional() }),
|
|
1109
|
+
write_knowledge: z7.object({
|
|
1069
1110
|
/** A project you belong to, or null for society knowledge, which the steward and the user curate. */
|
|
1070
1111
|
project: NameSchema.nullable().default(null),
|
|
1071
1112
|
topic: NameSchema,
|
|
1072
|
-
body:
|
|
1113
|
+
body: z7.string().min(1),
|
|
1073
1114
|
/** The `revision` in the frontmatter of the topic you read, 0 when it names none or for a new topic. */
|
|
1074
|
-
revision:
|
|
1115
|
+
revision: z7.number().int().min(0)
|
|
1075
1116
|
}),
|
|
1076
|
-
remove_knowledge:
|
|
1117
|
+
remove_knowledge: z7.object({
|
|
1077
1118
|
/** As for write_knowledge: a project you belong to, or null for society knowledge. */
|
|
1078
1119
|
project: NameSchema.nullable().default(null),
|
|
1079
1120
|
topic: NameSchema
|
|
1080
1121
|
}),
|
|
1081
|
-
plan_task:
|
|
1122
|
+
plan_task: z7.object({
|
|
1082
1123
|
task_id: UlidSchema,
|
|
1083
|
-
stages:
|
|
1124
|
+
stages: z7.array(PlanEditStageSchema),
|
|
1084
1125
|
on_done: CompletionEffectSchema.optional()
|
|
1085
1126
|
}),
|
|
1086
1127
|
/** The note is posted to the task's thread as the caller, marked with the step. */
|
|
1087
|
-
advance_task:
|
|
1088
|
-
configure_project:
|
|
1128
|
+
advance_task: z7.object({ task_id: UlidSchema, note: z7.string().min(1).optional() }),
|
|
1129
|
+
configure_project: z7.object({
|
|
1089
1130
|
project: NameSchema,
|
|
1090
1131
|
on_done: CompletionEffectSchema.optional(),
|
|
1091
1132
|
/** A new display name; the slug, which everything refers to the project by, never changes. */
|
|
1092
|
-
name:
|
|
1133
|
+
name: z7.string().trim().min(1).max(120).optional(),
|
|
1093
1134
|
/** The branch tasks start from and land on from now; tasks in play keep their branches. */
|
|
1094
1135
|
default_branch: DefaultBranchSchema.optional()
|
|
1095
1136
|
}),
|
|
1096
|
-
archive_project:
|
|
1097
|
-
create_channel:
|
|
1137
|
+
archive_project: z7.object({ project: NameSchema, reason: z7.string().min(1) }),
|
|
1138
|
+
create_channel: z7.object({
|
|
1098
1139
|
/** A project, or null for a channel of the society. */
|
|
1099
1140
|
project: NameSchema.nullable().default(null),
|
|
1100
1141
|
name: NameSchema,
|
|
1101
|
-
purpose:
|
|
1142
|
+
purpose: z7.string().min(1)
|
|
1102
1143
|
}),
|
|
1103
|
-
archive_channel:
|
|
1104
|
-
update_dashboard:
|
|
1144
|
+
archive_channel: z7.object({ channel: ChannelRefSchema, reason: z7.string().min(1) }),
|
|
1145
|
+
update_dashboard: z7.object({
|
|
1105
1146
|
project: NameSchema,
|
|
1106
1147
|
/** The whole dashboard as markdown; the board keeps its frontmatter. */
|
|
1107
|
-
body:
|
|
1148
|
+
body: z7.string().min(1),
|
|
1108
1149
|
/** The `revision` in the frontmatter of the dashboard you read, 0 when it names none. */
|
|
1109
|
-
revision:
|
|
1150
|
+
revision: z7.number().int().min(0)
|
|
1110
1151
|
}),
|
|
1111
|
-
create_cron:
|
|
1152
|
+
create_cron: z7.object({
|
|
1112
1153
|
title: CronTitleSchema,
|
|
1113
1154
|
/** What to do when it fires; quoted in the prompt of every turn it starts. */
|
|
1114
1155
|
note: CronNoteSchema,
|
|
@@ -1127,10 +1168,10 @@ var VerbInputs = {
|
|
|
1127
1168
|
/** An open channel of that place other than general, whose conversation it fires in. */
|
|
1128
1169
|
channel: NameSchema.optional()
|
|
1129
1170
|
}),
|
|
1130
|
-
update_cron:
|
|
1171
|
+
update_cron: z7.object({
|
|
1131
1172
|
cron_id: UlidSchema,
|
|
1132
1173
|
/** Pause it, or resume it, which starts its schedule afresh from now. */
|
|
1133
|
-
paused:
|
|
1174
|
+
paused: z7.boolean().optional(),
|
|
1134
1175
|
title: CronTitleSchema.optional(),
|
|
1135
1176
|
note: CronNoteSchema.optional(),
|
|
1136
1177
|
/** A new expression, or `at` for one time; either starts the schedule afresh. */
|
|
@@ -1139,12 +1180,16 @@ var VerbInputs = {
|
|
|
1139
1180
|
timezone: TimeZoneSchema.nullable().optional(),
|
|
1140
1181
|
at: MomentSchema.optional()
|
|
1141
1182
|
}),
|
|
1142
|
-
remove_cron:
|
|
1143
|
-
remove_skill:
|
|
1183
|
+
remove_cron: z7.object({ cron_id: UlidSchema, reason: z7.string().trim().min(1) }),
|
|
1184
|
+
remove_skill: z7.object({ name: NameSchema, reason: z7.string().trim().min(1) }),
|
|
1185
|
+
upload_image: z7.object({
|
|
1186
|
+
/** The image file on the machine your turn runs on: absolute, or relative to your working directory. */
|
|
1187
|
+
path: ImagePathSchema
|
|
1188
|
+
})
|
|
1144
1189
|
};
|
|
1145
1190
|
|
|
1146
1191
|
// packages/shared/dist/events.js
|
|
1147
|
-
import { z as
|
|
1192
|
+
import { z as z8 } from "zod";
|
|
1148
1193
|
var BOARD_EVENT_TYPES = [
|
|
1149
1194
|
"society.initialized",
|
|
1150
1195
|
"project.added",
|
|
@@ -1208,21 +1253,22 @@ var BOARD_EVENT_TYPES = [
|
|
|
1208
1253
|
"cron.updated",
|
|
1209
1254
|
"cron.fired",
|
|
1210
1255
|
"cron.skipped",
|
|
1211
|
-
"cron.ended"
|
|
1256
|
+
"cron.ended",
|
|
1257
|
+
"image.uploaded"
|
|
1212
1258
|
];
|
|
1213
|
-
var BoardEventTypeSchema =
|
|
1214
|
-
var BoardEventSchema =
|
|
1259
|
+
var BoardEventTypeSchema = z8.enum(BOARD_EVENT_TYPES);
|
|
1260
|
+
var BoardEventSchema = z8.object({
|
|
1215
1261
|
id: UlidSchema,
|
|
1216
1262
|
ts: IsoDateTimeSchema,
|
|
1217
1263
|
type: BoardEventTypeSchema,
|
|
1218
1264
|
actor: NameSchema,
|
|
1219
|
-
payload:
|
|
1265
|
+
payload: z8.record(z8.string(), z8.unknown())
|
|
1220
1266
|
});
|
|
1221
|
-
var UsageSchema =
|
|
1222
|
-
inputTokens:
|
|
1223
|
-
outputTokens:
|
|
1224
|
-
cacheReadTokens:
|
|
1225
|
-
cacheWriteTokens:
|
|
1267
|
+
var UsageSchema = z8.object({
|
|
1268
|
+
inputTokens: z8.number().int().nonnegative(),
|
|
1269
|
+
outputTokens: z8.number().int().nonnegative(),
|
|
1270
|
+
cacheReadTokens: z8.number().int().nonnegative().default(0),
|
|
1271
|
+
cacheWriteTokens: z8.number().int().nonnegative().default(0)
|
|
1226
1272
|
});
|
|
1227
1273
|
function addUsage(a, b) {
|
|
1228
1274
|
return {
|
|
@@ -1232,14 +1278,14 @@ function addUsage(a, b) {
|
|
|
1232
1278
|
cacheWriteTokens: a.cacheWriteTokens + b.cacheWriteTokens
|
|
1233
1279
|
};
|
|
1234
1280
|
}
|
|
1235
|
-
var TurnStatusSchema =
|
|
1236
|
-
summary:
|
|
1237
|
-
claimsHeld:
|
|
1238
|
-
blockedOn:
|
|
1239
|
-
needsUserDecision:
|
|
1240
|
-
memoryUpdated:
|
|
1241
|
-
});
|
|
1242
|
-
var TurnExitReasonSchema =
|
|
1281
|
+
var TurnStatusSchema = z8.object({
|
|
1282
|
+
summary: z8.string().min(1),
|
|
1283
|
+
claimsHeld: z8.array(UlidSchema).default([]),
|
|
1284
|
+
blockedOn: z8.array(z8.string()).default([]),
|
|
1285
|
+
needsUserDecision: z8.boolean().default(false),
|
|
1286
|
+
memoryUpdated: z8.boolean().default(false)
|
|
1287
|
+
});
|
|
1288
|
+
var TurnExitReasonSchema = z8.enum([
|
|
1243
1289
|
"completed",
|
|
1244
1290
|
"timeout",
|
|
1245
1291
|
"error",
|
|
@@ -1247,50 +1293,50 @@ var TurnExitReasonSchema = z7.enum([
|
|
|
1247
1293
|
"blocked",
|
|
1248
1294
|
"stopped"
|
|
1249
1295
|
]);
|
|
1250
|
-
var AgentEventSchema =
|
|
1251
|
-
|
|
1252
|
-
type:
|
|
1296
|
+
var AgentEventSchema = z8.discriminatedUnion("type", [
|
|
1297
|
+
z8.object({
|
|
1298
|
+
type: z8.literal("turn_started"),
|
|
1253
1299
|
agent: NameSchema,
|
|
1254
|
-
session:
|
|
1300
|
+
session: z8.string(),
|
|
1255
1301
|
runner: NameSchema,
|
|
1256
1302
|
/** The model the CLI reports running, when it reports one. */
|
|
1257
|
-
model:
|
|
1303
|
+
model: z8.string().optional()
|
|
1258
1304
|
}),
|
|
1259
1305
|
/**
|
|
1260
1306
|
* The CLI took a steer into the running turn. Adapters name the steer; the server adds the
|
|
1261
1307
|
* messages it delivered and the text the CLI was given.
|
|
1262
1308
|
*/
|
|
1263
|
-
|
|
1264
|
-
type:
|
|
1265
|
-
steer:
|
|
1266
|
-
messages:
|
|
1267
|
-
text:
|
|
1309
|
+
z8.object({
|
|
1310
|
+
type: z8.literal("steered"),
|
|
1311
|
+
steer: z8.string().min(1),
|
|
1312
|
+
messages: z8.array(UlidSchema).optional(),
|
|
1313
|
+
text: z8.string().optional()
|
|
1268
1314
|
}),
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
type:
|
|
1273
|
-
name:
|
|
1274
|
-
ok:
|
|
1315
|
+
z8.object({ type: z8.literal("text"), delta: z8.string() }),
|
|
1316
|
+
z8.object({ type: z8.literal("tool_call"), name: z8.string(), input: z8.unknown() }),
|
|
1317
|
+
z8.object({
|
|
1318
|
+
type: z8.literal("tool_result"),
|
|
1319
|
+
name: z8.string(),
|
|
1320
|
+
ok: z8.boolean(),
|
|
1275
1321
|
/** What the tool returned, cut to `OUTPUT_LIMIT` characters by `capOutput`. */
|
|
1276
|
-
output:
|
|
1322
|
+
output: z8.string().optional()
|
|
1277
1323
|
}),
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
type:
|
|
1324
|
+
z8.object({ type: z8.literal("approval_requested"), kind: z8.string(), detail: z8.unknown() }),
|
|
1325
|
+
z8.object({
|
|
1326
|
+
type: z8.literal("turn_completed"),
|
|
1281
1327
|
usage: UsageSchema,
|
|
1282
|
-
costUsd:
|
|
1328
|
+
costUsd: z8.number().nonnegative(),
|
|
1283
1329
|
status: TurnStatusSchema.nullable(),
|
|
1284
1330
|
exitReason: TurnExitReasonSchema
|
|
1285
1331
|
}),
|
|
1286
|
-
|
|
1332
|
+
z8.object({ type: z8.literal("error"), message: z8.string() })
|
|
1287
1333
|
]);
|
|
1288
|
-
var TranscriptEntrySchema =
|
|
1334
|
+
var TranscriptEntrySchema = z8.object({
|
|
1289
1335
|
ts: IsoDateTimeSchema,
|
|
1290
1336
|
event: AgentEventSchema
|
|
1291
1337
|
});
|
|
1292
|
-
var LiveTurnEventSchema =
|
|
1293
|
-
seq:
|
|
1338
|
+
var LiveTurnEventSchema = z8.object({
|
|
1339
|
+
seq: z8.number().int().positive(),
|
|
1294
1340
|
ts: IsoDateTimeSchema,
|
|
1295
1341
|
agent: NameSchema,
|
|
1296
1342
|
project: NameSchema,
|
|
@@ -1302,105 +1348,107 @@ var LiveTurnEventSchema = z7.object({
|
|
|
1302
1348
|
});
|
|
1303
1349
|
|
|
1304
1350
|
// packages/shared/dist/turns.js
|
|
1305
|
-
import { z as
|
|
1351
|
+
import { z as z10 } from "zod";
|
|
1306
1352
|
|
|
1307
1353
|
// packages/shared/dist/runner.js
|
|
1308
|
-
import { z as
|
|
1354
|
+
import { z as z9 } from "zod";
|
|
1309
1355
|
var HOME_SCRATCH = "scratch";
|
|
1310
1356
|
var HOME_FILE_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
1311
|
-
var RunnerHelloSchema =
|
|
1312
|
-
protocol:
|
|
1313
|
-
version:
|
|
1357
|
+
var RunnerHelloSchema = z9.object({
|
|
1358
|
+
protocol: z9.number().int().positive(),
|
|
1359
|
+
version: z9.string().min(1),
|
|
1314
1360
|
os: RunnerOsSchema,
|
|
1315
|
-
clis:
|
|
1361
|
+
clis: z9.array(CliKindSchema),
|
|
1316
1362
|
/** The CLIs whose adapter can keep a session warm between turns. */
|
|
1317
|
-
residentClis:
|
|
1363
|
+
residentClis: z9.array(CliKindSchema).default([]),
|
|
1318
1364
|
/** The CLIs whose adapter can take input into a running turn; the server steers only these. */
|
|
1319
|
-
steerableClis:
|
|
1365
|
+
steerableClis: z9.array(CliKindSchema).default([]),
|
|
1320
1366
|
/** The CLIs whose adapter can stop a running turn; the server stops only these. */
|
|
1321
|
-
stoppableClis:
|
|
1367
|
+
stoppableClis: z9.array(CliKindSchema).default([]),
|
|
1322
1368
|
/** Whether the runner answers file reads on its projects' branches; one from before never does. */
|
|
1323
|
-
branchReads:
|
|
1369
|
+
branchReads: z9.boolean().default(false),
|
|
1324
1370
|
/** Whether the runner lists what a branch changed; one from before never does. */
|
|
1325
|
-
branchChanges:
|
|
1371
|
+
branchChanges: z9.boolean().default(false),
|
|
1326
1372
|
/** Whether the runner answers a read of a CLI's quota; one from before never does. */
|
|
1327
|
-
quotaReads:
|
|
1328
|
-
|
|
1373
|
+
quotaReads: z9.boolean().default(false),
|
|
1374
|
+
/** Whether the runner reads an image a turn running there uploads; one from before never does. */
|
|
1375
|
+
imageReads: z9.boolean().default(false),
|
|
1376
|
+
capabilities: z9.array(z9.string()).default([]),
|
|
1329
1377
|
/**
|
|
1330
1378
|
* What the runner's account lacks of the git identity citizens' own commits carry, checked
|
|
1331
1379
|
* before each hello outside any repository; empty when it has both. Absent from a runner from
|
|
1332
1380
|
* before the check, which no default fills in, so the board marks only what a runner reported.
|
|
1333
1381
|
*/
|
|
1334
|
-
gitIdentityMissing:
|
|
1382
|
+
gitIdentityMissing: z9.array(GitIdentityPartSchema).optional(),
|
|
1335
1383
|
/** Turns the runner runs at once, or null for no limit. */
|
|
1336
|
-
slots:
|
|
1384
|
+
slots: z9.number().int().positive().nullable(),
|
|
1337
1385
|
/** Turns the runner is still running, when it registers again; the server fails the rest of its turns. */
|
|
1338
|
-
turns:
|
|
1386
|
+
turns: z9.array(UlidSchema).default([])
|
|
1339
1387
|
});
|
|
1340
|
-
var RunnerWelcomeSchema =
|
|
1341
|
-
var RunnerEnrollRequestSchema =
|
|
1342
|
-
protocol:
|
|
1343
|
-
version:
|
|
1344
|
-
hostname:
|
|
1388
|
+
var RunnerWelcomeSchema = z9.object({ name: NameSchema, version: z9.string() });
|
|
1389
|
+
var RunnerEnrollRequestSchema = z9.object({
|
|
1390
|
+
protocol: z9.number().int().positive(),
|
|
1391
|
+
version: z9.string().min(1).max(64),
|
|
1392
|
+
hostname: z9.string().min(1).max(253),
|
|
1345
1393
|
os: RunnerOsSchema,
|
|
1346
|
-
clis:
|
|
1347
|
-
capabilities:
|
|
1394
|
+
clis: z9.array(CliKindSchema).max(8),
|
|
1395
|
+
capabilities: z9.array(z9.string().min(1).max(64)).max(32).default([])
|
|
1348
1396
|
});
|
|
1349
|
-
var RunnerEnrollmentSchema =
|
|
1350
|
-
deviceCode:
|
|
1351
|
-
userCode:
|
|
1397
|
+
var RunnerEnrollmentSchema = z9.object({
|
|
1398
|
+
deviceCode: z9.string().min(1),
|
|
1399
|
+
userCode: z9.string().min(1),
|
|
1352
1400
|
expiresAt: IsoDateTimeSchema,
|
|
1353
|
-
intervalMs:
|
|
1401
|
+
intervalMs: z9.number().int().positive()
|
|
1354
1402
|
});
|
|
1355
|
-
var RunnerEnrollPollSchema =
|
|
1356
|
-
var RunnerEnrollStatusSchema =
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1403
|
+
var RunnerEnrollPollSchema = z9.object({ deviceCode: z9.string().min(1) });
|
|
1404
|
+
var RunnerEnrollStatusSchema = z9.discriminatedUnion("status", [
|
|
1405
|
+
z9.object({ status: z9.literal("pending") }),
|
|
1406
|
+
z9.object({ status: z9.literal("approved"), name: NameSchema, token: z9.string().min(1) }),
|
|
1407
|
+
z9.object({ status: z9.literal("denied") })
|
|
1360
1408
|
]);
|
|
1361
|
-
var PendingEnrollmentSchema =
|
|
1362
|
-
userCode:
|
|
1363
|
-
hostname:
|
|
1409
|
+
var PendingEnrollmentSchema = z9.object({
|
|
1410
|
+
userCode: z9.string().min(1),
|
|
1411
|
+
hostname: z9.string(),
|
|
1364
1412
|
os: RunnerOsSchema,
|
|
1365
|
-
clis:
|
|
1366
|
-
capabilities:
|
|
1367
|
-
version:
|
|
1413
|
+
clis: z9.array(CliKindSchema),
|
|
1414
|
+
capabilities: z9.array(z9.string()),
|
|
1415
|
+
version: z9.string(),
|
|
1368
1416
|
requestedAt: IsoDateTimeSchema,
|
|
1369
1417
|
expiresAt: IsoDateTimeSchema
|
|
1370
1418
|
});
|
|
1371
|
-
var ProjectRepoSchema =
|
|
1419
|
+
var ProjectRepoSchema = z9.object({
|
|
1372
1420
|
slug: NameSchema,
|
|
1373
|
-
origin:
|
|
1374
|
-
defaultBranch:
|
|
1421
|
+
origin: z9.string().nullable(),
|
|
1422
|
+
defaultBranch: z9.string().min(1),
|
|
1375
1423
|
/**
|
|
1376
1424
|
* The board lands finished tasks on the default branch, itself or through their pull requests,
|
|
1377
1425
|
* so the runner lets nothing else move it.
|
|
1378
1426
|
*/
|
|
1379
|
-
boardLands:
|
|
1427
|
+
boardLands: z9.boolean()
|
|
1380
1428
|
});
|
|
1381
|
-
var TurnWorkspaceSchema =
|
|
1382
|
-
|
|
1383
|
-
kind:
|
|
1429
|
+
var TurnWorkspaceSchema = z9.discriminatedUnion("kind", [
|
|
1430
|
+
z9.object({
|
|
1431
|
+
kind: z9.literal("home"),
|
|
1384
1432
|
thread: UlidSchema.optional(),
|
|
1385
1433
|
channel: NameSchema.optional()
|
|
1386
1434
|
}),
|
|
1387
|
-
|
|
1388
|
-
kind:
|
|
1435
|
+
z9.object({
|
|
1436
|
+
kind: z9.literal("project"),
|
|
1389
1437
|
repo: ProjectRepoSchema,
|
|
1390
|
-
branches:
|
|
1438
|
+
branches: z9.array(z9.string().min(1)),
|
|
1391
1439
|
thread: UlidSchema.optional(),
|
|
1392
1440
|
channel: NameSchema.optional()
|
|
1393
1441
|
}),
|
|
1394
|
-
|
|
1442
|
+
z9.object({ kind: z9.literal("task"), repo: ProjectRepoSchema, taskId: UlidSchema })
|
|
1395
1443
|
]);
|
|
1396
|
-
var TurnJobSchema =
|
|
1444
|
+
var TurnJobSchema = z9.object({
|
|
1397
1445
|
turnId: UlidSchema,
|
|
1398
1446
|
agent: NameSchema,
|
|
1399
1447
|
role: NameSchema,
|
|
1400
1448
|
cli: CliKindSchema,
|
|
1401
|
-
model:
|
|
1449
|
+
model: z9.string().optional(),
|
|
1402
1450
|
/** The reasoning effort set on the agent; absent for the model's own default. */
|
|
1403
|
-
effort:
|
|
1451
|
+
effort: z9.string().optional(),
|
|
1404
1452
|
/** A project slug, or the society scope. */
|
|
1405
1453
|
scope: NameSchema,
|
|
1406
1454
|
/** The thread whose conversation the turn is in; absent for the home conversation. */
|
|
@@ -1411,130 +1459,130 @@ var TurnJobSchema = z8.object({
|
|
|
1411
1459
|
* The session to resume, or null to start one: the CLI's adapter picks a fresh session's id, and
|
|
1412
1460
|
* the outcome reports it.
|
|
1413
1461
|
*/
|
|
1414
|
-
session:
|
|
1462
|
+
session: z9.string().min(1).nullable(),
|
|
1415
1463
|
/** The running total the session reported after its last turn, which a resumed session starts from. */
|
|
1416
|
-
costSoFarUsd:
|
|
1464
|
+
costSoFarUsd: z9.number().nonnegative(),
|
|
1417
1465
|
/** The rendered charter, norms, memory core, and skills index, with `PATH_TOKENS` for places. */
|
|
1418
|
-
instructions:
|
|
1419
|
-
prompt:
|
|
1420
|
-
mcp:
|
|
1421
|
-
limits:
|
|
1422
|
-
timeoutMs:
|
|
1423
|
-
maxTurns:
|
|
1466
|
+
instructions: z9.string(),
|
|
1467
|
+
prompt: z9.string(),
|
|
1468
|
+
mcp: z9.object({ url: z9.string().min(1), token: z9.string().min(1) }),
|
|
1469
|
+
limits: z9.object({
|
|
1470
|
+
timeoutMs: z9.number().int().positive().nullable(),
|
|
1471
|
+
maxTurns: z9.number().int().positive().nullable()
|
|
1424
1472
|
}),
|
|
1425
1473
|
/** Present when the runner keeps the conversation's session warm between turns, under `key`. */
|
|
1426
|
-
resident:
|
|
1474
|
+
resident: z9.object({ key: z9.string().min(1), idleMs: z9.number().int().positive() }).optional(),
|
|
1427
1475
|
workspace: TurnWorkspaceSchema
|
|
1428
1476
|
});
|
|
1429
|
-
var TurnWorkSchema =
|
|
1430
|
-
var TurnEventsSchema =
|
|
1431
|
-
var TurnOutcomeSchema =
|
|
1477
|
+
var TurnWorkSchema = z9.object({ branch: z9.string().min(1), head: z9.string().min(1) });
|
|
1478
|
+
var TurnEventsSchema = z9.object({ entries: z9.array(TranscriptEntrySchema) });
|
|
1479
|
+
var TurnOutcomeSchema = z9.object({
|
|
1432
1480
|
exitReason: TurnExitReasonSchema,
|
|
1433
1481
|
status: TurnStatusSchema.nullable(),
|
|
1434
|
-
error:
|
|
1482
|
+
error: z9.string().nullable(),
|
|
1435
1483
|
usage: UsageSchema,
|
|
1436
|
-
costUsd:
|
|
1484
|
+
costUsd: z9.number().nonnegative(),
|
|
1437
1485
|
/** The session's running total after this turn, for CLIs that report one. */
|
|
1438
|
-
sessionCostUsd:
|
|
1486
|
+
sessionCostUsd: z9.number().nonnegative().optional(),
|
|
1439
1487
|
/** The session the CLI used, which differs from the job's for CLIs that assign their own ids. */
|
|
1440
|
-
session:
|
|
1488
|
+
session: z9.string().min(1),
|
|
1441
1489
|
/** The model the CLI reported, when it reported one. */
|
|
1442
|
-
model:
|
|
1490
|
+
model: z9.string().nullable(),
|
|
1443
1491
|
work: TurnWorkSchema.nullable(),
|
|
1444
1492
|
/**
|
|
1445
1493
|
* Whether the turn's own workspace, a thread's, a channel's, or a task's, holds work on no
|
|
1446
1494
|
* branch after the hand-back: uncommitted changes, or commits no branch contains.
|
|
1447
1495
|
*/
|
|
1448
|
-
leftovers:
|
|
1496
|
+
leftovers: z9.boolean().default(false),
|
|
1449
1497
|
/**
|
|
1450
1498
|
* The CLI's plan quota as the turn's stream last reported it, when it reported any; a runner from
|
|
1451
1499
|
* before never sends it.
|
|
1452
1500
|
*/
|
|
1453
1501
|
quota: CliQuotaSchema.optional()
|
|
1454
1502
|
});
|
|
1455
|
-
var TurnAckSchema =
|
|
1456
|
-
var LandRequestSchema =
|
|
1503
|
+
var TurnAckSchema = z9.object({ dropWorkspace: z9.boolean() });
|
|
1504
|
+
var LandRequestSchema = z9.object({
|
|
1457
1505
|
repo: ProjectRepoSchema,
|
|
1458
|
-
branch:
|
|
1506
|
+
branch: z9.string().min(1),
|
|
1459
1507
|
/**
|
|
1460
1508
|
* For a `ghpr` task, the pull request to merge in place of the branch, which must hold the
|
|
1461
1509
|
* branch's files, and the merge commit's subject and body, the pull request's title and an
|
|
1462
1510
|
* empty body when left out.
|
|
1463
1511
|
*/
|
|
1464
|
-
pullRequest:
|
|
1465
|
-
url:
|
|
1466
|
-
subject:
|
|
1467
|
-
body:
|
|
1512
|
+
pullRequest: z9.object({
|
|
1513
|
+
url: z9.string().min(1),
|
|
1514
|
+
subject: z9.string().min(1).optional(),
|
|
1515
|
+
body: z9.string().optional()
|
|
1468
1516
|
}).optional()
|
|
1469
1517
|
});
|
|
1470
|
-
var CloseRequestSchema =
|
|
1518
|
+
var CloseRequestSchema = z9.object({
|
|
1471
1519
|
repo: ProjectRepoSchema,
|
|
1472
|
-
url:
|
|
1473
|
-
comment:
|
|
1520
|
+
url: z9.string().min(1),
|
|
1521
|
+
comment: z9.string().min(1)
|
|
1474
1522
|
});
|
|
1475
|
-
var MergeOutcomeSchema =
|
|
1476
|
-
var ModelListSchema =
|
|
1523
|
+
var MergeOutcomeSchema = z9.object({ ok: z9.boolean(), detail: z9.string() });
|
|
1524
|
+
var ModelListSchema = z9.array(ModelOptionSchema);
|
|
1477
1525
|
var BRANCH_FILE_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
1478
|
-
var BranchPathSchema =
|
|
1479
|
-
var BranchNameSchema =
|
|
1480
|
-
var BranchReadSchema =
|
|
1526
|
+
var BranchPathSchema = z9.string().max(4096).refine((value) => value === "" || value.split("/").every((segment) => segment !== "" && segment !== "." && segment !== ".." && !segment.includes("\0")), { message: "a path inside the branch, with no empty, `.`, or `..` segment" });
|
|
1527
|
+
var BranchNameSchema = z9.string().regex(/^[A-Za-z0-9][A-Za-z0-9._/-]*$/);
|
|
1528
|
+
var BranchReadSchema = z9.object({
|
|
1481
1529
|
repo: ProjectRepoSchema,
|
|
1482
1530
|
branch: BranchNameSchema,
|
|
1483
1531
|
path: BranchPathSchema
|
|
1484
1532
|
});
|
|
1485
|
-
var BranchCommitSchema =
|
|
1486
|
-
id:
|
|
1533
|
+
var BranchCommitSchema = z9.object({
|
|
1534
|
+
id: z9.string().min(1),
|
|
1487
1535
|
at: IsoDateTimeSchema,
|
|
1488
|
-
author:
|
|
1536
|
+
author: z9.string()
|
|
1489
1537
|
});
|
|
1490
|
-
var BranchFileSchema =
|
|
1491
|
-
|
|
1492
|
-
kind:
|
|
1538
|
+
var BranchFileSchema = z9.discriminatedUnion("kind", [
|
|
1539
|
+
z9.object({
|
|
1540
|
+
kind: z9.literal("file"),
|
|
1493
1541
|
path: BranchPathSchema,
|
|
1494
1542
|
commit: BranchCommitSchema,
|
|
1495
|
-
size:
|
|
1496
|
-
content:
|
|
1543
|
+
size: z9.number().int().nonnegative(),
|
|
1544
|
+
content: z9.string().nullable()
|
|
1497
1545
|
}),
|
|
1498
|
-
|
|
1499
|
-
kind:
|
|
1546
|
+
z9.object({
|
|
1547
|
+
kind: z9.literal("dir"),
|
|
1500
1548
|
path: BranchPathSchema,
|
|
1501
1549
|
commit: BranchCommitSchema,
|
|
1502
|
-
entries:
|
|
1503
|
-
name:
|
|
1504
|
-
kind:
|
|
1505
|
-
size:
|
|
1550
|
+
entries: z9.array(z9.object({
|
|
1551
|
+
name: z9.string().min(1),
|
|
1552
|
+
kind: z9.enum(["file", "dir"]),
|
|
1553
|
+
size: z9.number().int().nonnegative().nullable()
|
|
1506
1554
|
}))
|
|
1507
1555
|
})
|
|
1508
1556
|
]);
|
|
1509
|
-
var BranchChangesReadSchema =
|
|
1557
|
+
var BranchChangesReadSchema = z9.object({
|
|
1510
1558
|
repo: ProjectRepoSchema,
|
|
1511
1559
|
branch: BranchNameSchema
|
|
1512
1560
|
});
|
|
1513
|
-
var BranchFileChangeSchema =
|
|
1514
|
-
path:
|
|
1515
|
-
status:
|
|
1561
|
+
var BranchFileChangeSchema = z9.object({
|
|
1562
|
+
path: z9.string().min(1),
|
|
1563
|
+
status: z9.enum(["added", "modified", "deleted"]),
|
|
1516
1564
|
/** Lines added and removed, or null for a binary file. */
|
|
1517
|
-
added:
|
|
1518
|
-
removed:
|
|
1565
|
+
added: z9.number().int().nonnegative().nullable(),
|
|
1566
|
+
removed: z9.number().int().nonnegative().nullable(),
|
|
1519
1567
|
/** Absent when the file changed only through a merge of another branch. */
|
|
1520
|
-
lastChange:
|
|
1568
|
+
lastChange: z9.object({ author: z9.string(), at: IsoDateTimeSchema }).optional()
|
|
1521
1569
|
});
|
|
1522
|
-
var BranchChangesSchema =
|
|
1570
|
+
var BranchChangesSchema = z9.object({
|
|
1523
1571
|
head: BranchCommitSchema,
|
|
1524
|
-
files:
|
|
1525
|
-
total:
|
|
1572
|
+
files: z9.array(BranchFileChangeSchema),
|
|
1573
|
+
total: z9.number().int().nonnegative()
|
|
1526
1574
|
});
|
|
1527
|
-
var BranchDiffReadSchema =
|
|
1575
|
+
var BranchDiffReadSchema = z9.object({
|
|
1528
1576
|
repo: ProjectRepoSchema,
|
|
1529
1577
|
branch: BranchNameSchema,
|
|
1530
1578
|
path: BranchPathSchema.min(1)
|
|
1531
1579
|
});
|
|
1532
|
-
var BranchFileDiffSchema =
|
|
1580
|
+
var BranchFileDiffSchema = z9.object({
|
|
1533
1581
|
head: BranchCommitSchema,
|
|
1534
1582
|
path: BranchPathSchema,
|
|
1535
1583
|
status: BranchFileChangeSchema.shape.status,
|
|
1536
|
-
patch:
|
|
1537
|
-
truncated:
|
|
1584
|
+
patch: z9.string().nullable(),
|
|
1585
|
+
truncated: z9.boolean()
|
|
1538
1586
|
});
|
|
1539
1587
|
function patchHunks(patch, limit) {
|
|
1540
1588
|
if (/^Binary files .* differ$/m.test(patch)) {
|
|
@@ -1548,69 +1596,88 @@ function patchHunks(patch, limit) {
|
|
|
1548
1596
|
const cut = hunks.lastIndexOf("\n", limit);
|
|
1549
1597
|
return { patch: hunks.slice(0, cut === -1 ? limit : cut), truncated: true };
|
|
1550
1598
|
}
|
|
1551
|
-
var
|
|
1552
|
-
|
|
1553
|
-
|
|
1599
|
+
var TurnImageReadSchema = z9.object({
|
|
1600
|
+
turnId: UlidSchema,
|
|
1601
|
+
path: ImagePathSchema
|
|
1602
|
+
});
|
|
1603
|
+
var ImageRefusalSchema = z9.enum(["missing", "outside", "not_image", "too_big"]);
|
|
1604
|
+
var TurnImageSchema = z9.discriminatedUnion("kind", [
|
|
1605
|
+
z9.object({
|
|
1606
|
+
kind: z9.literal("image"),
|
|
1607
|
+
type: ImageTypeSchema,
|
|
1608
|
+
size: z9.number().int().positive(),
|
|
1609
|
+
content: z9.string()
|
|
1610
|
+
}),
|
|
1611
|
+
z9.object({ kind: z9.literal("refused"), why: ImageRefusalSchema, detail: z9.string() })
|
|
1612
|
+
]);
|
|
1613
|
+
var WorkspaceConversationSchema = z9.discriminatedUnion("kind", [
|
|
1614
|
+
z9.object({ kind: z9.literal("thread"), id: UlidSchema }),
|
|
1615
|
+
z9.object({ kind: z9.literal("channel"), scope: NameSchema, name: NameSchema })
|
|
1554
1616
|
]);
|
|
1555
|
-
var HeldWorkspaceSchema =
|
|
1617
|
+
var HeldWorkspaceSchema = z9.object({
|
|
1556
1618
|
agent: NameSchema,
|
|
1557
1619
|
scope: NameSchema,
|
|
1558
1620
|
conversation: WorkspaceConversationSchema
|
|
1559
1621
|
});
|
|
1560
|
-
var HeldWorkspacesSchema =
|
|
1561
|
-
var SweepResultSchema =
|
|
1562
|
-
var TurnSteerSchema =
|
|
1563
|
-
var RunnerMessageSchema =
|
|
1564
|
-
|
|
1565
|
-
|
|
1622
|
+
var HeldWorkspacesSchema = z9.object({ workspaces: z9.array(HeldWorkspaceSchema) });
|
|
1623
|
+
var SweepResultSchema = z9.object({ kept: z9.array(HeldWorkspaceSchema) });
|
|
1624
|
+
var TurnSteerSchema = z9.object({ id: z9.uuid(), text: z9.string().min(1) });
|
|
1625
|
+
var RunnerMessageSchema = z9.discriminatedUnion("type", [
|
|
1626
|
+
z9.object({ type: z9.literal("turn"), job: TurnJobSchema }),
|
|
1627
|
+
z9.object({ type: z9.literal("land"), request: z9.string().min(1), land: LandRequestSchema }),
|
|
1566
1628
|
/** Answered with a `MergeOutcome`. */
|
|
1567
|
-
|
|
1568
|
-
|
|
1629
|
+
z9.object({ type: z9.literal("close"), request: z9.string().min(1), close: CloseRequestSchema }),
|
|
1630
|
+
z9.object({ type: z9.literal("models"), request: z9.string().min(1), cli: CliKindSchema }),
|
|
1569
1631
|
/**
|
|
1570
1632
|
* Answered with a `CliQuota` read from the CLI without a turn, or null when its adapter cannot
|
|
1571
1633
|
* read one. Sent only to runners whose hello says `quotaReads`.
|
|
1572
1634
|
*/
|
|
1573
|
-
|
|
1635
|
+
z9.object({ type: z9.literal("quota"), request: z9.string().min(1), cli: CliKindSchema }),
|
|
1574
1636
|
/** Answered with a `BranchFile`, or null when the branch or the path does not exist. */
|
|
1575
|
-
|
|
1637
|
+
z9.object({ type: z9.literal("file"), request: z9.string().min(1), read: BranchReadSchema }),
|
|
1576
1638
|
/** Answered with `BranchChanges`, or null when the repository or the branch does not exist. */
|
|
1577
|
-
|
|
1578
|
-
type:
|
|
1579
|
-
request:
|
|
1639
|
+
z9.object({
|
|
1640
|
+
type: z9.literal("changes"),
|
|
1641
|
+
request: z9.string().min(1),
|
|
1580
1642
|
read: BranchChangesReadSchema
|
|
1581
1643
|
}),
|
|
1582
1644
|
/** Answered with a `BranchFileDiff`, or null when the branch does not exist or left the path alone. */
|
|
1583
|
-
|
|
1645
|
+
z9.object({ type: z9.literal("diff"), request: z9.string().min(1), read: BranchDiffReadSchema }),
|
|
1646
|
+
/**
|
|
1647
|
+
* Answered with a `TurnImage`, or null when the turn is not running there. Sent only to runners
|
|
1648
|
+
* whose hello says `imageReads`.
|
|
1649
|
+
*/
|
|
1650
|
+
z9.object({ type: z9.literal("image"), request: z9.string().min(1), read: TurnImageReadSchema }),
|
|
1584
1651
|
/** Answered with whether the CLI accepted it; that it took it comes as a `steered` event. */
|
|
1585
|
-
|
|
1586
|
-
type:
|
|
1587
|
-
request:
|
|
1652
|
+
z9.object({
|
|
1653
|
+
type: z9.literal("steer"),
|
|
1654
|
+
request: z9.string().min(1),
|
|
1588
1655
|
turnId: UlidSchema,
|
|
1589
1656
|
steer: TurnSteerSchema
|
|
1590
1657
|
}),
|
|
1591
1658
|
/** Answered with whether the turn was there to stop; it ends `stopped`. */
|
|
1592
|
-
|
|
1659
|
+
z9.object({ type: z9.literal("stop"), request: z9.string().min(1), turnId: UlidSchema }),
|
|
1593
1660
|
/**
|
|
1594
1661
|
* A conversation ended: the runner removes every citizen's workspace for it but those a turn
|
|
1595
1662
|
* still uses, and answers with a `SweepResult` naming those it kept for holding work on no branch.
|
|
1596
1663
|
*/
|
|
1597
|
-
|
|
1598
|
-
type:
|
|
1599
|
-
request:
|
|
1664
|
+
z9.object({
|
|
1665
|
+
type: z9.literal("sweep"),
|
|
1666
|
+
request: z9.string().min(1),
|
|
1600
1667
|
conversation: WorkspaceConversationSchema
|
|
1601
1668
|
})
|
|
1602
1669
|
]);
|
|
1603
|
-
var RunnerAnswerSchema =
|
|
1604
|
-
|
|
1605
|
-
|
|
1670
|
+
var RunnerAnswerSchema = z9.discriminatedUnion("ok", [
|
|
1671
|
+
z9.object({ ok: z9.literal(true), value: z9.unknown() }),
|
|
1672
|
+
z9.object({ ok: z9.literal(false), error: z9.string() })
|
|
1606
1673
|
]);
|
|
1607
|
-
var WarmSessionsSchema =
|
|
1608
|
-
var FileManifestSchema =
|
|
1674
|
+
var WarmSessionsSchema = z9.object({ warm: z9.array(z9.string()) });
|
|
1675
|
+
var FileManifestSchema = z9.object({ files: z9.record(z9.string(), z9.string()) });
|
|
1609
1676
|
function fileVersion(sha, executable) {
|
|
1610
1677
|
return executable ? `${sha}+x` : sha;
|
|
1611
1678
|
}
|
|
1612
|
-
var FileReadSchema =
|
|
1613
|
-
var FileContentsSchema =
|
|
1679
|
+
var FileReadSchema = z9.object({ paths: z9.array(z9.string()) });
|
|
1680
|
+
var FileContentsSchema = z9.object({ files: z9.record(z9.string(), z9.string()) });
|
|
1614
1681
|
function isSafeRelativePath(file) {
|
|
1615
1682
|
if (file.length === 0 || file.startsWith("/") || file.includes("\\") || file.includes("\0")) {
|
|
1616
1683
|
return false;
|
|
@@ -1619,7 +1686,7 @@ function isSafeRelativePath(file) {
|
|
|
1619
1686
|
}
|
|
1620
1687
|
|
|
1621
1688
|
// packages/shared/dist/turns.js
|
|
1622
|
-
var TriggerKindSchema =
|
|
1689
|
+
var TriggerKindSchema = z10.enum([
|
|
1623
1690
|
"mention",
|
|
1624
1691
|
"stage",
|
|
1625
1692
|
"task_done",
|
|
@@ -1633,11 +1700,11 @@ var TriggerKindSchema = z9.enum([
|
|
|
1633
1700
|
"closing",
|
|
1634
1701
|
"cron"
|
|
1635
1702
|
]);
|
|
1636
|
-
var TriggerSchema =
|
|
1703
|
+
var TriggerSchema = z10.object({
|
|
1637
1704
|
kind: TriggerKindSchema,
|
|
1638
1705
|
from: NameSchema.optional(),
|
|
1639
|
-
fromUser:
|
|
1640
|
-
reason:
|
|
1706
|
+
fromUser: z10.boolean().default(false),
|
|
1707
|
+
reason: z10.string().default(""),
|
|
1641
1708
|
taskId: UlidSchema.optional(),
|
|
1642
1709
|
messageId: UlidSchema.optional(),
|
|
1643
1710
|
/** The channel the waking message was posted in. */
|
|
@@ -1645,17 +1712,17 @@ var TriggerSchema = z9.object({
|
|
|
1645
1712
|
/** The cron that came due, for a `cron` wake. */
|
|
1646
1713
|
cronId: UlidSchema.optional()
|
|
1647
1714
|
});
|
|
1648
|
-
var TurnThreadSchema =
|
|
1649
|
-
var TurnDispatchSchema =
|
|
1715
|
+
var TurnThreadSchema = z10.object({ id: UlidSchema, task: z10.boolean() });
|
|
1716
|
+
var TurnDispatchSchema = z10.object({
|
|
1650
1717
|
agent: NameSchema,
|
|
1651
1718
|
project: NameSchema,
|
|
1652
1719
|
thread: TurnThreadSchema.optional(),
|
|
1653
1720
|
channel: NameSchema.optional(),
|
|
1654
1721
|
trigger: TriggerSchema,
|
|
1655
|
-
priority:
|
|
1656
|
-
onboarding:
|
|
1722
|
+
priority: z10.number().int().min(0).max(2),
|
|
1723
|
+
onboarding: z10.boolean().default(false),
|
|
1657
1724
|
/** Every cron that came due for this turn, whatever wake it merged into; its prompt quotes each. */
|
|
1658
|
-
crons:
|
|
1725
|
+
crons: z10.array(UlidSchema).optional()
|
|
1659
1726
|
});
|
|
1660
1727
|
function conversationPart(conversation) {
|
|
1661
1728
|
return conversation.thread ?? (conversation.channel === void 0 ? void 0 : `#${conversation.channel}`);
|
|
@@ -1666,7 +1733,7 @@ function channelConversation(scope, channel) {
|
|
|
1666
1733
|
const name = at < 0 ? channel : channel.slice(at + 1);
|
|
1667
1734
|
return place === scope && name !== "general" ? name : void 0;
|
|
1668
1735
|
}
|
|
1669
|
-
var TurnRecordSchema =
|
|
1736
|
+
var TurnRecordSchema = z10.object({
|
|
1670
1737
|
/** Assigned by the board when the turn begins; the turn's transcript is filed under it. */
|
|
1671
1738
|
id: UlidSchema.optional(),
|
|
1672
1739
|
agent: NameSchema,
|
|
@@ -1677,31 +1744,31 @@ var TurnRecordSchema = z9.object({
|
|
|
1677
1744
|
channel: NameSchema.optional(),
|
|
1678
1745
|
runner: NameSchema,
|
|
1679
1746
|
cli: CliKindSchema.nullable(),
|
|
1680
|
-
session:
|
|
1747
|
+
session: z10.string().nullable(),
|
|
1681
1748
|
trigger: TriggerSchema,
|
|
1682
1749
|
startedAt: IsoDateTimeSchema,
|
|
1683
1750
|
endedAt: IsoDateTimeSchema.nullable(),
|
|
1684
1751
|
exitReason: TurnExitReasonSchema.nullable(),
|
|
1685
1752
|
status: TurnStatusSchema.nullable(),
|
|
1686
|
-
error:
|
|
1753
|
+
error: z10.string().nullable(),
|
|
1687
1754
|
usage: UsageSchema.nullable(),
|
|
1688
|
-
costUsd:
|
|
1755
|
+
costUsd: z10.number().nonnegative().default(0),
|
|
1689
1756
|
/**
|
|
1690
1757
|
* The running total the CLI reported for the session after this turn, when it reports one. A
|
|
1691
1758
|
* resumed session starts from it, so the next turn's own cost is measured from here.
|
|
1692
1759
|
*/
|
|
1693
|
-
sessionCostUsd:
|
|
1694
|
-
toolCalls:
|
|
1760
|
+
sessionCostUsd: z10.number().nonnegative().optional(),
|
|
1761
|
+
toolCalls: z10.number().int().nonnegative().default(0),
|
|
1695
1762
|
/** The model the CLI reported for this turn, else the model configured for the agent, else null. */
|
|
1696
|
-
model:
|
|
1763
|
+
model: z10.string().nullable().default(null),
|
|
1697
1764
|
/** The task branch the turn left work on, with its commit, as the runner reported it. */
|
|
1698
1765
|
work: TurnWorkSchema.optional(),
|
|
1699
1766
|
/** Who stopped the turn, for one that ended `stopped`. */
|
|
1700
1767
|
stoppedBy: NameSchema.optional(),
|
|
1701
1768
|
/** The crons whose fire started the turn, which record how it ended. */
|
|
1702
|
-
crons:
|
|
1769
|
+
crons: z10.array(UlidSchema).optional()
|
|
1703
1770
|
});
|
|
1704
|
-
var RunningTurnSchema =
|
|
1771
|
+
var RunningTurnSchema = z10.object({
|
|
1705
1772
|
turnId: UlidSchema,
|
|
1706
1773
|
agent: NameSchema,
|
|
1707
1774
|
scope: NameSchema,
|
|
@@ -1709,49 +1776,49 @@ var RunningTurnSchema = z9.object({
|
|
|
1709
1776
|
channel: NameSchema.optional(),
|
|
1710
1777
|
cli: CliKindSchema,
|
|
1711
1778
|
askedIn: ChannelRefSchema.optional(),
|
|
1712
|
-
steerable:
|
|
1713
|
-
stoppable:
|
|
1779
|
+
steerable: z10.boolean(),
|
|
1780
|
+
stoppable: z10.boolean()
|
|
1714
1781
|
});
|
|
1715
|
-
var SessionsFileSchema =
|
|
1716
|
-
claude:
|
|
1717
|
-
codex:
|
|
1782
|
+
var SessionsFileSchema = z10.object({
|
|
1783
|
+
claude: z10.string().optional(),
|
|
1784
|
+
codex: z10.string().optional(),
|
|
1718
1785
|
runner: NameSchema.optional()
|
|
1719
1786
|
});
|
|
1720
|
-
var WakeRequestSchema =
|
|
1787
|
+
var WakeRequestSchema = z10.object({
|
|
1721
1788
|
agent: NameSchema,
|
|
1722
1789
|
project: NameSchema,
|
|
1723
|
-
reason:
|
|
1790
|
+
reason: z10.string().default("manual wake"),
|
|
1724
1791
|
/** A manual wake, or a reflection turn requested ahead of the cadence. */
|
|
1725
|
-
kind:
|
|
1792
|
+
kind: z10.enum(["manual", "reflection"]).default("manual")
|
|
1726
1793
|
});
|
|
1727
|
-
var TurnHistoryEntrySchema =
|
|
1794
|
+
var TurnHistoryEntrySchema = z10.object({
|
|
1728
1795
|
/** The id of the event that ended the turn. */
|
|
1729
1796
|
id: UlidSchema,
|
|
1730
1797
|
/** The turn's own id, when it has a transcript to open; turns before transcripts have none. */
|
|
1731
1798
|
turnId: UlidSchema.optional(),
|
|
1732
1799
|
ts: IsoDateTimeSchema,
|
|
1733
|
-
outcome:
|
|
1800
|
+
outcome: z10.enum(["completed", "failed"]),
|
|
1734
1801
|
/** A project slug, or the society scope. */
|
|
1735
1802
|
project: NameSchema,
|
|
1736
1803
|
/** The thread whose conversation the turn was in; absent for the home conversation. */
|
|
1737
1804
|
thread: UlidSchema.optional(),
|
|
1738
1805
|
/** The channel, never general, whose conversation the turn was in. */
|
|
1739
1806
|
channel: NameSchema.optional(),
|
|
1740
|
-
trigger:
|
|
1741
|
-
exitReason:
|
|
1742
|
-
costUsd:
|
|
1807
|
+
trigger: z10.string(),
|
|
1808
|
+
exitReason: z10.string().nullable(),
|
|
1809
|
+
costUsd: z10.number(),
|
|
1743
1810
|
/** The tokens the turn used; absent for turns logged before turns recorded them. */
|
|
1744
1811
|
usage: UsageSchema.optional(),
|
|
1745
|
-
model:
|
|
1746
|
-
summary:
|
|
1747
|
-
error:
|
|
1812
|
+
model: z10.string().nullable(),
|
|
1813
|
+
summary: z10.string().nullable(),
|
|
1814
|
+
error: z10.string().nullable(),
|
|
1748
1815
|
/** When the log recorded the turn's start; absent when the start is missing from the log. */
|
|
1749
1816
|
startedAt: IsoDateTimeSchema.optional(),
|
|
1750
|
-
toolCalls:
|
|
1817
|
+
toolCalls: z10.number().int().nonnegative().optional()
|
|
1751
1818
|
});
|
|
1752
1819
|
|
|
1753
1820
|
// packages/shared/dist/ops.js
|
|
1754
|
-
import { z as
|
|
1821
|
+
import { z as z11 } from "zod";
|
|
1755
1822
|
var OPS_SIGNAL_KINDS = [
|
|
1756
1823
|
"waiting_stage",
|
|
1757
1824
|
"backlog",
|
|
@@ -1767,16 +1834,16 @@ var OPS_SIGNAL_KINDS = [
|
|
|
1767
1834
|
"stuck_workspace",
|
|
1768
1835
|
"cron_failing"
|
|
1769
1836
|
];
|
|
1770
|
-
var OpsSignalKindSchema =
|
|
1771
|
-
var OpsSignalSchema =
|
|
1837
|
+
var OpsSignalKindSchema = z11.enum(OPS_SIGNAL_KINDS);
|
|
1838
|
+
var OpsSignalSchema = z11.object({
|
|
1772
1839
|
kind: OpsSignalKindSchema,
|
|
1773
1840
|
/** Identifies the condition, for example `backlog:demo:engineer`, so a persisting one is not logged again every pass. */
|
|
1774
|
-
key:
|
|
1841
|
+
key: z11.string().min(1),
|
|
1775
1842
|
/** One line a reader can act on. */
|
|
1776
|
-
summary:
|
|
1843
|
+
summary: z11.string().min(1),
|
|
1777
1844
|
/** The counter or timer value behind the signal. */
|
|
1778
|
-
value:
|
|
1779
|
-
threshold:
|
|
1845
|
+
value: z11.number(),
|
|
1846
|
+
threshold: z11.number().optional(),
|
|
1780
1847
|
project: NameSchema.optional(),
|
|
1781
1848
|
agent: NameSchema.optional(),
|
|
1782
1849
|
role: NameSchema.optional(),
|
|
@@ -1784,8 +1851,8 @@ var OpsSignalSchema = z10.object({
|
|
|
1784
1851
|
});
|
|
1785
1852
|
|
|
1786
1853
|
// packages/shared/dist/metrics.js
|
|
1787
|
-
import { z as
|
|
1788
|
-
var MetricsWindowSchema =
|
|
1854
|
+
import { z as z12 } from "zod";
|
|
1855
|
+
var MetricsWindowSchema = z12.enum(["24h", "7d", "all"]);
|
|
1789
1856
|
var METRICS_WINDOW_MS = {
|
|
1790
1857
|
"24h": 24 * 36e5,
|
|
1791
1858
|
"7d": 7 * 24 * 36e5,
|
|
@@ -1796,9 +1863,9 @@ function isBoardAction(tool) {
|
|
|
1796
1863
|
const verb = /^mcp__board__(.+)$/.exec(tool)?.[1];
|
|
1797
1864
|
return verb !== void 0 && !READ_VERBS.some((read2) => read2 === verb);
|
|
1798
1865
|
}
|
|
1799
|
-
var CountSchema =
|
|
1800
|
-
var MsSchema =
|
|
1801
|
-
var MetricsSchema =
|
|
1866
|
+
var CountSchema = z12.number().int().nonnegative();
|
|
1867
|
+
var MsSchema = z12.number().nonnegative();
|
|
1868
|
+
var MetricsSchema = z12.object({
|
|
1802
1869
|
window: MetricsWindowSchema,
|
|
1803
1870
|
since: IsoDateTimeSchema.nullable(),
|
|
1804
1871
|
until: IsoDateTimeSchema,
|
|
@@ -1806,12 +1873,12 @@ var MetricsSchema = z11.object({
|
|
|
1806
1873
|
* Finished turns that changed nothing on the board. Reflections are left out, since they write
|
|
1807
1874
|
* memory, not the board; turns without a transcript are counted apart, their actions unknown.
|
|
1808
1875
|
*/
|
|
1809
|
-
idle:
|
|
1876
|
+
idle: z12.object({
|
|
1810
1877
|
turns: CountSchema,
|
|
1811
1878
|
idle: CountSchema,
|
|
1812
1879
|
unknown: CountSchema,
|
|
1813
|
-
byTrigger:
|
|
1814
|
-
byAgent:
|
|
1880
|
+
byTrigger: z12.array(z12.object({ trigger: z12.string(), turns: CountSchema, idle: CountSchema })),
|
|
1881
|
+
byAgent: z12.array(z12.object({
|
|
1815
1882
|
agent: NameSchema,
|
|
1816
1883
|
role: NameSchema.nullable(),
|
|
1817
1884
|
turns: CountSchema,
|
|
@@ -1819,33 +1886,33 @@ var MetricsSchema = z11.object({
|
|
|
1819
1886
|
}))
|
|
1820
1887
|
}),
|
|
1821
1888
|
/** Work sent back to an earlier stage: over the tasks finished in the window, and by where. */
|
|
1822
|
-
sentBack:
|
|
1889
|
+
sentBack: z12.object({
|
|
1823
1890
|
finished: CountSchema,
|
|
1824
1891
|
sendBacks: CountSchema,
|
|
1825
1892
|
tasksSentBack: CountSchema,
|
|
1826
|
-
byStage:
|
|
1827
|
-
bySender:
|
|
1893
|
+
byStage: z12.array(z12.object({ project: NameSchema, stage: z12.string(), count: CountSchema })),
|
|
1894
|
+
bySender: z12.array(z12.object({ agent: NameSchema, count: CountSchema }))
|
|
1828
1895
|
}),
|
|
1829
1896
|
/** Posts in the threads of the tasks finished in the window, the board's own notices left out. */
|
|
1830
|
-
messages:
|
|
1897
|
+
messages: z12.object({
|
|
1831
1898
|
finished: CountSchema,
|
|
1832
1899
|
messages: CountSchema,
|
|
1833
|
-
byProject:
|
|
1834
|
-
busiest:
|
|
1900
|
+
byProject: z12.array(z12.object({ project: NameSchema, finished: CountSchema, messages: CountSchema })),
|
|
1901
|
+
busiest: z12.array(z12.object({
|
|
1835
1902
|
taskId: UlidSchema,
|
|
1836
|
-
title:
|
|
1903
|
+
title: z12.string(),
|
|
1837
1904
|
project: NameSchema,
|
|
1838
1905
|
messages: CountSchema
|
|
1839
1906
|
}))
|
|
1840
1907
|
}),
|
|
1841
1908
|
/** Time from a mention to the start of the turn it woke, in the conversation it was made in. */
|
|
1842
|
-
latency:
|
|
1909
|
+
latency: z12.object({
|
|
1843
1910
|
mentions: CountSchema,
|
|
1844
1911
|
/** Mentions no turn has followed yet. */
|
|
1845
1912
|
unanswered: CountSchema,
|
|
1846
1913
|
medianMs: MsSchema.nullable(),
|
|
1847
1914
|
slowestMs: MsSchema.nullable(),
|
|
1848
|
-
byAgent:
|
|
1915
|
+
byAgent: z12.array(z12.object({
|
|
1849
1916
|
agent: NameSchema,
|
|
1850
1917
|
mentions: CountSchema,
|
|
1851
1918
|
medianMs: MsSchema,
|
|
@@ -1853,93 +1920,93 @@ var MetricsSchema = z11.object({
|
|
|
1853
1920
|
}))
|
|
1854
1921
|
}),
|
|
1855
1922
|
/** The user's decisions: proposals decided, questions answered, and stages passed or sent back. */
|
|
1856
|
-
decisions:
|
|
1923
|
+
decisions: z12.object({
|
|
1857
1924
|
total: CountSchema,
|
|
1858
|
-
byDay:
|
|
1859
|
-
day:
|
|
1925
|
+
byDay: z12.array(z12.object({
|
|
1926
|
+
day: z12.string(),
|
|
1860
1927
|
proposals: CountSchema,
|
|
1861
1928
|
answers: CountSchema,
|
|
1862
1929
|
stages: CountSchema
|
|
1863
1930
|
}))
|
|
1864
1931
|
}),
|
|
1865
1932
|
/** Tasks that needed a capability no connected runner offered, and whether they still do. */
|
|
1866
|
-
blocked:
|
|
1933
|
+
blocked: z12.array(z12.object({
|
|
1867
1934
|
taskId: UlidSchema,
|
|
1868
|
-
title:
|
|
1935
|
+
title: z12.string().nullable(),
|
|
1869
1936
|
project: NameSchema.nullable(),
|
|
1870
|
-
summary:
|
|
1937
|
+
summary: z12.string(),
|
|
1871
1938
|
firstAt: IsoDateTimeSchema,
|
|
1872
1939
|
lastAt: IsoDateTimeSchema,
|
|
1873
|
-
holds:
|
|
1940
|
+
holds: z12.boolean()
|
|
1874
1941
|
}))
|
|
1875
1942
|
});
|
|
1876
|
-
var CitizenTokensSchema =
|
|
1943
|
+
var CitizenTokensSchema = z12.object({
|
|
1877
1944
|
agent: NameSchema,
|
|
1878
1945
|
turns: CountSchema,
|
|
1879
1946
|
withUsage: CountSchema,
|
|
1880
1947
|
usage: UsageSchema.nullable()
|
|
1881
1948
|
});
|
|
1882
|
-
var TokenUseSchema =
|
|
1949
|
+
var TokenUseSchema = z12.object({
|
|
1883
1950
|
window: MetricsWindowSchema,
|
|
1884
1951
|
since: IsoDateTimeSchema.nullable(),
|
|
1885
1952
|
until: IsoDateTimeSchema,
|
|
1886
|
-
citizens:
|
|
1953
|
+
citizens: z12.array(CitizenTokensSchema)
|
|
1887
1954
|
});
|
|
1888
1955
|
|
|
1889
1956
|
// packages/shared/dist/config.js
|
|
1890
|
-
import { z as
|
|
1891
|
-
var LogLevelSchema =
|
|
1892
|
-
var GithubSignInSchema =
|
|
1893
|
-
clientId:
|
|
1894
|
-
clientSecret:
|
|
1957
|
+
import { z as z13 } from "zod";
|
|
1958
|
+
var LogLevelSchema = z13.enum(["trace", "debug", "info", "warn", "error", "fatal"]);
|
|
1959
|
+
var GithubSignInSchema = z13.object({
|
|
1960
|
+
clientId: z13.string().min(1),
|
|
1961
|
+
clientSecret: z13.string().min(1),
|
|
1895
1962
|
/** Logins, lowercased; GitHub logins are case-insensitive. */
|
|
1896
|
-
users:
|
|
1963
|
+
users: z13.array(z13.string().min(1)).min(1)
|
|
1897
1964
|
});
|
|
1898
|
-
var ServerConfigSchema =
|
|
1899
|
-
dataDir:
|
|
1900
|
-
host:
|
|
1901
|
-
port:
|
|
1965
|
+
var ServerConfigSchema = z13.object({
|
|
1966
|
+
dataDir: z13.string().min(1),
|
|
1967
|
+
host: z13.string().min(1),
|
|
1968
|
+
port: z13.number().int().positive().max(65535),
|
|
1902
1969
|
/**
|
|
1903
1970
|
* An address every runner's agents reach this server at, for example https://board.example, or
|
|
1904
1971
|
* null for each runner to use the address it reaches the server at itself.
|
|
1905
1972
|
*/
|
|
1906
|
-
publicUrl:
|
|
1973
|
+
publicUrl: z13.string().min(1).nullable(),
|
|
1907
1974
|
logLevel: LogLevelSchema,
|
|
1908
1975
|
/** Turns running at once across every runner, or null for no limit beyond each runner's own. */
|
|
1909
|
-
concurrency:
|
|
1976
|
+
concurrency: z13.number().int().positive().nullable(),
|
|
1910
1977
|
/** How long one turn may run before it is stopped, or null for no limit. */
|
|
1911
|
-
turnTimeoutMs:
|
|
1978
|
+
turnTimeoutMs: z13.number().int().positive().nullable(),
|
|
1912
1979
|
/** Rounds of tool calls one Claude turn may take, or null for no limit. */
|
|
1913
|
-
toolRounds:
|
|
1980
|
+
toolRounds: z13.number().int().positive().nullable(),
|
|
1914
1981
|
/** How long a resident session stays warm after its last turn. */
|
|
1915
|
-
residentIdleMs:
|
|
1982
|
+
residentIdleMs: z13.number().int().positive(),
|
|
1916
1983
|
/** Signing in to the board with GitHub, or null when only a token lets anyone in. */
|
|
1917
1984
|
github: GithubSignInSchema.nullable(),
|
|
1918
1985
|
/**
|
|
1919
1986
|
* Reverse proxies in front of the server whose X-Forwarded-For entries name the client, for the
|
|
1920
1987
|
* rate limits on what anyone may ask without a token: 0 when clients connect directly.
|
|
1921
1988
|
*/
|
|
1922
|
-
trustedProxies:
|
|
1989
|
+
trustedProxies: z13.number().int().min(0).max(16)
|
|
1923
1990
|
});
|
|
1924
|
-
var RunnerConfigSchema =
|
|
1991
|
+
var RunnerConfigSchema = z13.object({
|
|
1925
1992
|
/** The board server, for example http://127.0.0.1:4700. */
|
|
1926
|
-
serverUrl:
|
|
1993
|
+
serverUrl: z13.string().url(),
|
|
1927
1994
|
/**
|
|
1928
1995
|
* The runner's token, from `runner add`, or null for the one it saved when it was enrolled, or
|
|
1929
1996
|
* to enroll it.
|
|
1930
1997
|
*/
|
|
1931
|
-
token:
|
|
1998
|
+
token: z13.string().min(1).nullable(),
|
|
1932
1999
|
/** The runner's own data directory: the board mirror, agent homes, repositories, worktrees. */
|
|
1933
|
-
dataDir:
|
|
2000
|
+
dataDir: z13.string().min(1),
|
|
1934
2001
|
logLevel: LogLevelSchema,
|
|
1935
2002
|
/** Turns this machine runs at once, or null for no limit. */
|
|
1936
|
-
slots:
|
|
1937
|
-
clis:
|
|
1938
|
-
capabilities:
|
|
2003
|
+
slots: z13.number().int().positive().nullable(),
|
|
2004
|
+
clis: z13.array(CliKindSchema).min(1),
|
|
2005
|
+
capabilities: z13.array(z13.string())
|
|
1939
2006
|
});
|
|
1940
2007
|
|
|
1941
2008
|
// packages/shared/dist/version.js
|
|
1942
|
-
var STELLARIS_VERSION = "0.3.
|
|
2009
|
+
var STELLARIS_VERSION = "0.3.23";
|
|
1943
2010
|
|
|
1944
2011
|
// packages/shared/dist/mentions.js
|
|
1945
2012
|
import { parse, postprocess, preprocess } from "micromark";
|
|
@@ -2657,32 +2724,32 @@ function postMentions(body) {
|
|
|
2657
2724
|
}
|
|
2658
2725
|
|
|
2659
2726
|
// packages/board-core/dist/metrics.js
|
|
2660
|
-
import { z as
|
|
2661
|
-
var TurnPayload =
|
|
2662
|
-
turnId:
|
|
2663
|
-
project:
|
|
2664
|
-
thread:
|
|
2665
|
-
channel:
|
|
2666
|
-
trigger:
|
|
2667
|
-
});
|
|
2668
|
-
var TaskPayload =
|
|
2669
|
-
taskId:
|
|
2670
|
-
project:
|
|
2671
|
-
from:
|
|
2672
|
-
});
|
|
2673
|
-
var MessagePayload =
|
|
2674
|
-
id:
|
|
2675
|
-
channel:
|
|
2676
|
-
thread:
|
|
2677
|
-
mentions:
|
|
2678
|
-
});
|
|
2679
|
-
var SteeredPayload =
|
|
2680
|
-
var SignalPayload =
|
|
2681
|
-
kind:
|
|
2682
|
-
key:
|
|
2683
|
-
summary:
|
|
2684
|
-
taskId:
|
|
2685
|
-
project:
|
|
2727
|
+
import { z as z14 } from "zod";
|
|
2728
|
+
var TurnPayload = z14.object({
|
|
2729
|
+
turnId: z14.string().optional(),
|
|
2730
|
+
project: z14.string(),
|
|
2731
|
+
thread: z14.string().optional(),
|
|
2732
|
+
channel: z14.string().optional(),
|
|
2733
|
+
trigger: z14.string()
|
|
2734
|
+
});
|
|
2735
|
+
var TaskPayload = z14.object({
|
|
2736
|
+
taskId: z14.string(),
|
|
2737
|
+
project: z14.string(),
|
|
2738
|
+
from: z14.string().optional()
|
|
2739
|
+
});
|
|
2740
|
+
var MessagePayload = z14.object({
|
|
2741
|
+
id: z14.string().optional(),
|
|
2742
|
+
channel: z14.string(),
|
|
2743
|
+
thread: z14.string().nullable().optional(),
|
|
2744
|
+
mentions: z14.array(z14.string()).default([])
|
|
2745
|
+
});
|
|
2746
|
+
var SteeredPayload = z14.object({ messages: z14.array(z14.string()) });
|
|
2747
|
+
var SignalPayload = z14.object({
|
|
2748
|
+
kind: z14.string(),
|
|
2749
|
+
key: z14.string(),
|
|
2750
|
+
summary: z14.string(),
|
|
2751
|
+
taskId: z14.string().optional(),
|
|
2752
|
+
project: z14.string().optional()
|
|
2686
2753
|
});
|
|
2687
2754
|
function median(values) {
|
|
2688
2755
|
const sorted = values.toSorted((a, b) => a - b);
|
|
@@ -2972,19 +3039,19 @@ function computeMetrics(input) {
|
|
|
2972
3039
|
}
|
|
2973
3040
|
|
|
2974
3041
|
// packages/board-core/dist/turn-history.js
|
|
2975
|
-
import { z as
|
|
2976
|
-
var TurnHistoryPayloadSchema =
|
|
3042
|
+
import { z as z15 } from "zod";
|
|
3043
|
+
var TurnHistoryPayloadSchema = z15.object({
|
|
2977
3044
|
project: NameSchema,
|
|
2978
3045
|
thread: UlidSchema.optional(),
|
|
2979
3046
|
channel: NameSchema.optional(),
|
|
2980
|
-
trigger:
|
|
2981
|
-
exitReason:
|
|
2982
|
-
costUsd:
|
|
3047
|
+
trigger: z15.string().default("manual"),
|
|
3048
|
+
exitReason: z15.string().nullable().default(null),
|
|
3049
|
+
costUsd: z15.number().default(0),
|
|
2983
3050
|
usage: UsageSchema.optional(),
|
|
2984
|
-
model:
|
|
2985
|
-
summary:
|
|
2986
|
-
error:
|
|
2987
|
-
toolCalls:
|
|
3051
|
+
model: z15.string().nullable().default(null),
|
|
3052
|
+
summary: z15.string().nullable().default(null),
|
|
3053
|
+
error: z15.string().nullable().default(null),
|
|
3054
|
+
toolCalls: z15.number().int().nonnegative().optional(),
|
|
2988
3055
|
turnId: UlidSchema.optional()
|
|
2989
3056
|
});
|
|
2990
3057
|
function tokenUse(events, window, now) {
|
|
@@ -3230,6 +3297,13 @@ var BoardPaths = class {
|
|
|
3230
3297
|
eventLog() {
|
|
3231
3298
|
return path5.join(this.events(), "log.jsonl");
|
|
3232
3299
|
}
|
|
3300
|
+
/** Images citizens uploaded, by id: outside the projection, which every runner mirrors. */
|
|
3301
|
+
images() {
|
|
3302
|
+
return path5.join(this.dataDir, "images");
|
|
3303
|
+
}
|
|
3304
|
+
image(id) {
|
|
3305
|
+
return path5.join(this.images(), id);
|
|
3306
|
+
}
|
|
3233
3307
|
state() {
|
|
3234
3308
|
return path5.join(this.dataDir, "state");
|
|
3235
3309
|
}
|
|
@@ -3265,27 +3339,27 @@ function namesList(names) {
|
|
|
3265
3339
|
return names.length <= 1 ? names[0] ?? "" : `${names.slice(0, -1).join(", ")} and ${names.at(-1) ?? ""}`;
|
|
3266
3340
|
}
|
|
3267
3341
|
var SKIPPED_IN_HOME = /* @__PURE__ */ new Set([".git", "turns", ".claude", ".codex"]);
|
|
3268
|
-
var RunnerTokensSchema =
|
|
3269
|
-
runners:
|
|
3342
|
+
var RunnerTokensSchema = z16.object({
|
|
3343
|
+
runners: z16.record(z16.string(), z16.object({ tokenHash: z16.string().min(1) }))
|
|
3270
3344
|
});
|
|
3271
|
-
var SignInsSchema =
|
|
3272
|
-
signIns:
|
|
3273
|
-
tokenHash:
|
|
3274
|
-
login:
|
|
3345
|
+
var SignInsSchema = z16.object({
|
|
3346
|
+
signIns: z16.array(z16.object({
|
|
3347
|
+
tokenHash: z16.string().min(1),
|
|
3348
|
+
login: z16.string().min(1),
|
|
3275
3349
|
/** The account's picture at the identity provider; sign-ins from before it have none. */
|
|
3276
|
-
avatarUrl:
|
|
3350
|
+
avatarUrl: z16.url().optional(),
|
|
3277
3351
|
createdAt: IsoDateTimeSchema,
|
|
3278
3352
|
expiresAt: IsoDateTimeSchema
|
|
3279
3353
|
})).default([])
|
|
3280
3354
|
});
|
|
3281
|
-
var TurnStartPayloadSchema =
|
|
3282
|
-
var CursorsSchema =
|
|
3283
|
-
digest:
|
|
3284
|
-
scopes:
|
|
3285
|
-
threadsFrom:
|
|
3286
|
-
channelsFrom:
|
|
3355
|
+
var TurnStartPayloadSchema = z16.object({ project: NameSchema, turnId: UlidSchema.optional() });
|
|
3356
|
+
var CursorsSchema = z16.object({
|
|
3357
|
+
digest: z16.string().nullable(),
|
|
3358
|
+
scopes: z16.record(z16.string(), z16.string()).default({}),
|
|
3359
|
+
threadsFrom: z16.record(z16.string(), z16.string().nullable()).default({}),
|
|
3360
|
+
channelsFrom: z16.record(z16.string(), z16.string().nullable()).default({}),
|
|
3287
3361
|
/** How far a work role has read news, which goes to whichever of its general conversations reads first. */
|
|
3288
|
-
news:
|
|
3362
|
+
news: z16.string().optional()
|
|
3289
3363
|
});
|
|
3290
3364
|
var NO_CURSORS = { digest: null, scopes: {}, threadsFrom: {}, channelsFrom: {} };
|
|
3291
3365
|
function conversationKey(scope, part) {
|
|
@@ -3324,7 +3398,7 @@ function byId(a, b) {
|
|
|
3324
3398
|
function turnTime(record) {
|
|
3325
3399
|
return record.endedAt ?? record.startedAt;
|
|
3326
3400
|
}
|
|
3327
|
-
var PausedSchema =
|
|
3401
|
+
var PausedSchema = z16.object({ paused: z16.boolean() });
|
|
3328
3402
|
var DEFAULT_LEASE_MS = 30 * 60 * 1e3;
|
|
3329
3403
|
function withoutMentions(text) {
|
|
3330
3404
|
return text.replaceAll(MENTION_PATTERN, "$1$2");
|
|
@@ -3349,7 +3423,7 @@ var OPS_WAKE_TRIGGER = "ops_event";
|
|
|
3349
3423
|
var FRONT_DESK_TRIGGER = "user_post";
|
|
3350
3424
|
var OPS_CHANNELS = ["governance"];
|
|
3351
3425
|
var FRONT_DESK_CHANNELS = [ASK_CHANNEL];
|
|
3352
|
-
var AlignmentsSchema =
|
|
3426
|
+
var AlignmentsSchema = z16.object({ applied: z16.array(z16.string()).default([]) });
|
|
3353
3427
|
var FOLLOW_DECISIONS = "ops-readers-follow-decisions";
|
|
3354
3428
|
var THREAD_RECORDS = "threads-as-records";
|
|
3355
3429
|
var DIGEST_CURSORS = "digest-replaces-inbox";
|
|
@@ -3363,10 +3437,11 @@ var CHANNEL_CONVERSATIONS = "channel-conversations";
|
|
|
3363
3437
|
var DASHBOARD_UPDATES = "dashboard-updates-granted";
|
|
3364
3438
|
var CRON_VERBS = "cron-verbs-granted";
|
|
3365
3439
|
var KNOWLEDGE_NOTICES = "knowledge-notices";
|
|
3366
|
-
var
|
|
3440
|
+
var IMAGE_UPLOADS = "image-uploads-granted";
|
|
3441
|
+
var KnowledgeEventSchema = z16.object({
|
|
3367
3442
|
topic: NameSchema,
|
|
3368
3443
|
project: NameSchema.nullable(),
|
|
3369
|
-
replaced:
|
|
3444
|
+
replaced: z16.boolean().optional()
|
|
3370
3445
|
});
|
|
3371
3446
|
var CRON_VERB_NAMES = ["create_cron", "update_cron", "remove_cron"];
|
|
3372
3447
|
var OLD_DASHBOARD_LINE = "Agents may edit this file. It is rendered by the board UI.";
|
|
@@ -3498,6 +3573,7 @@ var Board = class _Board {
|
|
|
3498
3573
|
mutex = new Mutex();
|
|
3499
3574
|
/** The turns in flight, which the server hosting them supplies; none until it does. */
|
|
3500
3575
|
turnsInFlight = () => [];
|
|
3576
|
+
imageSource = null;
|
|
3501
3577
|
newId = monotonicFactory();
|
|
3502
3578
|
events;
|
|
3503
3579
|
actionCounts = /* @__PURE__ */ new Map();
|
|
@@ -3562,7 +3638,8 @@ var Board = class _Board {
|
|
|
3562
3638
|
CHANNEL_CONVERSATIONS,
|
|
3563
3639
|
DASHBOARD_UPDATES,
|
|
3564
3640
|
CRON_VERBS,
|
|
3565
|
-
KNOWLEDGE_NOTICES
|
|
3641
|
+
KNOWLEDGE_NOTICES,
|
|
3642
|
+
IMAGE_UPLOADS
|
|
3566
3643
|
].filter((name) => !applied.includes(name));
|
|
3567
3644
|
if (pending.length === 0) {
|
|
3568
3645
|
return;
|
|
@@ -3592,13 +3669,13 @@ var Board = class _Board {
|
|
|
3592
3669
|
await this.openAsksChannel();
|
|
3593
3670
|
}
|
|
3594
3671
|
if (pending.includes(KNOWLEDGE_REMOVAL)) {
|
|
3595
|
-
await this.
|
|
3672
|
+
await this.grantBeside("write_knowledge", "remove_knowledge");
|
|
3596
3673
|
}
|
|
3597
3674
|
if (pending.includes(CHANNEL_CONVERSATIONS)) {
|
|
3598
3675
|
await this.startChannelCursors();
|
|
3599
3676
|
}
|
|
3600
3677
|
if (pending.includes(DASHBOARD_UPDATES)) {
|
|
3601
|
-
await this.
|
|
3678
|
+
await this.grantBeside("write_knowledge", "update_dashboard");
|
|
3602
3679
|
await this.rewordDashboards();
|
|
3603
3680
|
}
|
|
3604
3681
|
if (pending.includes(CRON_VERBS)) {
|
|
@@ -3607,6 +3684,9 @@ var Board = class _Board {
|
|
|
3607
3684
|
if (pending.includes(KNOWLEDGE_NOTICES)) {
|
|
3608
3685
|
await this.noticeKnowledgeNotes();
|
|
3609
3686
|
}
|
|
3687
|
+
if (pending.includes(IMAGE_UPLOADS)) {
|
|
3688
|
+
await this.grantBeside("post_message", "upload_image");
|
|
3689
|
+
}
|
|
3610
3690
|
await writeJson(file, { applied: [...applied, ...pending] });
|
|
3611
3691
|
}
|
|
3612
3692
|
/**
|
|
@@ -3648,12 +3728,12 @@ var Board = class _Board {
|
|
|
3648
3728
|
}
|
|
3649
3729
|
}
|
|
3650
3730
|
/**
|
|
3651
|
-
* Grants `verb` once to every charter granting `
|
|
3652
|
-
*
|
|
3731
|
+
* Grants `verb` once to every charter granting `beside`, the work roles' charters in practice;
|
|
3732
|
+
* seed roles have it from their seed.
|
|
3653
3733
|
*/
|
|
3654
|
-
async
|
|
3734
|
+
async grantBeside(beside, verb) {
|
|
3655
3735
|
for (const charter of await this.listRoles()) {
|
|
3656
|
-
if (charter.verbs.includes(
|
|
3736
|
+
if (charter.verbs.includes(beside) && !charter.verbs.includes(verb)) {
|
|
3657
3737
|
await this.writeRoleUnlocked(USER_NAME, { ...charter, verbs: [...charter.verbs, verb] }, { verbsAdded: [verb] });
|
|
3658
3738
|
}
|
|
3659
3739
|
}
|
|
@@ -3811,7 +3891,7 @@ var Board = class _Board {
|
|
|
3811
3891
|
}
|
|
3812
3892
|
}
|
|
3813
3893
|
for (const file of await listFiles(this.paths.tasks(slug))) {
|
|
3814
|
-
const raw = await readMarkdown(path6.join(this.paths.tasks(slug), file),
|
|
3894
|
+
const raw = await readMarkdown(path6.join(this.paths.tasks(slug), file), z16.record(z16.string(), z16.unknown()));
|
|
3815
3895
|
const legacy = raw.data["thread"];
|
|
3816
3896
|
if (legacy === void 0) {
|
|
3817
3897
|
continue;
|
|
@@ -3889,7 +3969,7 @@ var Board = class _Board {
|
|
|
3889
3969
|
* turns, so it follows nothing now.
|
|
3890
3970
|
*/
|
|
3891
3971
|
async renameInboxCursors() {
|
|
3892
|
-
const Legacy =
|
|
3972
|
+
const Legacy = z16.object({ inbox: z16.string().nullable() });
|
|
3893
3973
|
for (const agent2 of await this.listAgents()) {
|
|
3894
3974
|
const file = this.paths.agentCursors(agent2.name);
|
|
3895
3975
|
if (await exists(file)) {
|
|
@@ -3935,7 +4015,7 @@ ${charter.purpose}
|
|
|
3935
4015
|
*/
|
|
3936
4016
|
async alignSeedRole(seed) {
|
|
3937
4017
|
const file = this.paths.role(seed.name);
|
|
3938
|
-
const raw = await readMarkdown(file,
|
|
4018
|
+
const raw = await readMarkdown(file, z16.record(z16.string(), z16.unknown()));
|
|
3939
4019
|
const current = RoleCharterSchema.parse(raw.data);
|
|
3940
4020
|
const verbsAdded = seed.verbs.filter((verb) => !current.verbs.includes(verb));
|
|
3941
4021
|
const fieldsAligned = RoleCharterSchema.keyof().options.filter((key) => key === "verbs" || seed[key] === void 0 ? false : seed.name === USER_ROLE ? JSON.stringify(seed[key]) !== JSON.stringify(current[key]) : !(key in raw.data));
|
|
@@ -4252,7 +4332,7 @@ ${charter.purpose}
|
|
|
4252
4332
|
/** The society's norms, the one knowledge topic every turn loads. Empty until the steward writes it. */
|
|
4253
4333
|
async readSocietyNorms() {
|
|
4254
4334
|
const file = this.paths.societyKnowledgeFile("norms");
|
|
4255
|
-
return await exists(file) ? (await readMarkdown(file,
|
|
4335
|
+
return await exists(file) ? (await readMarkdown(file, z16.record(z16.string(), z16.unknown()))).body : "";
|
|
4256
4336
|
}
|
|
4257
4337
|
/** Knowledge topics of a project, or of the society when the project is null. */
|
|
4258
4338
|
async listKnowledge(project2) {
|
|
@@ -4272,7 +4352,7 @@ ${charter.purpose}
|
|
|
4272
4352
|
*/
|
|
4273
4353
|
async knowledgeAt(file, project2, topic) {
|
|
4274
4354
|
const { data, body } = await readLooseMarkdown(file);
|
|
4275
|
-
const revision =
|
|
4355
|
+
const revision = z16.number().int().min(0).safeParse(data["revision"]);
|
|
4276
4356
|
const updatedBy = NameSchema.safeParse(data["updatedBy"]);
|
|
4277
4357
|
const updatedAt = IsoDateTimeSchema.safeParse(data["updatedAt"]);
|
|
4278
4358
|
return {
|
|
@@ -5235,6 +5315,60 @@ ${current.body}`);
|
|
|
5235
5315
|
return updated;
|
|
5236
5316
|
});
|
|
5237
5317
|
}
|
|
5318
|
+
/**
|
|
5319
|
+
* Keeps an image a citizen's turn names by its path, read on the runner the turn runs on, which
|
|
5320
|
+
* refuses a file outside the turn's worktree, the citizen's home, and the system temp folder.
|
|
5321
|
+
* Only the bytes of a PNG, JPEG, GIF, or WebP of at most `IMAGE_LIMIT_BYTES` are kept, checked
|
|
5322
|
+
* here again whatever the runner said, under a new id outside the projection, so no runner
|
|
5323
|
+
* mirrors them and no prompt carries them: a post shows the image by its `image:` address.
|
|
5324
|
+
*/
|
|
5325
|
+
async uploadImage(actor, input) {
|
|
5326
|
+
const args = VerbInputs.upload_image.parse(input);
|
|
5327
|
+
await this.authorize(actor, "upload_image");
|
|
5328
|
+
if (actor.scope === void 0) {
|
|
5329
|
+
throw new BoardError("INVALID_STATE", "upload_image reads the file on the machine a turn runs on, so only a turn can call it");
|
|
5330
|
+
}
|
|
5331
|
+
if (this.imageSource === null) {
|
|
5332
|
+
throw new BoardError("NOT_FOUND", "this board has no runners to read an image from");
|
|
5333
|
+
}
|
|
5334
|
+
const bytes = await this.imageSource(actor, args.path);
|
|
5335
|
+
const type = imageTypeOf(bytes);
|
|
5336
|
+
if (type === null) {
|
|
5337
|
+
throw new BoardError("VALIDATION", `${args.path} is not a PNG, JPEG, GIF, or WebP image by its first bytes`);
|
|
5338
|
+
}
|
|
5339
|
+
if (bytes.byteLength > IMAGE_LIMIT_BYTES) {
|
|
5340
|
+
throw new BoardError("VALIDATION", `${args.path} is ${bytes.byteLength} bytes, over the ${IMAGE_LIMIT_BYTES} an image may be`);
|
|
5341
|
+
}
|
|
5342
|
+
return this.mutex.run(async () => {
|
|
5343
|
+
const id = this.newId();
|
|
5344
|
+
await writeFileAtomic(this.paths.image(id), bytes);
|
|
5345
|
+
await this.events.append("image.uploaded", actor.name, {
|
|
5346
|
+
id,
|
|
5347
|
+
type,
|
|
5348
|
+
size: bytes.byteLength
|
|
5349
|
+
});
|
|
5350
|
+
const name = path6.basename(args.path).replaceAll(/[[\]\\\r\n]/g, "");
|
|
5351
|
+
return {
|
|
5352
|
+
id,
|
|
5353
|
+
type,
|
|
5354
|
+
size: bytes.byteLength,
|
|
5355
|
+
markdown: ``
|
|
5356
|
+
};
|
|
5357
|
+
});
|
|
5358
|
+
}
|
|
5359
|
+
/** An uploaded image's bytes and kind, which its first bytes tell. */
|
|
5360
|
+
async readImage(id) {
|
|
5361
|
+
const file = this.paths.image(UlidSchema.parse(id));
|
|
5362
|
+
if (!await exists(file)) {
|
|
5363
|
+
throw new BoardError("NOT_FOUND", `image ${id} not found`);
|
|
5364
|
+
}
|
|
5365
|
+
const bytes = await readFile4(file);
|
|
5366
|
+
const type = imageTypeOf(bytes);
|
|
5367
|
+
if (type === null) {
|
|
5368
|
+
throw new BoardError("NOT_FOUND", `image ${id} is not an image the board shows`);
|
|
5369
|
+
}
|
|
5370
|
+
return { type, bytes };
|
|
5371
|
+
}
|
|
5238
5372
|
/** Every cron, ended ones included, oldest first. */
|
|
5239
5373
|
async listCrons() {
|
|
5240
5374
|
const crons = [];
|
|
@@ -5626,6 +5760,13 @@ ${current.body}`);
|
|
|
5626
5760
|
watchTurns(source) {
|
|
5627
5761
|
this.turnsInFlight = source;
|
|
5628
5762
|
}
|
|
5763
|
+
/**
|
|
5764
|
+
* Where `upload_image` reads a file from: the runner the calling turn runs on, through the server
|
|
5765
|
+
* that hosts the runners. Without one, as in the admin CLI, nothing can be uploaded.
|
|
5766
|
+
*/
|
|
5767
|
+
readImagesWith(source) {
|
|
5768
|
+
this.imageSource = source;
|
|
5769
|
+
}
|
|
5629
5770
|
/**
|
|
5630
5771
|
* Refuses to end conversations while another citizen's turn is in one of them: `cut` picks the
|
|
5631
5772
|
* turns that would lose theirs. The caller's own turn is exempt, since ending a conversation
|
|
@@ -6455,6 +6596,8 @@ ${rationale}`}`);
|
|
|
6455
6596
|
return this.updateCron(actor, VerbInputs.update_cron.parse(input));
|
|
6456
6597
|
case "remove_cron":
|
|
6457
6598
|
return this.removeCron(actor, VerbInputs.remove_cron.parse(input));
|
|
6599
|
+
case "upload_image":
|
|
6600
|
+
return this.uploadImage(actor, VerbInputs.upload_image.parse(input));
|
|
6458
6601
|
default:
|
|
6459
6602
|
throw new BoardError("VALIDATION", `unknown verb ${String(verb)}`);
|
|
6460
6603
|
}
|
|
@@ -6501,7 +6644,7 @@ ${rationale}`}`);
|
|
|
6501
6644
|
}
|
|
6502
6645
|
async readAgentRoleBody(agent2) {
|
|
6503
6646
|
const file = this.paths.agentRole(agent2);
|
|
6504
|
-
return await exists(file) ? (await readMarkdown(file,
|
|
6647
|
+
return await exists(file) ? (await readMarkdown(file, z16.record(z16.string(), z16.unknown()))).body : "";
|
|
6505
6648
|
}
|
|
6506
6649
|
/** The steps of one finished turn, as the runner handed them over when it ended. */
|
|
6507
6650
|
/**
|
|
@@ -6909,7 +7052,7 @@ ${rationale}`}`);
|
|
|
6909
7052
|
return { project: slug, revision: 0, body: "" };
|
|
6910
7053
|
}
|
|
6911
7054
|
const { data, body } = await readLooseMarkdown(file);
|
|
6912
|
-
const revision =
|
|
7055
|
+
const revision = z16.number().int().min(0).safeParse(data["revision"]);
|
|
6913
7056
|
const updatedBy = NameSchema.safeParse(data["updatedBy"]);
|
|
6914
7057
|
const updatedAt = IsoDateTimeSchema.safeParse(data["updatedAt"]);
|
|
6915
7058
|
return {
|
|
@@ -7183,7 +7326,7 @@ ${charter.purpose}
|
|
|
7183
7326
|
|
|
7184
7327
|
${charter.purpose}
|
|
7185
7328
|
|
|
7186
|
-
Route every lesson with one question: about me, my craft, or the user, it goes in memory/core.md; about this codebase, it goes in the project's knowledge
|
|
7329
|
+
Route every lesson with one question: about me, my craft, or the user, it goes in memory/core.md; about how this codebase behaves, it goes in the repo's AGENTS.md or README; about this project as a place (runners, access, flow, where results live), it goes in the project's knowledge; something everyone should know, post it.
|
|
7187
7330
|
` + (seed.length === 0 ? "" : `
|
|
7188
7331
|
${SEED_INSTRUCTIONS_HEADING}
|
|
7189
7332
|
|
|
@@ -7200,7 +7343,7 @@ ${seed}
|
|
|
7200
7343
|
continue;
|
|
7201
7344
|
}
|
|
7202
7345
|
const file = this.paths.agentRole(agent2.name);
|
|
7203
|
-
const body = await exists(file) ? (await readMarkdown(file,
|
|
7346
|
+
const body = await exists(file) ? (await readMarkdown(file, z16.record(z16.string(), z16.unknown()))).body : "";
|
|
7204
7347
|
const at = body.indexOf(`
|
|
7205
7348
|
${SEED_INSTRUCTIONS_HEADING}
|
|
7206
7349
|
`);
|