@herdingchats/friday 0.1.541 → 0.1.547
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/herd.mjs +523 -518
- package/package.json +2 -2
package/herd.mjs
CHANGED
|
@@ -18,12 +18,12 @@ var __export = (target, all) => {
|
|
|
18
18
|
var define_HERD_PACKAGE_default;
|
|
19
19
|
var init_define_HERD_PACKAGE = __esm({
|
|
20
20
|
"<define:HERD_PACKAGE>"() {
|
|
21
|
-
define_HERD_PACKAGE_default = { version: "0.1.
|
|
21
|
+
define_HERD_PACKAGE_default = { version: "0.1.547", gitHead: "2bb0029716f49d8ffbe45379ba4c6b9a40de4359" };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// ../common-chat/src/activation.ts
|
|
26
|
-
import { z
|
|
26
|
+
import { z } from "zod";
|
|
27
27
|
function activationText(agent, activation) {
|
|
28
28
|
if (!activation || activation.state === "activated") return "activated";
|
|
29
29
|
if (activation.state === "waiting") {
|
|
@@ -45,8 +45,8 @@ var init_activation = __esm({
|
|
|
45
45
|
"../common-chat/src/activation.ts"() {
|
|
46
46
|
"use strict";
|
|
47
47
|
init_define_HERD_PACKAGE();
|
|
48
|
-
time =
|
|
49
|
-
activationFailureSchema =
|
|
48
|
+
time = z.number().int().nonnegative();
|
|
49
|
+
activationFailureSchema = z.enum([
|
|
50
50
|
// The agent showed its own sign-in, and nobody finished it in time.
|
|
51
51
|
"signed_out",
|
|
52
52
|
// A screen herd doesn't know was in the way.
|
|
@@ -56,11 +56,11 @@ var init_activation = __esm({
|
|
|
56
56
|
// It didn't start in its terminal at all.
|
|
57
57
|
"didnt_start"
|
|
58
58
|
]);
|
|
59
|
-
agentActivationSchema =
|
|
60
|
-
state:
|
|
61
|
-
version:
|
|
59
|
+
agentActivationSchema = z.object({
|
|
60
|
+
state: z.enum(["activated", "waiting", "failed"]),
|
|
61
|
+
version: z.string().min(1).max(100),
|
|
62
62
|
at: time,
|
|
63
|
-
signingIn:
|
|
63
|
+
signingIn: z.boolean().optional(),
|
|
64
64
|
reason: activationFailureSchema.optional()
|
|
65
65
|
});
|
|
66
66
|
activationSignedOut = (activation) => Boolean(
|
|
@@ -71,34 +71,34 @@ var init_activation = __esm({
|
|
|
71
71
|
codex: "codex",
|
|
72
72
|
agy: "agy"
|
|
73
73
|
};
|
|
74
|
-
gitHubCliSchema =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
gitHubCliSchema = z.discriminatedUnion("state", [
|
|
75
|
+
z.object({ state: z.literal("signed_in"), login: z.string().min(1).max(100), checkedAt: time }),
|
|
76
|
+
z.object({ state: z.literal("signed_out"), checkedAt: time }),
|
|
77
|
+
z.object({ state: z.literal("missing"), checkedAt: time })
|
|
78
78
|
]);
|
|
79
|
-
signInToolSchema =
|
|
79
|
+
signInToolSchema = z.enum(["gh"]);
|
|
80
80
|
GITHUB_DEVICE_URL = "https://github.com/login/device";
|
|
81
|
-
signInUpdateSchema =
|
|
82
|
-
|
|
83
|
-
state:
|
|
84
|
-
code:
|
|
85
|
-
url:
|
|
81
|
+
signInUpdateSchema = z.discriminatedUnion("state", [
|
|
82
|
+
z.object({
|
|
83
|
+
state: z.literal("code"),
|
|
84
|
+
code: z.string().regex(/^[A-Z0-9]{4}-[A-Z0-9]{4}$/),
|
|
85
|
+
url: z.literal(GITHUB_DEVICE_URL)
|
|
86
86
|
}),
|
|
87
|
-
|
|
87
|
+
z.object({ state: z.literal("signed_in"), login: z.string().min(1).max(100) }),
|
|
88
88
|
// `no_code`: it printed nothing herd recognizes. `not_signed_in`: it ended without signing in.
|
|
89
|
-
|
|
89
|
+
z.object({ state: z.literal("failed"), reason: z.enum(["no_code", "not_signed_in"]) })
|
|
90
90
|
]);
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
// ../common-chat/src/github-triggers.ts
|
|
95
|
-
import { z as
|
|
95
|
+
import { z as z2 } from "zod";
|
|
96
96
|
var nonEmpty, GITHUB_TRIGGER_KINDS, githubTriggerKindSchema, GITHUB_TRIGGER_LABELS, githubTriggerEventSchema;
|
|
97
97
|
var init_github_triggers = __esm({
|
|
98
98
|
"../common-chat/src/github-triggers.ts"() {
|
|
99
99
|
"use strict";
|
|
100
100
|
init_define_HERD_PACKAGE();
|
|
101
|
-
nonEmpty =
|
|
101
|
+
nonEmpty = z2.string().min(1);
|
|
102
102
|
GITHUB_TRIGGER_KINDS = [
|
|
103
103
|
"opened",
|
|
104
104
|
"review_requested",
|
|
@@ -107,7 +107,7 @@ var init_github_triggers = __esm({
|
|
|
107
107
|
"merged",
|
|
108
108
|
"mention"
|
|
109
109
|
];
|
|
110
|
-
githubTriggerKindSchema =
|
|
110
|
+
githubTriggerKindSchema = z2.enum(GITHUB_TRIGGER_KINDS);
|
|
111
111
|
GITHUB_TRIGGER_LABELS = {
|
|
112
112
|
opened: "Pull requests you open",
|
|
113
113
|
review_requested: "Review requests",
|
|
@@ -116,33 +116,33 @@ var init_github_triggers = __esm({
|
|
|
116
116
|
merged: "Your pull requests merged",
|
|
117
117
|
mention: "Mentions of you"
|
|
118
118
|
};
|
|
119
|
-
githubTriggerEventSchema =
|
|
119
|
+
githubTriggerEventSchema = z2.object({
|
|
120
120
|
/** The event, so each fires an automation once. */
|
|
121
121
|
key: nonEmpty,
|
|
122
122
|
kind: githubTriggerKindSchema,
|
|
123
|
-
repoId:
|
|
123
|
+
repoId: z2.number().int(),
|
|
124
124
|
/** `owner/name`. */
|
|
125
125
|
repo: nonEmpty,
|
|
126
|
-
number:
|
|
126
|
+
number: z2.number().int().positive(),
|
|
127
127
|
/** The pull request's link. */
|
|
128
|
-
url:
|
|
128
|
+
url: z2.url(),
|
|
129
129
|
/** Where the event itself is, such as the review or the comment. */
|
|
130
|
-
eventUrl:
|
|
130
|
+
eventUrl: z2.url().optional(),
|
|
131
131
|
/** The pull request's title, when the event says it. */
|
|
132
|
-
title:
|
|
132
|
+
title: z2.string().max(300).optional(),
|
|
133
133
|
/** Who caused it. */
|
|
134
134
|
by: nonEmpty,
|
|
135
135
|
/** For a review, its state: `approved`, `changes_requested` or `commented`. */
|
|
136
|
-
state:
|
|
137
|
-
private:
|
|
138
|
-
at:
|
|
136
|
+
state: z2.string().optional(),
|
|
137
|
+
private: z2.boolean(),
|
|
138
|
+
at: z2.number().int().nonnegative()
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
// ../common-chat/src/automations.ts
|
|
144
144
|
import { Cron } from "croner";
|
|
145
|
-
import { z as
|
|
145
|
+
import { z as z3 } from "zod";
|
|
146
146
|
function isTimeZone(timeZone) {
|
|
147
147
|
try {
|
|
148
148
|
new Intl.DateTimeFormat("en-US", { timeZone }).format(0);
|
|
@@ -212,56 +212,56 @@ var init_automations = __esm({
|
|
|
212
212
|
MIN_SCHEDULE_INTERVAL_MS = 15 * 60 * 1e3;
|
|
213
213
|
MAX_WEBHOOK_BODY = 64 * 1024;
|
|
214
214
|
MAX_ONCE_AHEAD_MS = 366 * 24 * 60 * 60 * 1e3;
|
|
215
|
-
nonEmpty2 =
|
|
215
|
+
nonEmpty2 = z3.string().trim().min(1);
|
|
216
216
|
timeZoneSchema = nonEmpty2.max(64).refine(isTimeZone, "That isn't a time zone. Use an IANA name, such as America/Los_Angeles.");
|
|
217
|
-
triggerSchema =
|
|
217
|
+
triggerSchema = z3.discriminatedUnion("kind", [
|
|
218
218
|
// A five-field cron expression, read in its time zone.
|
|
219
|
-
|
|
219
|
+
z3.object({ kind: z3.literal("cron"), cron: nonEmpty2.max(100), timeZone: timeZoneSchema }),
|
|
220
220
|
// A single instant, with the time zone it's described in.
|
|
221
|
-
|
|
221
|
+
z3.object({ kind: z3.literal("once"), at: z3.number().int().positive(), timeZone: timeZoneSchema }),
|
|
222
222
|
// A secret URL on the hooks hostname, which anything can post to.
|
|
223
|
-
|
|
223
|
+
z3.object({ kind: z3.literal("webhook") }),
|
|
224
224
|
// The owner's own GitHub events, of these kinds, and only in these repos when it names any.
|
|
225
225
|
// `unfollowed` keeps only pull requests none of the owner's conversations follow or made.
|
|
226
|
-
|
|
227
|
-
kind:
|
|
228
|
-
events:
|
|
229
|
-
unfollowed:
|
|
230
|
-
repos:
|
|
231
|
-
|
|
226
|
+
z3.object({
|
|
227
|
+
kind: z3.literal("github"),
|
|
228
|
+
events: z3.array(githubTriggerKindSchema).min(1).max(GITHUB_TRIGGER_KINDS.length),
|
|
229
|
+
unfollowed: z3.boolean().optional(),
|
|
230
|
+
repos: z3.array(
|
|
231
|
+
z3.string().trim().regex(/^[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}$/, "Name each repo as owner/name.")
|
|
232
232
|
).max(10).optional()
|
|
233
233
|
})
|
|
234
234
|
]);
|
|
235
235
|
triggerTimeZone = (trigger) => trigger.kind === "cron" || trigger.kind === "once" ? trigger.timeZone : "UTC";
|
|
236
|
-
targetInputSchema =
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
targetInputSchema = z3.discriminatedUnion("kind", [
|
|
237
|
+
z3.object({ kind: z3.literal("direct") }),
|
|
238
|
+
z3.object({ kind: z3.literal("channel"), channel: nonEmpty2.max(100) }),
|
|
239
|
+
z3.object({ kind: z3.literal("conversation"), conversationId: nonEmpty2.max(100) })
|
|
240
240
|
]);
|
|
241
|
-
targetSchema =
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
kind:
|
|
241
|
+
targetSchema = z3.discriminatedUnion("kind", [
|
|
242
|
+
z3.object({ kind: z3.literal("direct") }),
|
|
243
|
+
z3.object({
|
|
244
|
+
kind: z3.literal("channel"),
|
|
245
245
|
channel: nonEmpty2,
|
|
246
246
|
name: nonEmpty2,
|
|
247
|
-
isPrivate:
|
|
247
|
+
isPrivate: z3.boolean()
|
|
248
248
|
}),
|
|
249
|
-
|
|
249
|
+
z3.object({ kind: z3.literal("conversation"), conversationId: nonEmpty2 })
|
|
250
250
|
]);
|
|
251
251
|
MAX_AUTOMATION_REPOS = 10;
|
|
252
|
-
automationInputSchema =
|
|
252
|
+
automationInputSchema = z3.object({
|
|
253
253
|
name: nonEmpty2.max(80),
|
|
254
254
|
trigger: triggerSchema,
|
|
255
255
|
target: targetInputSchema,
|
|
256
256
|
instructions: nonEmpty2.max(MAX_INSTRUCTIONS),
|
|
257
257
|
// The repos each firing's conversation starts with, as hints. `repo` is the one-repo form from
|
|
258
258
|
// before automations could name several, read as a list of one.
|
|
259
|
-
repos:
|
|
259
|
+
repos: z3.array(nonEmpty2.max(300)).max(MAX_AUTOMATION_REPOS).optional(),
|
|
260
260
|
repo: nonEmpty2.max(300).nullable().optional()
|
|
261
261
|
});
|
|
262
262
|
automationChangeSchema = automationInputSchema.partial();
|
|
263
|
-
automationStateSchema =
|
|
264
|
-
firingOutcomeSchema =
|
|
263
|
+
automationStateSchema = z3.enum(["pending_approval", "active", "paused", "finished"]);
|
|
264
|
+
firingOutcomeSchema = z3.enum([
|
|
265
265
|
// Waiting to reach its conversation.
|
|
266
266
|
"pending",
|
|
267
267
|
"delivered",
|
|
@@ -275,7 +275,7 @@ var init_automations = __esm({
|
|
|
275
275
|
});
|
|
276
276
|
|
|
277
277
|
// ../common-chat/src/content.ts
|
|
278
|
-
import { z as
|
|
278
|
+
import { z as z4 } from "zod";
|
|
279
279
|
function exactlyOneBody(message, ctx) {
|
|
280
280
|
if (message.text === void 0 === (message.markdown === void 0)) {
|
|
281
281
|
ctx.addIssue({
|
|
@@ -306,80 +306,80 @@ var init_content = __esm({
|
|
|
306
306
|
MAX_FILES_PER_MESSAGE = 10;
|
|
307
307
|
MAX_FILE_BYTES = 100 * 1024 * 1024;
|
|
308
308
|
MAX_CONVERSATION_FILE_BYTES = 1024 * 1024 * 1024;
|
|
309
|
-
layoutPlatformSchema =
|
|
310
|
-
blockSchema =
|
|
311
|
-
blocksSchema =
|
|
309
|
+
layoutPlatformSchema = z4.enum(["slack"]);
|
|
310
|
+
blockSchema = z4.looseObject({ type: z4.string().min(1) });
|
|
311
|
+
blocksSchema = z4.array(blockSchema).min(1).max(MAX_LAYOUT_BLOCKS, `A message can have at most ${MAX_LAYOUT_BLOCKS} blocks.`).refine(
|
|
312
312
|
(blocks) => new TextEncoder().encode(JSON.stringify(blocks)).length <= MAX_LAYOUT_BYTES,
|
|
313
313
|
`Blocks can be at most ${MAX_LAYOUT_BYTES / 1e3} KB as JSON.`
|
|
314
314
|
);
|
|
315
|
-
layoutSchema =
|
|
315
|
+
layoutSchema = z4.strictObject({
|
|
316
316
|
platform: layoutPlatformSchema,
|
|
317
317
|
blocks: blocksSchema
|
|
318
318
|
});
|
|
319
|
-
textBody =
|
|
319
|
+
textBody = z4.string().max(
|
|
320
320
|
MAX_TEXT_LENGTH,
|
|
321
321
|
`Text can be at most ${MAX_TEXT_LENGTH.toLocaleString("en-US")} characters.`
|
|
322
322
|
).refine((text4) => text4.trim().length > 0, "The message is empty.");
|
|
323
|
-
markdownBody =
|
|
323
|
+
markdownBody = z4.string().max(
|
|
324
324
|
MAX_MARKDOWN_LENGTH,
|
|
325
325
|
`Markdown can be at most ${MAX_MARKDOWN_LENGTH.toLocaleString("en-US")} characters.`
|
|
326
326
|
).refine((text4) => text4.trim().length > 0, "The message is empty.");
|
|
327
|
-
title =
|
|
328
|
-
alt =
|
|
329
|
-
channelTargetSchema =
|
|
327
|
+
title = z4.string().trim().min(1).max(255);
|
|
328
|
+
alt = z4.string().trim().min(1).max(1e3);
|
|
329
|
+
channelTargetSchema = z4.string().trim().regex(/^(#[a-z0-9][a-z0-9._-]{0,79}|[CG][A-Z0-9]{2,})$/, {
|
|
330
330
|
message: "A channel is an ID such as C0123ABCD, or a name such as #eng."
|
|
331
331
|
});
|
|
332
|
-
herdMessageSchema =
|
|
332
|
+
herdMessageSchema = z4.strictObject({
|
|
333
333
|
text: textBody.optional(),
|
|
334
334
|
markdown: markdownBody.optional(),
|
|
335
335
|
blocks: blocksSchema.optional(),
|
|
336
|
-
files:
|
|
337
|
-
|
|
336
|
+
files: z4.array(
|
|
337
|
+
z4.strictObject({ path: z4.string().min(1), title: title.optional(), alt: alt.optional() })
|
|
338
338
|
).min(1).max(MAX_FILES_PER_MESSAGE, `A message can have at most ${MAX_FILES_PER_MESSAGE} files.`).optional(),
|
|
339
339
|
channel: channelTargetSchema.optional()
|
|
340
340
|
}).superRefine(exactlyOneBody);
|
|
341
|
-
sendMessageSchema =
|
|
341
|
+
sendMessageSchema = z4.strictObject({
|
|
342
342
|
text: textBody.optional(),
|
|
343
343
|
markdown: markdownBody.optional(),
|
|
344
344
|
layout: layoutSchema.optional(),
|
|
345
|
-
files:
|
|
346
|
-
|
|
347
|
-
id:
|
|
345
|
+
files: z4.array(
|
|
346
|
+
z4.strictObject({
|
|
347
|
+
id: z4.string().min(1).max(100),
|
|
348
348
|
title: title.optional(),
|
|
349
349
|
alt: alt.optional()
|
|
350
350
|
})
|
|
351
351
|
).min(1).max(MAX_FILES_PER_MESSAGE, `A message can have at most ${MAX_FILES_PER_MESSAGE} files.`).optional(),
|
|
352
352
|
channel: channelTargetSchema.optional(),
|
|
353
|
-
quiet:
|
|
353
|
+
quiet: z4.boolean().optional(),
|
|
354
354
|
// Which client an agent sent it through, such as "Claude Code", recorded on the message.
|
|
355
|
-
client:
|
|
355
|
+
client: z4.string().trim().min(1).max(40).regex(/^[^\r\n]+$/).optional()
|
|
356
356
|
}).superRefine(exactlyOneBody).superRefine((message, ctx) => {
|
|
357
357
|
if (message.quiet && message.channel) {
|
|
358
358
|
ctx.addIssue({ code: "custom", message: "A channel post can't be quiet.", path: ["quiet"] });
|
|
359
359
|
}
|
|
360
360
|
});
|
|
361
|
-
messageFileStateSchema =
|
|
362
|
-
messageFileSchema =
|
|
363
|
-
id:
|
|
364
|
-
name:
|
|
365
|
-
type:
|
|
366
|
-
size:
|
|
367
|
-
title:
|
|
368
|
-
alt:
|
|
361
|
+
messageFileStateSchema = z4.enum(["pending", "ready", "unavailable"]);
|
|
362
|
+
messageFileSchema = z4.object({
|
|
363
|
+
id: z4.string().min(1),
|
|
364
|
+
name: z4.string().min(1),
|
|
365
|
+
type: z4.string().min(1),
|
|
366
|
+
size: z4.number().int().nonnegative(),
|
|
367
|
+
title: z4.string().optional(),
|
|
368
|
+
alt: z4.string().optional(),
|
|
369
369
|
state: messageFileStateSchema.optional(),
|
|
370
370
|
// Why an `unavailable` file couldn't come in, for a person to read.
|
|
371
|
-
reason:
|
|
371
|
+
reason: z4.string().optional()
|
|
372
372
|
});
|
|
373
|
-
postTargetSchema =
|
|
374
|
-
place:
|
|
375
|
-
placeName:
|
|
376
|
-
conversationId:
|
|
373
|
+
postTargetSchema = z4.object({
|
|
374
|
+
place: z4.string().min(1),
|
|
375
|
+
placeName: z4.string().min(1),
|
|
376
|
+
conversationId: z4.string().min(1)
|
|
377
377
|
});
|
|
378
378
|
}
|
|
379
379
|
});
|
|
380
380
|
|
|
381
381
|
// ../common-chat/src/github.ts
|
|
382
|
-
import { z as
|
|
382
|
+
import { z as z5 } from "zod";
|
|
383
383
|
function parsePullRequestRef(text4) {
|
|
384
384
|
const trimmed = text4.trim();
|
|
385
385
|
const short = trimmed.match(new RegExp(`^(${NAME})/(${REPO})#(\\d{1,10})$`));
|
|
@@ -397,16 +397,16 @@ var init_github = __esm({
|
|
|
397
397
|
"../common-chat/src/github.ts"() {
|
|
398
398
|
"use strict";
|
|
399
399
|
init_define_HERD_PACKAGE();
|
|
400
|
-
nonEmpty3 =
|
|
400
|
+
nonEmpty3 = z5.string().min(1);
|
|
401
401
|
MAX_EXTERNAL_TEXT = 4e3;
|
|
402
|
-
subscriptionOriginSchema =
|
|
403
|
-
subscriptionEndSchema =
|
|
402
|
+
subscriptionOriginSchema = z5.enum(["watch", "branch", "work"]);
|
|
403
|
+
subscriptionEndSchema = z5.enum([
|
|
404
404
|
"resource_closed",
|
|
405
405
|
"unsubscribed",
|
|
406
406
|
"uninstalled",
|
|
407
407
|
"conversation_deleted"
|
|
408
408
|
]);
|
|
409
|
-
githubEventKindSchema =
|
|
409
|
+
githubEventKindSchema = z5.enum([
|
|
410
410
|
"pull_request",
|
|
411
411
|
"review",
|
|
412
412
|
"review_comment",
|
|
@@ -414,48 +414,48 @@ var init_github = __esm({
|
|
|
414
414
|
"comment",
|
|
415
415
|
"ci"
|
|
416
416
|
]);
|
|
417
|
-
githubSenderSchema =
|
|
418
|
-
id:
|
|
417
|
+
githubSenderSchema = z5.object({
|
|
418
|
+
id: z5.number().int(),
|
|
419
419
|
login: nonEmpty3,
|
|
420
|
-
association:
|
|
421
|
-
bot:
|
|
420
|
+
association: z5.string().optional(),
|
|
421
|
+
bot: z5.boolean()
|
|
422
422
|
});
|
|
423
|
-
githubEventSummarySchema =
|
|
423
|
+
githubEventSummarySchema = z5.object({
|
|
424
424
|
resource: nonEmpty3,
|
|
425
425
|
/** `owner/name#number`, for people. */
|
|
426
426
|
label: nonEmpty3,
|
|
427
427
|
kind: githubEventKindSchema,
|
|
428
428
|
action: nonEmpty3,
|
|
429
429
|
/** What it reports, such as `merged`, `changes_requested` or `failed`. */
|
|
430
|
-
state:
|
|
431
|
-
url:
|
|
430
|
+
state: z5.string().optional(),
|
|
431
|
+
url: z5.url(),
|
|
432
432
|
sender: githubSenderSchema,
|
|
433
433
|
/** A person's words, cut to `MAX_EXTERNAL_TEXT`. */
|
|
434
|
-
text:
|
|
435
|
-
sha:
|
|
434
|
+
text: z5.string().max(MAX_EXTERNAL_TEXT).optional(),
|
|
435
|
+
sha: z5.string().optional(),
|
|
436
436
|
/** For CI: the check or status that settled it, or failed first. */
|
|
437
|
-
check:
|
|
438
|
-
wakes:
|
|
437
|
+
check: z5.object({ name: nonEmpty3, conclusion: z5.string().optional() }).optional(),
|
|
438
|
+
wakes: z5.boolean(),
|
|
439
439
|
reason: nonEmpty3,
|
|
440
440
|
/** Set when its author isn't an owner, member or collaborator of the repo. */
|
|
441
|
-
outsider:
|
|
441
|
+
outsider: z5.boolean().optional(),
|
|
442
442
|
/** Set when its author is a GitHub account linked to the subscriber. */
|
|
443
|
-
own:
|
|
443
|
+
own: z5.boolean().optional(),
|
|
444
444
|
/**
|
|
445
445
|
* Whether its repo is private, and GitHub's numeric ID for the repo, so its words are shown only
|
|
446
446
|
* to people who can read it. A summary stored without `private` is treated as private.
|
|
447
447
|
*/
|
|
448
|
-
private:
|
|
449
|
-
repoId:
|
|
448
|
+
private: z5.boolean().optional(),
|
|
449
|
+
repoId: z5.number().int().optional(),
|
|
450
450
|
/** Set where a reader can't see the words of a private repo, which were taken out. */
|
|
451
|
-
withheld:
|
|
451
|
+
withheld: z5.boolean().optional()
|
|
452
452
|
});
|
|
453
|
-
subscriptionSchema =
|
|
453
|
+
subscriptionSchema = z5.object({
|
|
454
454
|
resource: nonEmpty3,
|
|
455
455
|
label: nonEmpty3,
|
|
456
|
-
url:
|
|
456
|
+
url: z5.url(),
|
|
457
457
|
createdBy: subscriptionOriginSchema,
|
|
458
|
-
createdAt:
|
|
458
|
+
createdAt: z5.number().int().nonnegative()
|
|
459
459
|
});
|
|
460
460
|
NAME = "[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})";
|
|
461
461
|
REPO = "[A-Za-z0-9._-]{1,100}";
|
|
@@ -463,7 +463,7 @@ var init_github = __esm({
|
|
|
463
463
|
});
|
|
464
464
|
|
|
465
465
|
// ../common-chat/src/usage.ts
|
|
466
|
-
import { z as
|
|
466
|
+
import { z as z6 } from "zod";
|
|
467
467
|
function currentUsage(usage, now) {
|
|
468
468
|
if (!usage) return void 0;
|
|
469
469
|
const fresh = (window) => window && window.resetsAt > now ? window : void 0;
|
|
@@ -481,38 +481,38 @@ var init_usage = __esm({
|
|
|
481
481
|
"../common-chat/src/usage.ts"() {
|
|
482
482
|
"use strict";
|
|
483
483
|
init_define_HERD_PACKAGE();
|
|
484
|
-
usageWindowSchema =
|
|
485
|
-
usedPercentage:
|
|
486
|
-
resetsAt:
|
|
484
|
+
usageWindowSchema = z6.object({
|
|
485
|
+
usedPercentage: z6.number().min(0).max(100),
|
|
486
|
+
resetsAt: z6.number().int().nonnegative()
|
|
487
487
|
});
|
|
488
488
|
USAGE_AGENTS = {
|
|
489
489
|
"claude-code": "Claude",
|
|
490
490
|
codex: "Codex",
|
|
491
491
|
agy: "Antigravity"
|
|
492
492
|
};
|
|
493
|
-
usageSchema =
|
|
493
|
+
usageSchema = z6.object({
|
|
494
494
|
fiveHour: usageWindowSchema.optional(),
|
|
495
495
|
sevenDay: usageWindowSchema.optional(),
|
|
496
|
-
agent:
|
|
496
|
+
agent: z6.enum(["claude-code", "codex", "agy"]).optional()
|
|
497
497
|
}).refine((usage) => usage.fiveHour || usage.sevenDay, "Usage needs at least one window");
|
|
498
498
|
MAX_ACTIVITY_LENGTH = 150;
|
|
499
|
-
activityTextSchema =
|
|
499
|
+
activityTextSchema = z6.string().trim().min(1).max(MAX_ACTIVITY_LENGTH).regex(/^[^\r\n]+$/);
|
|
500
500
|
MAX_TITLE_LENGTH = 40;
|
|
501
|
-
titleSchema =
|
|
502
|
-
listedWindowSchema =
|
|
501
|
+
titleSchema = z6.string().trim().min(1).max(MAX_TITLE_LENGTH).regex(/^[^\r\n]+$/);
|
|
502
|
+
listedWindowSchema = z6.union([
|
|
503
503
|
usageWindowSchema,
|
|
504
|
-
|
|
504
|
+
z6.object({ reset: z6.literal(true), resetsAt: z6.number().int().nonnegative() })
|
|
505
505
|
]);
|
|
506
|
-
listedUsageSchema =
|
|
506
|
+
listedUsageSchema = z6.object({
|
|
507
507
|
fiveHour: listedWindowSchema.optional(),
|
|
508
508
|
sevenDay: listedWindowSchema.optional(),
|
|
509
|
-
agent:
|
|
509
|
+
agent: z6.enum(["claude-code", "codex", "agy"]).optional()
|
|
510
510
|
});
|
|
511
511
|
}
|
|
512
512
|
});
|
|
513
513
|
|
|
514
514
|
// ../common-chat/src/workers.ts
|
|
515
|
-
import { z as
|
|
515
|
+
import { z as z7 } from "zod";
|
|
516
516
|
function agentShortName(cli) {
|
|
517
517
|
return AGENTS[cli]?.short ?? cli;
|
|
518
518
|
}
|
|
@@ -548,11 +548,11 @@ var init_workers = __esm({
|
|
|
548
548
|
"xcode",
|
|
549
549
|
"image_generation"
|
|
550
550
|
];
|
|
551
|
-
capabilitySchema =
|
|
551
|
+
capabilitySchema = z7.enum(CAPABILITIES);
|
|
552
552
|
PLATFORMS = ["macos", "linux", "windows"];
|
|
553
|
-
platformSchema =
|
|
553
|
+
platformSchema = z7.enum(PLATFORMS);
|
|
554
554
|
TOOLS = ["xcode", "gpu"];
|
|
555
|
-
toolSchema =
|
|
555
|
+
toolSchema = z7.enum(TOOLS);
|
|
556
556
|
CAPABILITY_WORDING = {
|
|
557
557
|
macos: "a Mac running macOS",
|
|
558
558
|
linux: "a Linux computer",
|
|
@@ -570,51 +570,51 @@ var init_workers = __esm({
|
|
|
570
570
|
PHRASE_MAX = 100;
|
|
571
571
|
PHRASES_MAX = 10;
|
|
572
572
|
ABOUT_MAX = 500;
|
|
573
|
-
phrase =
|
|
574
|
-
phrases =
|
|
573
|
+
phrase = z7.string().trim().min(1).max(PHRASE_MAX, `at most ${PHRASE_MAX} characters`);
|
|
574
|
+
phrases = z7.array(phrase).max(PHRASES_MAX, `at most ${PHRASES_MAX} phrases`);
|
|
575
575
|
SHARES = ["off", "little", "some", "lot"];
|
|
576
|
-
shareSchema =
|
|
576
|
+
shareSchema = z7.enum(SHARES);
|
|
577
577
|
SHARE_LABELS = {
|
|
578
578
|
off: "off",
|
|
579
579
|
little: "a little",
|
|
580
580
|
some: "some",
|
|
581
581
|
lot: "a lot"
|
|
582
582
|
};
|
|
583
|
-
harnessConfigSchema =
|
|
583
|
+
harnessConfigSchema = z7.object({
|
|
584
584
|
share: shareSchema.optional(),
|
|
585
585
|
/** Read as `share: "off"` when false, from files written before shares. */
|
|
586
|
-
enabled:
|
|
586
|
+
enabled: z7.boolean().optional(),
|
|
587
587
|
only: phrases.optional(),
|
|
588
588
|
great: phrases.optional(),
|
|
589
589
|
good: phrases.optional(),
|
|
590
590
|
okay: phrases.optional(),
|
|
591
591
|
cant: phrases.optional(),
|
|
592
592
|
/** false starts the harness's profile empty, rather than from herd's defaults. */
|
|
593
|
-
defaults:
|
|
593
|
+
defaults: z7.boolean().optional(),
|
|
594
594
|
/** Read as `great`, from files written before profiles. */
|
|
595
595
|
prefer: phrases.optional(),
|
|
596
596
|
/** Read as `cant`, from files written before profiles. */
|
|
597
597
|
avoid: phrases.optional(),
|
|
598
|
-
priority:
|
|
598
|
+
priority: z7.number().int().min(-100).max(100).optional()
|
|
599
599
|
}).strict();
|
|
600
600
|
BUILDS_MAX = 4;
|
|
601
|
-
buildsSettingSchema =
|
|
602
|
-
|
|
603
|
-
|
|
601
|
+
buildsSettingSchema = z7.union([
|
|
602
|
+
z7.literal(true),
|
|
603
|
+
z7.object({ max: z7.number().int().min(1).max(BUILDS_MAX) }).strict()
|
|
604
604
|
]);
|
|
605
605
|
CONFIG_REPOS_MAX = 50;
|
|
606
|
-
configRepoSchema =
|
|
607
|
-
remote:
|
|
608
|
-
about:
|
|
606
|
+
configRepoSchema = z7.object({
|
|
607
|
+
remote: z7.string().trim().min(1).max(300),
|
|
608
|
+
about: z7.string().trim().max(PHRASE_MAX, `at most ${PHRASE_MAX} characters`).optional()
|
|
609
609
|
}).strict();
|
|
610
|
-
herdConfigSchema =
|
|
611
|
-
about:
|
|
610
|
+
herdConfigSchema = z7.object({
|
|
611
|
+
about: z7.string().trim().max(ABOUT_MAX, `at most ${ABOUT_MAX} characters`).optional(),
|
|
612
612
|
cant: phrases.optional(),
|
|
613
613
|
/** Read as `cant`, from files written before profiles. */
|
|
614
614
|
avoid: phrases.optional(),
|
|
615
|
-
harnesses:
|
|
615
|
+
harnesses: z7.record(z7.string().regex(/^[a-z][a-z0-9-]*$/), harnessConfigSchema).optional(),
|
|
616
616
|
builds: buildsSettingSchema.optional(),
|
|
617
|
-
repos:
|
|
617
|
+
repos: z7.array(configRepoSchema).max(CONFIG_REPOS_MAX, `at most ${CONFIG_REPOS_MAX} repos`).optional()
|
|
618
618
|
}).strict();
|
|
619
619
|
HERD_CONFIG_TYPE = `type HerdConfig = {
|
|
620
620
|
/** What this machine is for, in plain words. At most ${ABOUT_MAX} characters. */
|
|
@@ -665,41 +665,41 @@ export default {
|
|
|
665
665
|
harnesses: { claude: { great: ["code review"] }, codex: { cant: ["the billing service"] } },
|
|
666
666
|
} satisfies HerdConfig;`;
|
|
667
667
|
PROFILE_LEVELS = ["great", "good", "okay", "cant"];
|
|
668
|
-
profileEntrySchema =
|
|
669
|
-
statement:
|
|
670
|
-
level:
|
|
671
|
-
source:
|
|
668
|
+
profileEntrySchema = z7.object({
|
|
669
|
+
statement: z7.string().min(1),
|
|
670
|
+
level: z7.enum(PROFILE_LEVELS),
|
|
671
|
+
source: z7.enum(["default", "owner"])
|
|
672
672
|
});
|
|
673
|
-
workerSchema =
|
|
674
|
-
key:
|
|
675
|
-
name:
|
|
676
|
-
machineId:
|
|
677
|
-
machineName:
|
|
678
|
-
agent:
|
|
679
|
-
capabilities:
|
|
680
|
-
about:
|
|
681
|
-
only:
|
|
673
|
+
workerSchema = z7.object({
|
|
674
|
+
key: z7.string().min(1),
|
|
675
|
+
name: z7.string().min(1),
|
|
676
|
+
machineId: z7.string().min(1),
|
|
677
|
+
machineName: z7.string().min(1),
|
|
678
|
+
agent: z7.string().min(1),
|
|
679
|
+
capabilities: z7.array(capabilitySchema),
|
|
680
|
+
about: z7.string().optional(),
|
|
681
|
+
only: z7.array(z7.string()),
|
|
682
682
|
/** What it's great, good and okay at, and can't do: its agent's defaults with its owner's word. */
|
|
683
|
-
profile:
|
|
684
|
-
priority:
|
|
683
|
+
profile: z7.array(profileEntrySchema),
|
|
684
|
+
priority: z7.number().int(),
|
|
685
685
|
/** How much of its agent its owner has. Servers from before shares send none, which is "some". */
|
|
686
686
|
share: shareSchema.default("some"),
|
|
687
|
-
enabled:
|
|
687
|
+
enabled: z7.boolean(),
|
|
688
688
|
/** Whether its agent checked in from herd's terminal on this version, so it's offered work. */
|
|
689
|
-
activated:
|
|
689
|
+
activated: z7.boolean(),
|
|
690
690
|
activation: agentActivationSchema.optional(),
|
|
691
|
-
online:
|
|
691
|
+
online: z7.boolean(),
|
|
692
692
|
// Its machine's repos, each marked whether herd has cloned it there. Older daemons send no `cloned`.
|
|
693
|
-
repos:
|
|
694
|
-
|
|
693
|
+
repos: z7.array(
|
|
694
|
+
z7.object({ name: z7.string(), remote: z7.string(), cloned: z7.boolean().optional() })
|
|
695
695
|
),
|
|
696
|
-
machineCreatedAt:
|
|
696
|
+
machineCreatedAt: z7.number().int().nonnegative()
|
|
697
697
|
});
|
|
698
698
|
}
|
|
699
699
|
});
|
|
700
700
|
|
|
701
701
|
// ../common-chat/src/machines.ts
|
|
702
|
-
import { z as
|
|
702
|
+
import { z as z8 } from "zod";
|
|
703
703
|
var nonEmpty4, time2, terminalStateSchema, agentStatusSchema, machineRepoSchema, isCloned, machineCliSchema, machineRegistrationSchema, machineSchema, machinePresenceSchema, worktreeSchema, MAX_REPO_HINTS, repoHintSchema, terminalSchema, offerSchema, offerAnswerSchema, dispatchFrameSchema, machineMessageSchema;
|
|
704
704
|
var init_machines = __esm({
|
|
705
705
|
"../common-chat/src/machines.ts"() {
|
|
@@ -708,9 +708,9 @@ var init_machines = __esm({
|
|
|
708
708
|
init_activation();
|
|
709
709
|
init_usage();
|
|
710
710
|
init_workers();
|
|
711
|
-
nonEmpty4 =
|
|
712
|
-
time2 =
|
|
713
|
-
terminalStateSchema =
|
|
711
|
+
nonEmpty4 = z8.string().min(1);
|
|
712
|
+
time2 = z8.number().int().nonnegative();
|
|
713
|
+
terminalStateSchema = z8.enum([
|
|
714
714
|
"working",
|
|
715
715
|
"idle",
|
|
716
716
|
"waiting_on_someone",
|
|
@@ -718,55 +718,55 @@ var init_machines = __esm({
|
|
|
718
718
|
"signed_out",
|
|
719
719
|
"unknown"
|
|
720
720
|
]);
|
|
721
|
-
agentStatusSchema =
|
|
722
|
-
machineRepoSchema =
|
|
721
|
+
agentStatusSchema = z8.enum(["working", "idle", "waiting_on_someone", "exited"]);
|
|
722
|
+
machineRepoSchema = z8.object({
|
|
723
723
|
name: nonEmpty4,
|
|
724
724
|
remote: nonEmpty4,
|
|
725
|
-
cloned:
|
|
725
|
+
cloned: z8.boolean().optional()
|
|
726
726
|
});
|
|
727
727
|
isCloned = (repo) => repo.cloned !== false;
|
|
728
|
-
machineCliSchema =
|
|
728
|
+
machineCliSchema = z8.object({
|
|
729
729
|
name: nonEmpty4,
|
|
730
730
|
version: nonEmpty4,
|
|
731
|
-
runnable:
|
|
732
|
-
capabilities:
|
|
731
|
+
runnable: z8.boolean().optional(),
|
|
732
|
+
capabilities: z8.array(capabilitySchema).optional(),
|
|
733
733
|
activation: agentActivationSchema.optional()
|
|
734
734
|
});
|
|
735
|
-
machineRegistrationSchema =
|
|
735
|
+
machineRegistrationSchema = z8.object({
|
|
736
736
|
id: nonEmpty4,
|
|
737
737
|
name: nonEmpty4,
|
|
738
|
-
repos:
|
|
739
|
-
clis:
|
|
738
|
+
repos: z8.array(machineRepoSchema),
|
|
739
|
+
clis: z8.array(machineCliSchema),
|
|
740
740
|
// The platform the agent actually runs on, and tools from herd's fixed list.
|
|
741
741
|
platform: platformSchema.optional(),
|
|
742
|
-
tools:
|
|
742
|
+
tools: z8.array(toolSchema).optional(),
|
|
743
743
|
// The machine's validated `herd.config.ts`, and why the file on disk didn't load if it didn't.
|
|
744
744
|
config: herdConfigSchema.optional(),
|
|
745
|
-
configError:
|
|
745
|
+
configError: z8.string().max(1e3).optional(),
|
|
746
746
|
// Whether its GitHub CLI is signed in, and as whom.
|
|
747
747
|
gh: gitHubCliSchema.optional()
|
|
748
748
|
});
|
|
749
749
|
machineSchema = machineRegistrationSchema.extend({
|
|
750
750
|
ownerId: nonEmpty4,
|
|
751
|
-
online:
|
|
751
|
+
online: z8.boolean(),
|
|
752
752
|
lastSeenAt: time2,
|
|
753
753
|
createdAt: time2
|
|
754
754
|
});
|
|
755
|
-
machinePresenceSchema =
|
|
756
|
-
worktreeSchema =
|
|
755
|
+
machinePresenceSchema = z8.object({ name: nonEmpty4, online: z8.boolean() });
|
|
756
|
+
worktreeSchema = z8.object({ repo: nonEmpty4, branch: nonEmpty4 });
|
|
757
757
|
MAX_REPO_HINTS = 10;
|
|
758
|
-
repoHintSchema =
|
|
758
|
+
repoHintSchema = z8.object({
|
|
759
759
|
remote: nonEmpty4,
|
|
760
760
|
branch: nonEmpty4.optional(),
|
|
761
761
|
folder: nonEmpty4.optional()
|
|
762
762
|
});
|
|
763
|
-
terminalSchema =
|
|
763
|
+
terminalSchema = z8.object({
|
|
764
764
|
id: nonEmpty4,
|
|
765
765
|
name: nonEmpty4,
|
|
766
766
|
machineId: nonEmpty4,
|
|
767
767
|
conversationId: nonEmpty4,
|
|
768
768
|
// The lead terminal receives the conversation's notices. Others are started with `herd run`.
|
|
769
|
-
lead:
|
|
769
|
+
lead: z8.boolean(),
|
|
770
770
|
// Only for a conversation from before folders, which works in one repo's worktree.
|
|
771
771
|
worktree: worktreeSchema.optional(),
|
|
772
772
|
// The program the screen reader recognized, such as `claude-code` or `shell`, when it knows.
|
|
@@ -774,7 +774,7 @@ var init_machines = __esm({
|
|
|
774
774
|
state: terminalStateSchema,
|
|
775
775
|
updatedAt: time2
|
|
776
776
|
});
|
|
777
|
-
offerSchema =
|
|
777
|
+
offerSchema = z8.object({
|
|
778
778
|
id: nonEmpty4,
|
|
779
779
|
conversationId: nonEmpty4,
|
|
780
780
|
machineId: nonEmpty4,
|
|
@@ -782,33 +782,33 @@ var init_machines = __esm({
|
|
|
782
782
|
expiresAt: time2,
|
|
783
783
|
// The repos the work hints, which the machine adds to the conversation's folder before the agent
|
|
784
784
|
// starts. Hints never decide which machines are offered the work.
|
|
785
|
-
repos:
|
|
785
|
+
repos: z8.array(repoHintSchema).max(MAX_REPO_HINTS).optional(),
|
|
786
786
|
// The first hint's remote, for daemons from before `repos`, which work in that one repo.
|
|
787
787
|
repo: nonEmpty4.optional(),
|
|
788
788
|
// The agent CLI of the worker it's offered to. Without one, it's Claude Code.
|
|
789
789
|
agent: nonEmpty4.optional(),
|
|
790
790
|
// A handed-off conversation restores each of its repos from its branch, if the remote has it.
|
|
791
|
-
handoff:
|
|
791
|
+
handoff: z8.boolean().optional()
|
|
792
792
|
});
|
|
793
|
-
offerAnswerSchema =
|
|
794
|
-
|
|
795
|
-
|
|
793
|
+
offerAnswerSchema = z8.discriminatedUnion("answer", [
|
|
794
|
+
z8.object({ answer: z8.literal("accept") }),
|
|
795
|
+
z8.object({ answer: z8.literal("refuse"), reason: nonEmpty4 })
|
|
796
796
|
]);
|
|
797
|
-
dispatchFrameSchema =
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
type:
|
|
797
|
+
dispatchFrameSchema = z8.discriminatedUnion("type", [
|
|
798
|
+
z8.object({ type: z8.literal("offer"), offer: offerSchema }),
|
|
799
|
+
z8.object({
|
|
800
|
+
type: z8.literal("message"),
|
|
801
801
|
conversationId: nonEmpty4,
|
|
802
|
-
delivery:
|
|
802
|
+
delivery: z8.enum(["interrupt", "defer"])
|
|
803
803
|
}),
|
|
804
|
-
|
|
804
|
+
z8.object({ type: z8.literal("reconnect") }),
|
|
805
805
|
// Its owner asked for a sign-in on this machine, which the daemon runs and reports on.
|
|
806
|
-
|
|
806
|
+
z8.object({ type: z8.literal("sign_in"), signInId: nonEmpty4, tool: signInToolSchema })
|
|
807
807
|
]);
|
|
808
|
-
machineMessageSchema =
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
type:
|
|
808
|
+
machineMessageSchema = z8.discriminatedUnion("type", [
|
|
809
|
+
z8.object({ type: z8.literal("ack"), conversationId: nonEmpty4 }),
|
|
810
|
+
z8.object({
|
|
811
|
+
type: z8.literal("usage"),
|
|
812
812
|
/** The worker's agent on this machine, such as `claude-code`. */
|
|
813
813
|
agent: nonEmpty4,
|
|
814
814
|
usage: usageSchema,
|
|
@@ -819,39 +819,39 @@ var init_machines = __esm({
|
|
|
819
819
|
});
|
|
820
820
|
|
|
821
821
|
// ../common-chat/src/prompts.ts
|
|
822
|
-
import { z as
|
|
822
|
+
import { z as z9 } from "zod";
|
|
823
823
|
var nonEmpty5, id, promptKindSchema, promptOptionSchema, promptQuestionSchema, promptRequestSchema, promptOutcomeSchema;
|
|
824
824
|
var init_prompts = __esm({
|
|
825
825
|
"../common-chat/src/prompts.ts"() {
|
|
826
826
|
"use strict";
|
|
827
827
|
init_define_HERD_PACKAGE();
|
|
828
|
-
nonEmpty5 =
|
|
829
|
-
id =
|
|
830
|
-
promptKindSchema =
|
|
831
|
-
promptOptionSchema =
|
|
828
|
+
nonEmpty5 = z9.string().min(1);
|
|
829
|
+
id = z9.string().regex(/^[A-Za-z0-9_-]{1,40}$/).describe("Short, so it fits in a button's value and action ID");
|
|
830
|
+
promptKindSchema = z9.enum(["permission", "question", "plan", "automation"]);
|
|
831
|
+
promptOptionSchema = z9.object({
|
|
832
832
|
id,
|
|
833
|
-
label:
|
|
834
|
-
description:
|
|
833
|
+
label: z9.string().trim().min(1).max(75),
|
|
834
|
+
description: z9.string().max(200).optional(),
|
|
835
835
|
// How a button for it is drawn: `primary` to go ahead, `danger` to refuse.
|
|
836
|
-
style:
|
|
836
|
+
style: z9.enum(["primary", "danger"]).optional()
|
|
837
837
|
});
|
|
838
|
-
promptQuestionSchema =
|
|
838
|
+
promptQuestionSchema = z9.object({
|
|
839
839
|
id,
|
|
840
|
-
text:
|
|
841
|
-
options:
|
|
840
|
+
text: z9.string().trim().min(1).max(300),
|
|
841
|
+
options: z9.array(promptOptionSchema).min(1).max(10)
|
|
842
842
|
});
|
|
843
|
-
promptRequestSchema =
|
|
843
|
+
promptRequestSchema = z9.object({
|
|
844
844
|
kind: promptKindSchema,
|
|
845
|
-
title:
|
|
846
|
-
detail:
|
|
847
|
-
questions:
|
|
845
|
+
title: z9.string().trim().min(1).max(150),
|
|
846
|
+
detail: z9.string().max(2800).optional(),
|
|
847
|
+
questions: z9.array(promptQuestionSchema).min(1).max(4)
|
|
848
848
|
});
|
|
849
|
-
promptOutcomeSchema =
|
|
849
|
+
promptOutcomeSchema = z9.enum(["answered", "cancelled"]);
|
|
850
850
|
}
|
|
851
851
|
});
|
|
852
852
|
|
|
853
853
|
// ../common-chat/src/pull-requests.ts
|
|
854
|
-
import { z as
|
|
854
|
+
import { z as z10 } from "zod";
|
|
855
855
|
function statusOfPhase(phase) {
|
|
856
856
|
return phase === "merged" ? "done" : phase === "closed" ? "closed" : "open";
|
|
857
857
|
}
|
|
@@ -890,8 +890,8 @@ var init_pull_requests = __esm({
|
|
|
890
890
|
"../common-chat/src/pull-requests.ts"() {
|
|
891
891
|
"use strict";
|
|
892
892
|
init_define_HERD_PACKAGE();
|
|
893
|
-
time3 =
|
|
894
|
-
pullRequestPhaseSchema =
|
|
893
|
+
time3 = z10.number().int().nonnegative();
|
|
894
|
+
pullRequestPhaseSchema = z10.enum([
|
|
895
895
|
"draft",
|
|
896
896
|
"checks_running",
|
|
897
897
|
"checks_failed",
|
|
@@ -902,7 +902,7 @@ var init_pull_requests = __esm({
|
|
|
902
902
|
"merged",
|
|
903
903
|
"closed"
|
|
904
904
|
]);
|
|
905
|
-
pullRequestMoveSchema =
|
|
905
|
+
pullRequestMoveSchema = z10.enum(["you", "agent", "others", "nobody"]);
|
|
906
906
|
PHASE_LABELS = {
|
|
907
907
|
draft: "draft",
|
|
908
908
|
checks_running: "checks running",
|
|
@@ -914,22 +914,22 @@ var init_pull_requests = __esm({
|
|
|
914
914
|
merged: "merged",
|
|
915
915
|
closed: "closed"
|
|
916
916
|
};
|
|
917
|
-
leadChangeSchema =
|
|
917
|
+
leadChangeSchema = z10.object({
|
|
918
918
|
/** Its repo and number, such as `api#104`, or "a pull request" when hidden. */
|
|
919
|
-
label:
|
|
919
|
+
label: z10.string().min(1),
|
|
920
920
|
phase: pullRequestPhaseSchema,
|
|
921
921
|
move: pullRequestMoveSchema,
|
|
922
922
|
changedAt: time3,
|
|
923
923
|
/** How many of the conversation's other open pull requests are also the person's move. */
|
|
924
|
-
moreForYou:
|
|
924
|
+
moreForYou: z10.number().int().nonnegative(),
|
|
925
925
|
/** Absent when hidden. */
|
|
926
|
-
url:
|
|
926
|
+
url: z10.string().optional()
|
|
927
927
|
});
|
|
928
928
|
}
|
|
929
929
|
});
|
|
930
930
|
|
|
931
931
|
// ../common-chat/src/work-objects.ts
|
|
932
|
-
import { z as
|
|
932
|
+
import { z as z11 } from "zod";
|
|
933
933
|
function workLine(work) {
|
|
934
934
|
const parts = [
|
|
935
935
|
work.phase ? `${work.kind} ${PHASE_LABELS[work.phase]}` : `${work.kind} ${work.status}`
|
|
@@ -944,21 +944,21 @@ var init_work_objects = __esm({
|
|
|
944
944
|
"use strict";
|
|
945
945
|
init_define_HERD_PACKAGE();
|
|
946
946
|
init_pull_requests();
|
|
947
|
-
time4 =
|
|
948
|
-
workKindSchema =
|
|
949
|
-
workStatusSchema =
|
|
950
|
-
workSourceSchema =
|
|
947
|
+
time4 = z11.number().int().nonnegative();
|
|
948
|
+
workKindSchema = z11.enum(["change", "ticket", "deploy", "document", "other"]);
|
|
949
|
+
workStatusSchema = z11.enum(["open", "done", "closed"]);
|
|
950
|
+
workSourceSchema = z11.enum(["agent", "provider"]);
|
|
951
951
|
MAX_WORK_TITLE = 200;
|
|
952
952
|
MAX_WORK_DETAIL = 100;
|
|
953
953
|
MAX_WORK_URL = 2048;
|
|
954
|
-
workObjectSchema =
|
|
955
|
-
url:
|
|
954
|
+
workObjectSchema = z11.object({
|
|
955
|
+
url: z11.string().min(1).max(MAX_WORK_URL),
|
|
956
956
|
kind: workKindSchema,
|
|
957
|
-
title:
|
|
957
|
+
title: z11.string().min(1).max(MAX_WORK_TITLE),
|
|
958
958
|
status: workStatusSchema,
|
|
959
|
-
detail:
|
|
959
|
+
detail: z11.string().max(MAX_WORK_DETAIL).nullable(),
|
|
960
960
|
/** Whether the conversation made it, rather than only being about it. */
|
|
961
|
-
made:
|
|
961
|
+
made: z11.boolean(),
|
|
962
962
|
changedAt: time4,
|
|
963
963
|
changedBy: workSourceSchema,
|
|
964
964
|
createdAt: time4,
|
|
@@ -966,21 +966,21 @@ var init_work_objects = __esm({
|
|
|
966
966
|
phase: pullRequestPhaseSchema.nullable().optional(),
|
|
967
967
|
move: pullRequestMoveSchema.nullable().optional(),
|
|
968
968
|
/** The delegate holding it, when it's read from an ancestor. */
|
|
969
|
-
conversationId:
|
|
969
|
+
conversationId: z11.string().min(1).optional()
|
|
970
970
|
});
|
|
971
|
-
workChangeSchema =
|
|
972
|
-
url:
|
|
971
|
+
workChangeSchema = z11.object({
|
|
972
|
+
url: z11.string().trim().min(1).max(MAX_WORK_URL),
|
|
973
973
|
kind: workKindSchema.optional(),
|
|
974
|
-
title:
|
|
974
|
+
title: z11.string().trim().min(1).max(2e3).optional(),
|
|
975
975
|
status: workStatusSchema.optional(),
|
|
976
|
-
detail:
|
|
977
|
-
made:
|
|
976
|
+
detail: z11.string().trim().max(2e3).nullable().optional(),
|
|
977
|
+
made: z11.boolean().optional(),
|
|
978
978
|
/** Only for a `change`. Its status then follows it. */
|
|
979
979
|
phase: pullRequestPhaseSchema.optional(),
|
|
980
980
|
/** Set by a provider, which knows who was asked to review. Otherwise it follows the phase. */
|
|
981
981
|
move: pullRequestMoveSchema.optional()
|
|
982
982
|
});
|
|
983
|
-
workFieldSchema =
|
|
983
|
+
workFieldSchema = z11.enum([
|
|
984
984
|
"kind",
|
|
985
985
|
"title",
|
|
986
986
|
"status",
|
|
@@ -989,27 +989,27 @@ var init_work_objects = __esm({
|
|
|
989
989
|
"phase",
|
|
990
990
|
"move"
|
|
991
991
|
]);
|
|
992
|
-
workObjectSummarySchema =
|
|
992
|
+
workObjectSummarySchema = z11.object({
|
|
993
993
|
kind: workKindSchema,
|
|
994
994
|
status: workStatusSchema,
|
|
995
|
-
made:
|
|
995
|
+
made: z11.boolean(),
|
|
996
996
|
changedAt: time4,
|
|
997
997
|
/** A pull request's phase and move, which say nothing of its content, so they're never hidden. */
|
|
998
998
|
phase: pullRequestPhaseSchema.nullable().optional(),
|
|
999
999
|
move: pullRequestMoveSchema.nullable().optional(),
|
|
1000
|
-
url:
|
|
1001
|
-
title:
|
|
1002
|
-
detail:
|
|
1000
|
+
url: z11.string().optional(),
|
|
1001
|
+
title: z11.string().optional(),
|
|
1002
|
+
detail: z11.string().nullable().optional(),
|
|
1003
1003
|
/** The delegate holding it, when it isn't the item's own conversation. */
|
|
1004
|
-
conversationId:
|
|
1004
|
+
conversationId: z11.string().min(1).optional()
|
|
1005
1005
|
});
|
|
1006
1006
|
}
|
|
1007
1007
|
});
|
|
1008
1008
|
|
|
1009
1009
|
// ../common-chat/src/events.ts
|
|
1010
|
-
import { z as
|
|
1010
|
+
import { z as z12 } from "zod";
|
|
1011
1011
|
function event(type, payload) {
|
|
1012
|
-
return
|
|
1012
|
+
return z12.object({ ...eventBase, type: z12.literal(type), payload: z12.object(payload) });
|
|
1013
1013
|
}
|
|
1014
1014
|
var routeSchema, deliveryModeSchema, eventSourceSchema, nonEmpty6, actorSchema, eventBase, entryIds, routingRecordSchema, conversationEventSchema, conversationVisibilitySchema, conversationStatusSchema, conversationSummarySchema, placementSchema, treeSummarySchema, conversationSnapshotSchema, liveFrameSchema, adapterCapabilitiesSchema;
|
|
1015
1015
|
var init_events = __esm({
|
|
@@ -1023,129 +1023,129 @@ var init_events = __esm({
|
|
|
1023
1023
|
init_usage();
|
|
1024
1024
|
init_work_objects();
|
|
1025
1025
|
init_workers();
|
|
1026
|
-
routeSchema =
|
|
1027
|
-
deliveryModeSchema =
|
|
1028
|
-
eventSourceSchema =
|
|
1029
|
-
nonEmpty6 =
|
|
1030
|
-
actorSchema =
|
|
1026
|
+
routeSchema = z12.enum(["direct", "mention", "joined"]);
|
|
1027
|
+
deliveryModeSchema = z12.enum(["interrupt", "defer"]);
|
|
1028
|
+
eventSourceSchema = z12.enum(["slack", "discord", "web", "api", "cli", "mcp", "system"]);
|
|
1029
|
+
nonEmpty6 = z12.string().min(1);
|
|
1030
|
+
actorSchema = z12.discriminatedUnion("kind", [
|
|
1031
1031
|
// Someone signed in to this system. `id` is the stable person identifier.
|
|
1032
|
-
|
|
1032
|
+
z12.object({ kind: z12.literal("person"), id: nonEmpty6, name: nonEmpty6 }),
|
|
1033
1033
|
// An account on a platform, which may or may not be linked to a person.
|
|
1034
|
-
|
|
1035
|
-
kind:
|
|
1034
|
+
z12.object({
|
|
1035
|
+
kind: z12.literal("account"),
|
|
1036
1036
|
provider: nonEmpty6,
|
|
1037
1037
|
tenant: nonEmpty6,
|
|
1038
1038
|
subject: nonEmpty6,
|
|
1039
|
-
name:
|
|
1040
|
-
isBot:
|
|
1039
|
+
name: z12.string().optional(),
|
|
1040
|
+
isBot: z12.boolean()
|
|
1041
1041
|
}),
|
|
1042
|
-
|
|
1042
|
+
z12.object({ kind: z12.literal("system") })
|
|
1043
1043
|
]);
|
|
1044
1044
|
eventBase = {
|
|
1045
|
-
seq:
|
|
1045
|
+
seq: z12.number().int().positive(),
|
|
1046
1046
|
source: eventSourceSchema,
|
|
1047
1047
|
actor: actorSchema,
|
|
1048
|
-
createdAt:
|
|
1048
|
+
createdAt: z12.number().int().nonnegative()
|
|
1049
1049
|
};
|
|
1050
|
-
entryIds =
|
|
1051
|
-
routingRecordSchema =
|
|
1052
|
-
eligible:
|
|
1053
|
-
questions:
|
|
1054
|
-
|
|
1050
|
+
entryIds = z12.array(nonEmpty6);
|
|
1051
|
+
routingRecordSchema = z12.object({
|
|
1052
|
+
eligible: z12.array(z12.object({ key: nonEmpty6, name: nonEmpty6 })),
|
|
1053
|
+
questions: z12.array(
|
|
1054
|
+
z12.object({
|
|
1055
1055
|
id: nonEmpty6,
|
|
1056
1056
|
question: nonEmpty6,
|
|
1057
|
-
probability:
|
|
1057
|
+
probability: z12.number().min(0).max(1).nullable()
|
|
1058
1058
|
})
|
|
1059
1059
|
),
|
|
1060
1060
|
model: nonEmpty6.optional(),
|
|
1061
1061
|
// Why the model's answers weren't used, when they weren't.
|
|
1062
|
-
fallback:
|
|
1063
|
-
removed:
|
|
1064
|
-
order:
|
|
1062
|
+
fallback: z12.string().optional(),
|
|
1063
|
+
removed: z12.array(z12.object({ key: nonEmpty6, name: nonEmpty6, rule: nonEmpty6 })),
|
|
1064
|
+
order: z12.array(nonEmpty6),
|
|
1065
1065
|
// Each ordered worker's fit, and the profile statement and level that gave it, when the model
|
|
1066
1066
|
// answered.
|
|
1067
|
-
fits:
|
|
1068
|
-
|
|
1067
|
+
fits: z12.array(
|
|
1068
|
+
z12.object({
|
|
1069
1069
|
key: nonEmpty6,
|
|
1070
|
-
fit:
|
|
1071
|
-
statement:
|
|
1072
|
-
level:
|
|
1070
|
+
fit: z12.number().min(0).max(1),
|
|
1071
|
+
statement: z12.string().optional(),
|
|
1072
|
+
level: z12.enum(["great", "good", "okay"]).optional()
|
|
1073
1073
|
})
|
|
1074
1074
|
).optional(),
|
|
1075
1075
|
// Profile statements left out to keep within the most questions one call asks.
|
|
1076
|
-
dropped:
|
|
1076
|
+
dropped: z12.array(z12.string()).optional(),
|
|
1077
1077
|
// The repos the work hinted, and the workers whose machine had cloned every one, which go first
|
|
1078
1078
|
// among workers that tie on fit and priority.
|
|
1079
|
-
hints:
|
|
1080
|
-
warm:
|
|
1079
|
+
hints: z12.array(nonEmpty6).optional(),
|
|
1080
|
+
warm: z12.array(nonEmpty6).optional(),
|
|
1081
1081
|
// Each ordered worker's share, how its weekly usage is pacing, and the weight that gives it. The
|
|
1082
1082
|
// first worker was drawn by weight from those in `drawn`, which suited the work equally.
|
|
1083
|
-
shares:
|
|
1084
|
-
|
|
1083
|
+
shares: z12.array(
|
|
1084
|
+
z12.object({
|
|
1085
1085
|
key: nonEmpty6,
|
|
1086
1086
|
share: shareSchema,
|
|
1087
|
-
pacing:
|
|
1088
|
-
weight:
|
|
1087
|
+
pacing: z12.enum(["ahead", "even", "under", "unknown"]),
|
|
1088
|
+
weight: z12.number().nonnegative()
|
|
1089
1089
|
})
|
|
1090
1090
|
).optional(),
|
|
1091
|
-
drawn:
|
|
1091
|
+
drawn: z12.array(nonEmpty6).optional()
|
|
1092
1092
|
});
|
|
1093
|
-
conversationEventSchema =
|
|
1093
|
+
conversationEventSchema = z12.discriminatedUnion("type", [
|
|
1094
1094
|
event("message.created", {
|
|
1095
1095
|
messageId: nonEmpty6,
|
|
1096
|
-
text:
|
|
1097
|
-
direction:
|
|
1096
|
+
text: z12.string(),
|
|
1097
|
+
direction: z12.enum(["inbound", "outbound"]),
|
|
1098
1098
|
route: routeSchema.optional(),
|
|
1099
1099
|
// Why the message did or didn't wake the conversation.
|
|
1100
|
-
reason:
|
|
1100
|
+
reason: z12.string().optional(),
|
|
1101
1101
|
// Loaded from before the conversation joined the thread, so it never waits for a response.
|
|
1102
|
-
isContext:
|
|
1102
|
+
isContext: z12.boolean().optional(),
|
|
1103
1103
|
// Set when the message was deleted on its platform. `text` is then empty.
|
|
1104
|
-
deleted:
|
|
1104
|
+
deleted: z12.boolean().optional(),
|
|
1105
1105
|
// Sent through the API but kept out of the platform, so only clients see it.
|
|
1106
|
-
quiet:
|
|
1106
|
+
quiet: z12.boolean().optional(),
|
|
1107
1107
|
// The client an agent sent it through, such as "Claude Code". Such a message is the agent's.
|
|
1108
|
-
client:
|
|
1108
|
+
client: z12.string().optional(),
|
|
1109
1109
|
// How to read `text`. Absent means plain text, as every message before this field was.
|
|
1110
|
-
format:
|
|
1110
|
+
format: z12.enum(["markdown"]).optional(),
|
|
1111
1111
|
// Files attached to it, kept with the conversation.
|
|
1112
|
-
files:
|
|
1112
|
+
files: z12.array(messageFileSchema).optional(),
|
|
1113
1113
|
// A platform's own layout, shown there in place of `text`. Every other surface shows `text`.
|
|
1114
|
-
layout:
|
|
1114
|
+
layout: z12.object({ platform: layoutPlatformSchema, blocks: z12.array(z12.unknown()) }).optional(),
|
|
1115
1115
|
// Set when this was posted in another channel, starting the conversation named here.
|
|
1116
1116
|
post: postTargetSchema.optional(),
|
|
1117
1117
|
// Set on a channel post's own conversation: the conversation that posted it. Its ID is left
|
|
1118
1118
|
// out for anyone who can't read that conversation.
|
|
1119
|
-
origin:
|
|
1119
|
+
origin: z12.object({ conversationId: nonEmpty6.optional() }).optional(),
|
|
1120
1120
|
// Set on Friday's one notice that a firing with no thread can't run yet, saying why.
|
|
1121
1121
|
threadNotice: nonEmpty6.optional(),
|
|
1122
1122
|
// Set when this reply answered an open prompt, so it never waits as a message of its own.
|
|
1123
1123
|
answersPrompt: nonEmpty6.optional(),
|
|
1124
1124
|
// Set on a child conversation's first message: the brief its parent's agent wrote, from the
|
|
1125
1125
|
// principal's own account. `by` is the parent's worker.
|
|
1126
|
-
delegation:
|
|
1126
|
+
delegation: z12.object({ parent: nonEmpty6, by: nonEmpty6 }).optional(),
|
|
1127
1127
|
// Set on a message from another of the principal's conversations' agents, which is that agent's
|
|
1128
1128
|
// words, not a person's. `posted` means a delegate already posted it in the thread, and
|
|
1129
1129
|
// `outsideTree` that the sender isn't in this conversation's tree.
|
|
1130
|
-
agentMessage:
|
|
1130
|
+
agentMessage: z12.object({
|
|
1131
1131
|
from: nonEmpty6,
|
|
1132
1132
|
worker: nonEmpty6,
|
|
1133
|
-
posted:
|
|
1134
|
-
overdue:
|
|
1133
|
+
posted: z12.boolean().optional(),
|
|
1134
|
+
overdue: z12.boolean().optional(),
|
|
1135
1135
|
// herd's own note about the delegate, such as that it's waiting for its worker.
|
|
1136
|
-
notice:
|
|
1137
|
-
outsideTree:
|
|
1136
|
+
notice: z12.boolean().optional(),
|
|
1137
|
+
outsideTree: z12.boolean().optional()
|
|
1138
1138
|
}).optional(),
|
|
1139
1139
|
// Set on a message a root posted for one of its children, which is labelled as the child's.
|
|
1140
|
-
forChild:
|
|
1140
|
+
forChild: z12.object({ id: nonEmpty6, worker: nonEmpty6, for: nonEmpty6 }).optional(),
|
|
1141
1141
|
// Set on an automation's firing, whose `text` is the owner's instructions, and on the opening
|
|
1142
1142
|
// post that starts a conversation for one. `payload` is what the trigger brought: untrusted.
|
|
1143
|
-
automation:
|
|
1143
|
+
automation: z12.object({
|
|
1144
1144
|
id: nonEmpty6,
|
|
1145
1145
|
name: nonEmpty6,
|
|
1146
1146
|
reason: nonEmpty6,
|
|
1147
1147
|
key: nonEmpty6,
|
|
1148
|
-
payload:
|
|
1148
|
+
payload: z12.string().optional(),
|
|
1149
1149
|
// The opening post a firing's reactions are shown on, in a conversation it started.
|
|
1150
1150
|
opener: nonEmpty6.optional()
|
|
1151
1151
|
}).optional(),
|
|
@@ -1153,27 +1153,27 @@ var init_events = __esm({
|
|
|
1153
1153
|
// follows. `text` is a short line about it, and anyone's words in it are untrusted.
|
|
1154
1154
|
github: githubEventSummarySchema.optional()
|
|
1155
1155
|
}),
|
|
1156
|
-
event("message.updated", { messageId: nonEmpty6, text:
|
|
1156
|
+
event("message.updated", { messageId: nonEmpty6, text: z12.string() }),
|
|
1157
1157
|
// A decision model judged whether a reply in a joined thread was meant for the bot. `for_bot`
|
|
1158
1158
|
// woke the conversation. `failed` means it couldn't be decided in time, so nothing woke.
|
|
1159
1159
|
event("message.decided", {
|
|
1160
1160
|
messageId: nonEmpty6,
|
|
1161
|
-
messageSeq:
|
|
1162
|
-
outcome:
|
|
1163
|
-
probability:
|
|
1161
|
+
messageSeq: z12.number().int().positive(),
|
|
1162
|
+
outcome: z12.enum(["for_bot", "not_for_bot", "failed"]),
|
|
1163
|
+
probability: z12.number().min(0).max(1).optional(),
|
|
1164
1164
|
model: nonEmpty6,
|
|
1165
|
-
error:
|
|
1165
|
+
error: z12.string().optional()
|
|
1166
1166
|
}),
|
|
1167
1167
|
// A decision model judged whether the bot's last message of a turn asks a person to answer,
|
|
1168
1168
|
// decide, provide or confirm something before it can carry on. `asks` keeps the conversation
|
|
1169
1169
|
// waiting on them. `failed` means it couldn't be judged in time, so nothing changed.
|
|
1170
1170
|
event("message.asked", {
|
|
1171
1171
|
messageId: nonEmpty6,
|
|
1172
|
-
messageSeq:
|
|
1173
|
-
outcome:
|
|
1174
|
-
probability:
|
|
1172
|
+
messageSeq: z12.number().int().positive(),
|
|
1173
|
+
outcome: z12.enum(["asks", "doesnt_ask", "failed"]),
|
|
1174
|
+
probability: z12.number().min(0).max(1).optional(),
|
|
1175
1175
|
model: nonEmpty6,
|
|
1176
|
-
error:
|
|
1176
|
+
error: z12.string().optional()
|
|
1177
1177
|
}),
|
|
1178
1178
|
// One of an incoming message's files arrived, or couldn't. `file` replaces the one with its ID.
|
|
1179
1179
|
event("message.file_changed", { messageId: nonEmpty6, file: messageFileSchema }),
|
|
@@ -1185,21 +1185,21 @@ var init_events = __esm({
|
|
|
1185
1185
|
event("context.unavailable", { reason: nonEmpty6 }),
|
|
1186
1186
|
event("mailbox.queued", {
|
|
1187
1187
|
entryId: nonEmpty6,
|
|
1188
|
-
messageSeq:
|
|
1188
|
+
messageSeq: z12.number().int().positive(),
|
|
1189
1189
|
delivery: deliveryModeSchema
|
|
1190
1190
|
}),
|
|
1191
1191
|
event("mailbox.claimed", {
|
|
1192
1192
|
claimId: nonEmpty6,
|
|
1193
1193
|
entryIds,
|
|
1194
1194
|
holder: nonEmpty6,
|
|
1195
|
-
expiresAt:
|
|
1195
|
+
expiresAt: z12.number().int()
|
|
1196
1196
|
}),
|
|
1197
|
-
event("mailbox.renewed", { claimId: nonEmpty6, expiresAt:
|
|
1197
|
+
event("mailbox.renewed", { claimId: nonEmpty6, expiresAt: z12.number().int() }),
|
|
1198
1198
|
event("mailbox.released", {
|
|
1199
1199
|
claimId: nonEmpty6,
|
|
1200
1200
|
entryIds,
|
|
1201
1201
|
// `delegates` means messages held for delegates are waiting again now that they've settled.
|
|
1202
|
-
reason:
|
|
1202
|
+
reason: z12.enum(["released", "expired", "delegates"])
|
|
1203
1203
|
}),
|
|
1204
1204
|
// A turn ended with delegates still open, so the messages it worked on wait for them, still ⏳.
|
|
1205
1205
|
event("mailbox.held", { claimId: nonEmpty6, entryIds }),
|
|
@@ -1207,7 +1207,7 @@ var init_events = __esm({
|
|
|
1207
1207
|
event("mailbox.completed", {
|
|
1208
1208
|
entryIds,
|
|
1209
1209
|
claimId: nonEmpty6.optional(),
|
|
1210
|
-
outcome:
|
|
1210
|
+
outcome: z12.enum(["passed"]).optional()
|
|
1211
1211
|
}),
|
|
1212
1212
|
event("mailbox.cancelled", { entryIds, reason: nonEmpty6 }),
|
|
1213
1213
|
// A person asked for what's waiting to be delivered again. The entries stay waiting.
|
|
@@ -1224,15 +1224,15 @@ var init_events = __esm({
|
|
|
1224
1224
|
// The message it was delivering, when it was one of the conversation's own messages.
|
|
1225
1225
|
messageId: nonEmpty6.optional(),
|
|
1226
1226
|
// For `kind: "files"`, which of that message's files didn't arrive.
|
|
1227
|
-
fileIds:
|
|
1227
|
+
fileIds: z12.array(nonEmpty6).optional()
|
|
1228
1228
|
}),
|
|
1229
1229
|
event("status.changed", { status: agentStatusSchema }),
|
|
1230
1230
|
// A work object was added or changed: the whole of it as it now stands, which fields changed, and
|
|
1231
1231
|
// whether the agent or a provider changed them. Recording one never wakes the conversation.
|
|
1232
1232
|
event("work.recorded", {
|
|
1233
1233
|
work: workObjectSchema.omit({ conversationId: true }),
|
|
1234
|
-
changed:
|
|
1235
|
-
added:
|
|
1234
|
+
changed: z12.array(workFieldSchema),
|
|
1235
|
+
added: z12.boolean(),
|
|
1236
1236
|
by: workSourceSchema
|
|
1237
1237
|
}),
|
|
1238
1238
|
event("work.removed", { url: nonEmpty6, by: workSourceSchema }),
|
|
@@ -1245,7 +1245,7 @@ var init_events = __esm({
|
|
|
1245
1245
|
event("prompt.opened", {
|
|
1246
1246
|
promptId: nonEmpty6,
|
|
1247
1247
|
...promptRequestSchema.shape,
|
|
1248
|
-
forChild:
|
|
1248
|
+
forChild: z12.object({ id: nonEmpty6, worker: nonEmpty6, promptId: nonEmpty6 }).optional()
|
|
1249
1249
|
}),
|
|
1250
1250
|
// A reply in the thread answers with its `messageId`, and with `text` when it was taken as the
|
|
1251
1251
|
// answer in its own words rather than as naming an option.
|
|
@@ -1254,12 +1254,12 @@ var init_events = __esm({
|
|
|
1254
1254
|
questionId: nonEmpty6,
|
|
1255
1255
|
optionId: nonEmpty6.optional(),
|
|
1256
1256
|
messageId: nonEmpty6.optional(),
|
|
1257
|
-
text:
|
|
1257
|
+
text: z12.string().optional()
|
|
1258
1258
|
}),
|
|
1259
1259
|
event("prompt.closed", {
|
|
1260
1260
|
promptId: nonEmpty6,
|
|
1261
1261
|
outcome: promptOutcomeSchema,
|
|
1262
|
-
reason:
|
|
1262
|
+
reason: z12.string().optional()
|
|
1263
1263
|
}),
|
|
1264
1264
|
// Dispatch: which machine the conversation was offered to, and which one holds it.
|
|
1265
1265
|
event("dispatch.offered", {
|
|
@@ -1283,19 +1283,19 @@ var init_events = __esm({
|
|
|
1283
1283
|
// An agent started a child conversation on another worker, and how the child has gone since.
|
|
1284
1284
|
event("delegation.started", {
|
|
1285
1285
|
childId: nonEmpty6,
|
|
1286
|
-
workers:
|
|
1287
|
-
routed:
|
|
1286
|
+
workers: z12.array(nonEmpty6),
|
|
1287
|
+
routed: z12.boolean()
|
|
1288
1288
|
}),
|
|
1289
1289
|
event("delegation.settled", { childId: nonEmpty6 }),
|
|
1290
1290
|
event("delegation.overdue", { childId: nonEmpty6 }),
|
|
1291
|
-
event("delegation.waiting", { childId: nonEmpty6, waiting:
|
|
1291
|
+
event("delegation.waiting", { childId: nonEmpty6, waiting: z12.boolean() }),
|
|
1292
1292
|
// An agent asked for its conversation to move to another worker once its turn ends.
|
|
1293
1293
|
event("dispatch.handoff_requested", { workerKey: nonEmpty6, workerName: nonEmpty6 }),
|
|
1294
1294
|
// Terminals on the bound machine. Their output never enters the history, only these facts.
|
|
1295
1295
|
event("terminal.opened", {
|
|
1296
1296
|
terminalId: nonEmpty6,
|
|
1297
1297
|
machineId: nonEmpty6,
|
|
1298
|
-
lead:
|
|
1298
|
+
lead: z12.boolean(),
|
|
1299
1299
|
// Only for a conversation from before folders, which works in one repo's worktree.
|
|
1300
1300
|
worktree: worktreeSchema.optional()
|
|
1301
1301
|
}),
|
|
@@ -1307,9 +1307,9 @@ var init_events = __esm({
|
|
|
1307
1307
|
folder: nonEmpty6,
|
|
1308
1308
|
branch: nonEmpty6,
|
|
1309
1309
|
base: nonEmpty6.optional(),
|
|
1310
|
-
fetchFailed:
|
|
1310
|
+
fetchFailed: z12.string().max(1e3).optional()
|
|
1311
1311
|
}),
|
|
1312
|
-
event("terminal.exited", { terminalId: nonEmpty6, exitCode:
|
|
1312
|
+
event("terminal.exited", { terminalId: nonEmpty6, exitCode: z12.number().int().nullable() }),
|
|
1313
1313
|
event("terminal.notice_failed", { terminalId: nonEmpty6, reason: nonEmpty6 }),
|
|
1314
1314
|
/** The daemon closed one of Claude Code's own dialogs that it has recorded, named by its title. */
|
|
1315
1315
|
event("terminal.dialog_closed", { terminalId: nonEmpty6, dialog: nonEmpty6 }),
|
|
@@ -1319,7 +1319,7 @@ var init_events = __esm({
|
|
|
1319
1319
|
event("subscription.created", {
|
|
1320
1320
|
resource: nonEmpty6,
|
|
1321
1321
|
label: nonEmpty6,
|
|
1322
|
-
url:
|
|
1322
|
+
url: z12.url(),
|
|
1323
1323
|
subscriber: nonEmpty6,
|
|
1324
1324
|
createdBy: subscriptionOriginSchema
|
|
1325
1325
|
}),
|
|
@@ -1331,72 +1331,72 @@ var init_events = __esm({
|
|
|
1331
1331
|
// A subscription reached its hourly limit of wakes, noted once each hour.
|
|
1332
1332
|
event("subscription.limited", { resource: nonEmpty6 })
|
|
1333
1333
|
]);
|
|
1334
|
-
conversationVisibilitySchema =
|
|
1335
|
-
conversationStatusSchema =
|
|
1336
|
-
conversationSummarySchema =
|
|
1334
|
+
conversationVisibilitySchema = z12.enum(["public", "private"]);
|
|
1335
|
+
conversationStatusSchema = z12.enum(["idle", "waiting", "working"]);
|
|
1336
|
+
conversationSummarySchema = z12.object({
|
|
1337
1337
|
id: nonEmpty6,
|
|
1338
1338
|
provider: nonEmpty6,
|
|
1339
1339
|
visibility: conversationVisibilitySchema,
|
|
1340
1340
|
title: nonEmpty6,
|
|
1341
1341
|
// Where the conversation lives on its platform, when it has a link.
|
|
1342
|
-
placeUrl:
|
|
1342
|
+
placeUrl: z12.string().nullable(),
|
|
1343
1343
|
status: conversationStatusSchema,
|
|
1344
|
-
waitingCount:
|
|
1345
|
-
createdAt:
|
|
1346
|
-
lastActivityAt:
|
|
1347
|
-
expiresAt:
|
|
1344
|
+
waitingCount: z12.number().int().nonnegative(),
|
|
1345
|
+
createdAt: z12.number().int(),
|
|
1346
|
+
lastActivityAt: z12.number().int(),
|
|
1347
|
+
expiresAt: z12.number().int()
|
|
1348
1348
|
});
|
|
1349
|
-
placementSchema =
|
|
1350
|
-
|
|
1351
|
-
kind:
|
|
1352
|
-
machine:
|
|
1349
|
+
placementSchema = z12.discriminatedUnion("kind", [
|
|
1350
|
+
z12.object({
|
|
1351
|
+
kind: z12.literal("bound"),
|
|
1352
|
+
machine: z12.object({ name: nonEmpty6, online: z12.boolean() }),
|
|
1353
1353
|
// The worker's name, such as `mac-mini/claude`, and never its configuration or capabilities.
|
|
1354
1354
|
worker: nonEmpty6.optional()
|
|
1355
1355
|
}),
|
|
1356
|
-
|
|
1357
|
-
|
|
1356
|
+
z12.object({ kind: z12.literal("waiting_for_machine") }),
|
|
1357
|
+
z12.object({ kind: z12.literal("author_not_linked") })
|
|
1358
1358
|
]);
|
|
1359
|
-
treeSummarySchema =
|
|
1359
|
+
treeSummarySchema = z12.object({
|
|
1360
1360
|
parent: nonEmpty6.nullable(),
|
|
1361
1361
|
root: nonEmpty6,
|
|
1362
|
-
children:
|
|
1363
|
-
|
|
1362
|
+
children: z12.array(
|
|
1363
|
+
z12.object({
|
|
1364
1364
|
id: nonEmpty6,
|
|
1365
1365
|
title: nonEmpty6,
|
|
1366
|
-
state:
|
|
1367
|
-
createdAt:
|
|
1366
|
+
state: z12.string().nullable(),
|
|
1367
|
+
createdAt: z12.number()
|
|
1368
1368
|
})
|
|
1369
1369
|
)
|
|
1370
1370
|
});
|
|
1371
|
-
conversationSnapshotSchema =
|
|
1371
|
+
conversationSnapshotSchema = z12.object({
|
|
1372
1372
|
conversation: conversationSummarySchema,
|
|
1373
|
-
events:
|
|
1373
|
+
events: z12.array(conversationEventSchema),
|
|
1374
1374
|
/**
|
|
1375
1375
|
* Each person actor's display name, by ID, as it is now. A person is shown by this, never by
|
|
1376
1376
|
* the name stored with an event, which for older events was their address.
|
|
1377
1377
|
*/
|
|
1378
|
-
people:
|
|
1378
|
+
people: z12.record(z12.string(), z12.string()).optional(),
|
|
1379
1379
|
placement: placementSchema.nullable().optional(),
|
|
1380
1380
|
tree: treeSummarySchema.optional()
|
|
1381
1381
|
});
|
|
1382
|
-
liveFrameSchema =
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1382
|
+
liveFrameSchema = z12.discriminatedUnion("type", [
|
|
1383
|
+
z12.object({ type: z12.literal("event"), event: conversationEventSchema }),
|
|
1384
|
+
z12.object({ type: z12.literal("reconnect") }),
|
|
1385
|
+
z12.object({ type: z12.literal("expired") })
|
|
1386
1386
|
]);
|
|
1387
|
-
adapterCapabilitiesSchema =
|
|
1388
|
-
messages:
|
|
1389
|
-
edits:
|
|
1390
|
-
deletes:
|
|
1391
|
-
reactions:
|
|
1392
|
-
status:
|
|
1393
|
-
search:
|
|
1387
|
+
adapterCapabilitiesSchema = z12.object({
|
|
1388
|
+
messages: z12.enum(["push", "window"]),
|
|
1389
|
+
edits: z12.enum(["push", "rescan"]),
|
|
1390
|
+
deletes: z12.enum(["push", "rescan"]),
|
|
1391
|
+
reactions: z12.enum(["push", "counts"]),
|
|
1392
|
+
status: z12.boolean(),
|
|
1393
|
+
search: z12.boolean()
|
|
1394
1394
|
});
|
|
1395
1395
|
}
|
|
1396
1396
|
});
|
|
1397
1397
|
|
|
1398
1398
|
// ../common-chat/src/conversation-state.ts
|
|
1399
|
-
import { z as
|
|
1399
|
+
import { z as z13 } from "zod";
|
|
1400
1400
|
function openRank(item) {
|
|
1401
1401
|
if (item.state === "stuck") return 0;
|
|
1402
1402
|
if (leadOpen(item.lead) && item.lead?.move === "you") return 1;
|
|
@@ -1433,8 +1433,8 @@ var init_conversation_state = __esm({
|
|
|
1433
1433
|
init_machines();
|
|
1434
1434
|
init_pull_requests();
|
|
1435
1435
|
init_work_objects();
|
|
1436
|
-
nonEmpty7 =
|
|
1437
|
-
time5 =
|
|
1436
|
+
nonEmpty7 = z13.string().min(1);
|
|
1437
|
+
time5 = z13.number().int().nonnegative();
|
|
1438
1438
|
REACTIONS = {
|
|
1439
1439
|
waiting: "eyes",
|
|
1440
1440
|
working: "hourglass_flowing_sand",
|
|
@@ -1443,14 +1443,14 @@ var init_conversation_state = __esm({
|
|
|
1443
1443
|
passed: "ok_hand",
|
|
1444
1444
|
stuck: "warning"
|
|
1445
1445
|
};
|
|
1446
|
-
conversationStateSchema =
|
|
1446
|
+
conversationStateSchema = z13.enum([
|
|
1447
1447
|
"waiting",
|
|
1448
1448
|
"working",
|
|
1449
1449
|
"stuck",
|
|
1450
1450
|
"unanswered",
|
|
1451
1451
|
"done"
|
|
1452
1452
|
]);
|
|
1453
|
-
stuckReasonSchema =
|
|
1453
|
+
stuckReasonSchema = z13.enum([
|
|
1454
1454
|
"approval",
|
|
1455
1455
|
"waiting_on_someone",
|
|
1456
1456
|
// A delegate has an open prompt or is waiting on a person.
|
|
@@ -1467,43 +1467,43 @@ var init_conversation_state = __esm({
|
|
|
1467
1467
|
"awaiting_answer"
|
|
1468
1468
|
]);
|
|
1469
1469
|
STUCK_REASONS = stuckReasonSchema.options;
|
|
1470
|
-
placeKindSchema =
|
|
1471
|
-
conversationSourceSchema =
|
|
1470
|
+
placeKindSchema = z13.enum(["channel", "direct", "group", "web"]);
|
|
1471
|
+
conversationSourceSchema = z13.object({
|
|
1472
1472
|
provider: nonEmpty7,
|
|
1473
1473
|
kind: placeKindSchema,
|
|
1474
1474
|
/** Such as a Slack channel's name, without its `#`. Left out where it's unknown or hidden. */
|
|
1475
|
-
name:
|
|
1475
|
+
name: z13.string().optional()
|
|
1476
1476
|
});
|
|
1477
1477
|
LATEST_MESSAGE_LENGTH = 200;
|
|
1478
|
-
latestMessageSchema =
|
|
1479
|
-
text:
|
|
1478
|
+
latestMessageSchema = z13.object({
|
|
1479
|
+
text: z13.string().max(LATEST_MESSAGE_LENGTH),
|
|
1480
1480
|
/** A person wrote it, or the agent did. */
|
|
1481
|
-
from:
|
|
1481
|
+
from: z13.enum(["person", "agent"]),
|
|
1482
1482
|
at: time5
|
|
1483
1483
|
});
|
|
1484
1484
|
listMachineSchema = machinePresenceSchema.extend({
|
|
1485
|
-
mine:
|
|
1485
|
+
mine: z13.boolean().optional(),
|
|
1486
1486
|
/** The agent holding it on that machine, such as `Claude Code`, when it's known. */
|
|
1487
|
-
agent:
|
|
1487
|
+
agent: z13.string().optional()
|
|
1488
1488
|
});
|
|
1489
|
-
conversationListItemSchema =
|
|
1489
|
+
conversationListItemSchema = z13.object({
|
|
1490
1490
|
id: nonEmpty7,
|
|
1491
1491
|
title: nonEmpty7,
|
|
1492
1492
|
visibility: conversationVisibilitySchema,
|
|
1493
1493
|
/** The conversation's page. */
|
|
1494
1494
|
url: nonEmpty7,
|
|
1495
1495
|
/** Its thread on its platform, when it has a link. */
|
|
1496
|
-
placeUrl:
|
|
1496
|
+
placeUrl: z13.string().nullable(),
|
|
1497
1497
|
state: conversationStateSchema,
|
|
1498
1498
|
// A reason this version no longer gives, such as one stored before it, reads as none.
|
|
1499
1499
|
reason: stuckReasonSchema.nullable().catch(null),
|
|
1500
1500
|
/** The start of the latest waking message. */
|
|
1501
|
-
latestRequest:
|
|
1501
|
+
latestRequest: z13.string().nullable(),
|
|
1502
1502
|
lastRequestAt: time5.nullable(),
|
|
1503
1503
|
/** When the bot last posted in the thread. */
|
|
1504
1504
|
lastReplyAt: time5.nullable(),
|
|
1505
1505
|
/** What the agent says it's doing, while it works. */
|
|
1506
|
-
activity:
|
|
1506
|
+
activity: z13.string().nullable(),
|
|
1507
1507
|
/** The machine holding it, by name and presence only, and whether it's the reader's own. */
|
|
1508
1508
|
machine: listMachineSchema.nullable(),
|
|
1509
1509
|
lastActivityAt: time5,
|
|
@@ -1514,28 +1514,28 @@ var init_conversation_state = __esm({
|
|
|
1514
1514
|
/** When its activity last changed, which says how long an agent has been quiet. */
|
|
1515
1515
|
activityAt: time5.nullable().optional(),
|
|
1516
1516
|
/** Set when the title, latest request, link and activity were left out because it's private. */
|
|
1517
|
-
hidden:
|
|
1517
|
+
hidden: z13.boolean().optional(),
|
|
1518
1518
|
/**
|
|
1519
1519
|
* What it's about, its delegates' included: at most 5, open ones first. Missing, from servers
|
|
1520
1520
|
* older than work objects, means none.
|
|
1521
1521
|
*/
|
|
1522
|
-
work:
|
|
1522
|
+
work: z13.array(workObjectSummarySchema).optional(),
|
|
1523
1523
|
/** How many more work objects it holds than `work` carries. */
|
|
1524
|
-
moreWork:
|
|
1524
|
+
moreWork: z13.number().int().nonnegative().optional(),
|
|
1525
1525
|
/** The pull request it leads with, from all of its tree's, not only those in `work`. */
|
|
1526
1526
|
lead: leadChangeSchema.nullable().optional()
|
|
1527
1527
|
});
|
|
1528
|
-
conversationListSchema =
|
|
1529
|
-
items:
|
|
1528
|
+
conversationListSchema = z13.object({
|
|
1529
|
+
items: z13.array(conversationListItemSchema),
|
|
1530
1530
|
/** Present when there's more, to pass back as `next` for the following page. */
|
|
1531
|
-
next:
|
|
1531
|
+
next: z13.string().optional()
|
|
1532
1532
|
});
|
|
1533
|
-
listFrameSchema =
|
|
1534
|
-
|
|
1533
|
+
listFrameSchema = z13.discriminatedUnion("type", [
|
|
1534
|
+
z13.object({ type: z13.literal("changed"), conversations: z13.array(nonEmpty7).min(1) }),
|
|
1535
1535
|
/** A machine went online or offline, or a worker's usage changed. */
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1536
|
+
z13.object({ type: z13.literal("machines") }),
|
|
1537
|
+
z13.object({ type: z13.literal("reconnect") }),
|
|
1538
|
+
z13.object({ type: z13.literal("expired") })
|
|
1539
1539
|
]);
|
|
1540
1540
|
STATE_REACTIONS = {
|
|
1541
1541
|
stuck: REACTIONS.stuck,
|
|
@@ -1574,7 +1574,7 @@ var init_conversation_state = __esm({
|
|
|
1574
1574
|
});
|
|
1575
1575
|
|
|
1576
1576
|
// ../common-chat/src/board.ts
|
|
1577
|
-
import { z as
|
|
1577
|
+
import { z as z14 } from "zod";
|
|
1578
1578
|
var nonEmpty8, time6, BOARD_ITEMS, boardItemSchema, boardWorkerSchema, boardMachineSchema, boardSchema;
|
|
1579
1579
|
var init_board = __esm({
|
|
1580
1580
|
"../common-chat/src/board.ts"() {
|
|
@@ -1583,27 +1583,27 @@ var init_board = __esm({
|
|
|
1583
1583
|
init_conversation_state();
|
|
1584
1584
|
init_pull_requests();
|
|
1585
1585
|
init_usage();
|
|
1586
|
-
nonEmpty8 =
|
|
1587
|
-
time6 =
|
|
1586
|
+
nonEmpty8 = z14.string().min(1);
|
|
1587
|
+
time6 = z14.number().int().nonnegative();
|
|
1588
1588
|
BOARD_ITEMS = 8;
|
|
1589
|
-
boardItemSchema =
|
|
1589
|
+
boardItemSchema = z14.object({
|
|
1590
1590
|
id: nonEmpty8,
|
|
1591
1591
|
/** `HIDDEN_TITLE` when the item is private and the board doesn't show private titles. */
|
|
1592
1592
|
title: nonEmpty8,
|
|
1593
1593
|
state: conversationStateSchema,
|
|
1594
1594
|
reason: stuckReasonSchema.nullable().catch(null),
|
|
1595
1595
|
/** Where the work came from, such as `#herd-dev` or a direct message, when it's known. */
|
|
1596
|
-
source:
|
|
1596
|
+
source: z14.string().nullable(),
|
|
1597
1597
|
/** What the agent says it's doing, while it works. */
|
|
1598
|
-
activity:
|
|
1598
|
+
activity: z14.string().nullable(),
|
|
1599
1599
|
lastActivityAt: time6,
|
|
1600
1600
|
/** The machine and agent holding it, such as `mac-mini` and `Claude Code`, once it's bound. */
|
|
1601
|
-
heldBy:
|
|
1601
|
+
heldBy: z14.object({ machine: nonEmpty8, agent: nonEmpty8 }).nullable().optional(),
|
|
1602
1602
|
/** The pull request it leads with, and how many more are the person's move. */
|
|
1603
1603
|
change: leadChangeSchema.nullable().optional(),
|
|
1604
|
-
hidden:
|
|
1604
|
+
hidden: z14.boolean().optional()
|
|
1605
1605
|
});
|
|
1606
|
-
boardWorkerSchema =
|
|
1606
|
+
boardWorkerSchema = z14.object({
|
|
1607
1607
|
/** The worker's short name, such as `claude`, under its machine. */
|
|
1608
1608
|
name: nonEmpty8,
|
|
1609
1609
|
/** Its agent CLI, such as `claude-code`, which names it on the board. */
|
|
@@ -1612,33 +1612,33 @@ var init_board = __esm({
|
|
|
1612
1612
|
usage: usageSchema.nullable(),
|
|
1613
1613
|
reportedAt: time6.nullable(),
|
|
1614
1614
|
/** What it's great at, from its profile: its owner's statements, or herd's defaults. */
|
|
1615
|
-
strengths:
|
|
1615
|
+
strengths: z14.array(z14.string().min(1).max(100)).max(3).optional()
|
|
1616
1616
|
});
|
|
1617
|
-
boardMachineSchema =
|
|
1617
|
+
boardMachineSchema = z14.object({
|
|
1618
1618
|
name: nonEmpty8,
|
|
1619
|
-
online:
|
|
1620
|
-
workers:
|
|
1619
|
+
online: z14.boolean(),
|
|
1620
|
+
workers: z14.array(boardWorkerSchema).max(8)
|
|
1621
1621
|
});
|
|
1622
|
-
boardSchema =
|
|
1622
|
+
boardSchema = z14.object({
|
|
1623
1623
|
/** How many are in each open state: every state but `done`, which is counted for the last day. */
|
|
1624
|
-
counts:
|
|
1625
|
-
stuck:
|
|
1626
|
-
unanswered:
|
|
1627
|
-
waiting:
|
|
1628
|
-
working:
|
|
1624
|
+
counts: z14.object({
|
|
1625
|
+
stuck: z14.number().int().nonnegative(),
|
|
1626
|
+
unanswered: z14.number().int().nonnegative(),
|
|
1627
|
+
waiting: z14.number().int().nonnegative(),
|
|
1628
|
+
working: z14.number().int().nonnegative(),
|
|
1629
1629
|
/** Open pull requests the person's conversations made that are their move, each counted. */
|
|
1630
|
-
pullRequests:
|
|
1630
|
+
pullRequests: z14.number().int().nonnegative().optional()
|
|
1631
1631
|
}),
|
|
1632
1632
|
/** How many became `done` in the last 24 hours. */
|
|
1633
|
-
doneToday:
|
|
1633
|
+
doneToday: z14.number().int().nonnegative(),
|
|
1634
1634
|
/**
|
|
1635
1635
|
* What needs the person (stuck, then pull requests that are their move), then what's working or
|
|
1636
1636
|
* has a pull request under way, then what's queued, then the latest finished to fill the rest.
|
|
1637
1637
|
*/
|
|
1638
|
-
items:
|
|
1639
|
-
machines:
|
|
1638
|
+
items: z14.array(boardItemSchema).max(BOARD_ITEMS),
|
|
1639
|
+
machines: z14.array(boardMachineSchema).max(16),
|
|
1640
1640
|
/** Changes whenever anything the board shows changes, and only then. */
|
|
1641
|
-
stamp:
|
|
1641
|
+
stamp: z14.string().regex(/^[0-9a-f]{12}$/),
|
|
1642
1642
|
/** When its content last changed. */
|
|
1643
1643
|
changedAt: time6
|
|
1644
1644
|
});
|
|
@@ -1646,41 +1646,44 @@ var init_board = __esm({
|
|
|
1646
1646
|
});
|
|
1647
1647
|
|
|
1648
1648
|
// ../common-chat/src/bot.ts
|
|
1649
|
-
var BOT_NAME;
|
|
1649
|
+
var BOT_NAME, NPM_SCOPE, FRIDAY_PACKAGE, START_COMMAND;
|
|
1650
1650
|
var init_bot = __esm({
|
|
1651
1651
|
"../common-chat/src/bot.ts"() {
|
|
1652
1652
|
"use strict";
|
|
1653
1653
|
init_define_HERD_PACKAGE();
|
|
1654
1654
|
BOT_NAME = "Friday";
|
|
1655
|
+
NPM_SCOPE = "@herdingchats";
|
|
1656
|
+
FRIDAY_PACKAGE = `${NPM_SCOPE}/friday`;
|
|
1657
|
+
START_COMMAND = `npx ${FRIDAY_PACKAGE} start`;
|
|
1655
1658
|
}
|
|
1656
1659
|
});
|
|
1657
1660
|
|
|
1658
1661
|
// ../common-chat/src/builds.ts
|
|
1659
|
-
import { z as
|
|
1662
|
+
import { z as z15 } from "zod";
|
|
1660
1663
|
var nonEmpty9, time7, BUILD_LEASE_MS, BUILD_CLAIM_WINDOW_MS, MAX_LOG_CHUNK_BYTES, MAX_LOG_BYTES, MAX_NODE_MODULES_PART_BYTES, shaSchema, buildOfferSchema, buildCancelReasonSchema, runnerMessageSchema, serviceMessageSchema, runnerRegisterRequestSchema, runnerRegisterResponseSchema, runnerPollRequestSchema, runnerPollResponseSchema, buildStepSchema, buildFinishSchema, sharedPassSchema, passesResponseSchema, deployCredentialsSchema, deployedSchema, healthSchema;
|
|
1661
1664
|
var init_builds = __esm({
|
|
1662
1665
|
"../common-chat/src/builds.ts"() {
|
|
1663
1666
|
"use strict";
|
|
1664
1667
|
init_define_HERD_PACKAGE();
|
|
1665
1668
|
init_workers();
|
|
1666
|
-
nonEmpty9 =
|
|
1667
|
-
time7 =
|
|
1669
|
+
nonEmpty9 = z15.string().min(1);
|
|
1670
|
+
time7 = z15.number().int().nonnegative();
|
|
1668
1671
|
BUILD_LEASE_MS = 5 * 60 * 1e3;
|
|
1669
1672
|
BUILD_CLAIM_WINDOW_MS = 15 * 1e3;
|
|
1670
1673
|
MAX_LOG_CHUNK_BYTES = 256 * 1024;
|
|
1671
1674
|
MAX_LOG_BYTES = 5 * 1024 * 1024;
|
|
1672
1675
|
MAX_NODE_MODULES_PART_BYTES = 95 * 1024 * 1024;
|
|
1673
|
-
shaSchema =
|
|
1674
|
-
buildOfferSchema =
|
|
1676
|
+
shaSchema = z15.string().regex(/^[0-9a-f]{40}$/);
|
|
1677
|
+
buildOfferSchema = z15.object({
|
|
1675
1678
|
id: nonEmpty9,
|
|
1676
1679
|
offerId: nonEmpty9,
|
|
1677
1680
|
repo: nonEmpty9,
|
|
1678
1681
|
sha: shaSchema,
|
|
1679
1682
|
ref: nonEmpty9,
|
|
1680
|
-
main:
|
|
1683
|
+
main: z15.boolean(),
|
|
1681
1684
|
expiresAt: time7
|
|
1682
1685
|
});
|
|
1683
|
-
buildCancelReasonSchema =
|
|
1686
|
+
buildCancelReasonSchema = z15.enum([
|
|
1684
1687
|
// A newer push to the same branch replaced it.
|
|
1685
1688
|
"superseded",
|
|
1686
1689
|
// The branch was deleted.
|
|
@@ -1690,7 +1693,7 @@ var init_builds = __esm({
|
|
|
1690
1693
|
// Stopped for another reason, such as the repo being removed.
|
|
1691
1694
|
"cancelled"
|
|
1692
1695
|
]);
|
|
1693
|
-
runnerMessageSchema =
|
|
1696
|
+
runnerMessageSchema = z15.discriminatedUnion("type", [
|
|
1694
1697
|
/**
|
|
1695
1698
|
* Sent first, and again whenever any of it changes. `capacity` comes from `herd.config.ts`'s
|
|
1696
1699
|
* `builds` through `runnerCapacity`, `repos` are the normalized remotes of the repos herd has
|
|
@@ -1698,82 +1701,82 @@ var init_builds = __esm({
|
|
|
1698
1701
|
* any of its owner's repos, cloning one it hasn't got, and `repos` only puts it first for those.
|
|
1699
1702
|
* A daemon from before herd's root sent its configured checkouts here, which it builds from.
|
|
1700
1703
|
*/
|
|
1701
|
-
|
|
1702
|
-
type:
|
|
1704
|
+
z15.object({
|
|
1705
|
+
type: z15.literal("hello"),
|
|
1703
1706
|
/** How many builds at once. 0 when the machine can't sandbox a build, so it takes none. */
|
|
1704
|
-
capacity:
|
|
1705
|
-
repos:
|
|
1706
|
-
running:
|
|
1707
|
+
capacity: z15.number().int().min(0).max(BUILDS_MAX),
|
|
1708
|
+
repos: z15.array(nonEmpty9.max(300)).max(100),
|
|
1709
|
+
running: z15.array(nonEmpty9.max(100)).max(BUILDS_MAX * 2)
|
|
1707
1710
|
}),
|
|
1708
1711
|
/** An answer to an offer, before its `expiresAt`. A refusal may say why. */
|
|
1709
|
-
|
|
1710
|
-
type:
|
|
1712
|
+
z15.object({
|
|
1713
|
+
type: z15.literal("answer"),
|
|
1711
1714
|
buildId: nonEmpty9,
|
|
1712
1715
|
offerId: nonEmpty9,
|
|
1713
|
-
answer:
|
|
1714
|
-
reason:
|
|
1716
|
+
answer: z15.enum(["accept", "refuse"]),
|
|
1717
|
+
reason: z15.string().max(500).optional()
|
|
1715
1718
|
})
|
|
1716
1719
|
]);
|
|
1717
|
-
serviceMessageSchema =
|
|
1718
|
-
|
|
1720
|
+
serviceMessageSchema = z15.discriminatedUnion("type", [
|
|
1721
|
+
z15.object({ type: z15.literal("build"), build: buildOfferSchema }),
|
|
1719
1722
|
/** An accepted offer: the build's own secret, and how long its claim lasts between renewals. */
|
|
1720
|
-
|
|
1721
|
-
type:
|
|
1723
|
+
z15.object({
|
|
1724
|
+
type: z15.literal("accepted"),
|
|
1722
1725
|
buildId: nonEmpty9,
|
|
1723
1726
|
secret: nonEmpty9,
|
|
1724
|
-
leaseMs:
|
|
1727
|
+
leaseMs: z15.number().int().positive()
|
|
1725
1728
|
}),
|
|
1726
1729
|
/**
|
|
1727
1730
|
* Stop a build this runner holds, within 5 seconds. An accept that came too late, for an offer
|
|
1728
1731
|
* that had expired or was withdrawn, gets this too, with the reason `cancelled`.
|
|
1729
1732
|
*/
|
|
1730
|
-
|
|
1733
|
+
z15.object({ type: z15.literal("build-cancel"), buildId: nonEmpty9, reason: buildCancelReasonSchema }),
|
|
1731
1734
|
/** Connect again. Sent before the service closes a socket that another replaced. */
|
|
1732
|
-
|
|
1735
|
+
z15.object({ type: z15.literal("reconnect") })
|
|
1733
1736
|
]);
|
|
1734
|
-
runnerRegisterRequestSchema =
|
|
1735
|
-
runnerRegisterResponseSchema =
|
|
1737
|
+
runnerRegisterRequestSchema = z15.object({ name: z15.string().trim().min(1).max(100) });
|
|
1738
|
+
runnerRegisterResponseSchema = z15.object({
|
|
1736
1739
|
/** Shown to the owner, so they can match the approval page to the machine. */
|
|
1737
1740
|
code: nonEmpty9,
|
|
1738
1741
|
/** The page the owner opens, signed in, to approve it. */
|
|
1739
|
-
approveUrl:
|
|
1742
|
+
approveUrl: z15.url(),
|
|
1740
1743
|
/** Sent to `POST /runners/register/poll`. Only this machine has it. */
|
|
1741
1744
|
pollToken: nonEmpty9,
|
|
1742
1745
|
expiresAt: time7.optional(),
|
|
1743
1746
|
/** How often to poll. */
|
|
1744
|
-
pollMs:
|
|
1747
|
+
pollMs: z15.number().int().positive().optional()
|
|
1745
1748
|
});
|
|
1746
|
-
runnerPollRequestSchema =
|
|
1747
|
-
runnerPollResponseSchema =
|
|
1748
|
-
|
|
1749
|
+
runnerPollRequestSchema = z15.object({ pollToken: nonEmpty9.max(200) });
|
|
1750
|
+
runnerPollResponseSchema = z15.discriminatedUnion("status", [
|
|
1751
|
+
z15.object({ status: z15.literal("waiting") }),
|
|
1749
1752
|
/** Approved. The key is returned this once, and the service keeps only its hash. */
|
|
1750
|
-
|
|
1753
|
+
z15.object({ status: z15.literal("approved"), runnerId: nonEmpty9, key: nonEmpty9 }),
|
|
1751
1754
|
/** Expired, or the key was already collected. Start again. */
|
|
1752
|
-
|
|
1755
|
+
z15.object({ status: z15.literal("expired") })
|
|
1753
1756
|
]);
|
|
1754
|
-
buildStepSchema =
|
|
1755
|
-
label:
|
|
1756
|
-
key:
|
|
1757
|
-
status:
|
|
1758
|
-
ms:
|
|
1757
|
+
buildStepSchema = z15.object({
|
|
1758
|
+
label: z15.string().min(1).max(200),
|
|
1759
|
+
key: z15.string().regex(/^[0-9a-zA-Z_-]{8,128}$/),
|
|
1760
|
+
status: z15.enum(["passed", "failed", "remembered"]),
|
|
1761
|
+
ms: z15.number().int().nonnegative(),
|
|
1759
1762
|
/** Only some of the step's tests ran, so its pass isn't shared. */
|
|
1760
|
-
partial:
|
|
1761
|
-
budgetMs:
|
|
1763
|
+
partial: z15.boolean().default(false),
|
|
1764
|
+
budgetMs: z15.number().int().positive().nullable().default(null)
|
|
1762
1765
|
});
|
|
1763
|
-
buildFinishSchema =
|
|
1764
|
-
status:
|
|
1765
|
-
summary:
|
|
1766
|
-
deployed:
|
|
1766
|
+
buildFinishSchema = z15.object({
|
|
1767
|
+
status: z15.enum(["success", "failure", "error"]),
|
|
1768
|
+
summary: z15.string().max(2e3).default(""),
|
|
1769
|
+
deployed: z15.boolean().default(false)
|
|
1767
1770
|
});
|
|
1768
|
-
sharedPassSchema =
|
|
1771
|
+
sharedPassSchema = z15.object({
|
|
1769
1772
|
step: nonEmpty9,
|
|
1770
1773
|
passedAt: time7,
|
|
1771
1774
|
sha: nonEmpty9,
|
|
1772
1775
|
runner: nonEmpty9,
|
|
1773
|
-
partial:
|
|
1776
|
+
partial: z15.boolean()
|
|
1774
1777
|
});
|
|
1775
|
-
passesResponseSchema =
|
|
1776
|
-
deployCredentialsSchema =
|
|
1778
|
+
passesResponseSchema = z15.object({ passes: z15.record(z15.string(), sharedPassSchema) });
|
|
1779
|
+
deployCredentialsSchema = z15.object({
|
|
1777
1780
|
cloudflareToken: nonEmpty9,
|
|
1778
1781
|
/** Publishes `@herdingchats/friday`. Missing when the build service has none set. */
|
|
1779
1782
|
npmToken: nonEmpty9.optional(),
|
|
@@ -1782,20 +1785,20 @@ var init_builds = __esm({
|
|
|
1782
1785
|
/** `owner/name`, for moving `deployed`. */
|
|
1783
1786
|
repo: nonEmpty9,
|
|
1784
1787
|
/** The commit being built, which `deployed` moves to. Older services don't send it. */
|
|
1785
|
-
sha:
|
|
1788
|
+
sha: z15.string().regex(/^[0-9a-f]{40}$/).optional(),
|
|
1786
1789
|
/** Each Worker's key at its last successful deploy. */
|
|
1787
|
-
lastDeployed:
|
|
1790
|
+
lastDeployed: z15.record(z15.string(), z15.string())
|
|
1788
1791
|
});
|
|
1789
|
-
deployedSchema =
|
|
1790
|
-
worker:
|
|
1791
|
-
key:
|
|
1792
|
+
deployedSchema = z15.object({
|
|
1793
|
+
worker: z15.string().regex(/^[a-z][a-z0-9-]{0,62}$/),
|
|
1794
|
+
key: z15.string().regex(/^[0-9a-zA-Z_-]{8,128}$/)
|
|
1792
1795
|
});
|
|
1793
|
-
healthSchema =
|
|
1796
|
+
healthSchema = z15.object({ ok: z15.boolean(), version: z15.string() });
|
|
1794
1797
|
}
|
|
1795
1798
|
});
|
|
1796
1799
|
|
|
1797
1800
|
// ../common-chat/src/setup.ts
|
|
1798
|
-
import { z as
|
|
1801
|
+
import { z as z16 } from "zod";
|
|
1799
1802
|
function actionText(action) {
|
|
1800
1803
|
if (action.kind === "link") return `${action.label}: ${action.url}`;
|
|
1801
1804
|
if (action.kind === "sign_in") {
|
|
@@ -1830,42 +1833,42 @@ var init_setup = __esm({
|
|
|
1830
1833
|
init_activation();
|
|
1831
1834
|
init_bot();
|
|
1832
1835
|
SETUP_STEP_IDS = ["slack", "machine", "github", "repos"];
|
|
1833
|
-
setupActionSchema =
|
|
1836
|
+
setupActionSchema = z16.discriminatedUnion("kind", [
|
|
1834
1837
|
/** A page to open, which signs in to HerdingChats first. */
|
|
1835
|
-
|
|
1838
|
+
z16.object({ kind: z16.literal("link"), url: z16.string(), label: z16.string() }),
|
|
1836
1839
|
/** A command to run on the computer. */
|
|
1837
|
-
|
|
1840
|
+
z16.object({ kind: z16.literal("command"), command: z16.string() }),
|
|
1838
1841
|
/**
|
|
1839
1842
|
* A sign-in herd starts on one of the person's machines, from Slack or the page, whose code
|
|
1840
1843
|
* Friday sends to their direct message.
|
|
1841
1844
|
*/
|
|
1842
|
-
|
|
1843
|
-
kind:
|
|
1844
|
-
machineId:
|
|
1845
|
+
z16.object({
|
|
1846
|
+
kind: z16.literal("sign_in"),
|
|
1847
|
+
machineId: z16.string(),
|
|
1845
1848
|
tool: signInToolSchema,
|
|
1846
|
-
label:
|
|
1849
|
+
label: z16.string()
|
|
1847
1850
|
})
|
|
1848
1851
|
]);
|
|
1849
|
-
setupStepSchema =
|
|
1850
|
-
id:
|
|
1852
|
+
setupStepSchema = z16.object({
|
|
1853
|
+
id: z16.enum(SETUP_STEP_IDS),
|
|
1851
1854
|
/** `unavailable` is a step nobody can take yet, such as GitHub linking before an admin turns it on. */
|
|
1852
|
-
state:
|
|
1853
|
-
optional:
|
|
1854
|
-
title:
|
|
1855
|
+
state: z16.enum(["done", "todo", "unavailable"]),
|
|
1856
|
+
optional: z16.boolean(),
|
|
1857
|
+
title: z16.string(),
|
|
1855
1858
|
/** What was found, such as the machine and whether it's online, or why it can't be done yet. */
|
|
1856
|
-
detail:
|
|
1859
|
+
detail: z16.string().nullable(),
|
|
1857
1860
|
/** What to do next. None once it's done, or while it's unavailable. */
|
|
1858
1861
|
action: setupActionSchema.nullable(),
|
|
1859
1862
|
/**
|
|
1860
1863
|
* More that can be done, which doesn't decide whether the step is done, such as signing in a
|
|
1861
1864
|
* computer's GitHub CLI. Shown whatever the step's state.
|
|
1862
1865
|
*/
|
|
1863
|
-
extra:
|
|
1866
|
+
extra: z16.array(setupActionSchema).optional()
|
|
1864
1867
|
});
|
|
1865
|
-
setupStatusSchema =
|
|
1866
|
-
steps:
|
|
1868
|
+
setupStatusSchema = z16.object({
|
|
1869
|
+
steps: z16.array(setupStepSchema),
|
|
1867
1870
|
/** Whether every step that isn't optional is done, so Friday can take work. */
|
|
1868
|
-
ready:
|
|
1871
|
+
ready: z16.boolean()
|
|
1869
1872
|
});
|
|
1870
1873
|
READY_TEXT = `You're set up: mention @${BOT_NAME} in any channel it's in, or message it directly.`;
|
|
1871
1874
|
READY_SUGGESTIONS_TITLE = "Some things to try:";
|
|
@@ -3135,6 +3138,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
3135
3138
|
|
|
3136
3139
|
// src/friday/main.ts
|
|
3137
3140
|
init_define_HERD_PACKAGE();
|
|
3141
|
+
init_src();
|
|
3138
3142
|
import { spawn as spawn5 } from "node:child_process";
|
|
3139
3143
|
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
|
|
3140
3144
|
import { homedir as homedir4 } from "node:os";
|
|
@@ -3148,21 +3152,21 @@ import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:
|
|
|
3148
3152
|
import { createServer } from "node:http";
|
|
3149
3153
|
import { homedir } from "node:os";
|
|
3150
3154
|
import { join } from "node:path";
|
|
3151
|
-
import { z } from "zod";
|
|
3155
|
+
import { z as z17 } from "zod";
|
|
3152
3156
|
var herdHome = () => process.env.HERD_HOME ?? join(homedir(), ".herd");
|
|
3153
3157
|
var apiUrl = () => (process.env.HERD_API_URL ?? "https://api.herdingchats.com").replace(/\/+$/, "");
|
|
3154
3158
|
var isLocal = (url) => /^http:\/\/localhost:\d+\/?$/.test(url);
|
|
3155
3159
|
var localSignIn = () => process.env.HERD_LOCAL_SLACK ? { "X-Herd-Local-Slack": process.env.HERD_LOCAL_SLACK } : {};
|
|
3156
3160
|
var HerdError = class extends Error {
|
|
3157
3161
|
};
|
|
3158
|
-
var credentialsSchema =
|
|
3159
|
-
api:
|
|
3160
|
-
tokenEndpoint:
|
|
3161
|
-
revocationEndpoint:
|
|
3162
|
-
clientId:
|
|
3163
|
-
accessToken:
|
|
3164
|
-
accessTokenExpiresAt:
|
|
3165
|
-
refreshToken:
|
|
3162
|
+
var credentialsSchema = z17.object({
|
|
3163
|
+
api: z17.string(),
|
|
3164
|
+
tokenEndpoint: z17.string(),
|
|
3165
|
+
revocationEndpoint: z17.string().optional(),
|
|
3166
|
+
clientId: z17.string(),
|
|
3167
|
+
accessToken: z17.string(),
|
|
3168
|
+
accessTokenExpiresAt: z17.number(),
|
|
3169
|
+
refreshToken: z17.string()
|
|
3166
3170
|
});
|
|
3167
3171
|
var credentialsPath = () => join(herdHome(), "credentials.json");
|
|
3168
3172
|
function readCredentials() {
|
|
@@ -3178,16 +3182,16 @@ function writeCredentials(credentials) {
|
|
|
3178
3182
|
writeFileSync(credentialsPath(), JSON.stringify(credentials, null, 2), { mode: 384 });
|
|
3179
3183
|
chmodSync(credentialsPath(), 384);
|
|
3180
3184
|
}
|
|
3181
|
-
var metadataSchema =
|
|
3182
|
-
authorization_endpoint:
|
|
3183
|
-
token_endpoint:
|
|
3184
|
-
registration_endpoint:
|
|
3185
|
-
revocation_endpoint:
|
|
3185
|
+
var metadataSchema = z17.object({
|
|
3186
|
+
authorization_endpoint: z17.string(),
|
|
3187
|
+
token_endpoint: z17.string(),
|
|
3188
|
+
registration_endpoint: z17.string(),
|
|
3189
|
+
revocation_endpoint: z17.string().optional()
|
|
3186
3190
|
});
|
|
3187
|
-
var tokenSchema =
|
|
3188
|
-
access_token:
|
|
3189
|
-
refresh_token:
|
|
3190
|
-
expires_in:
|
|
3191
|
+
var tokenSchema = z17.object({
|
|
3192
|
+
access_token: z17.string().min(1),
|
|
3193
|
+
refresh_token: z17.string().min(1),
|
|
3194
|
+
expires_in: z17.number()
|
|
3191
3195
|
});
|
|
3192
3196
|
var base64url = (bytes) => bytes.toString("base64url");
|
|
3193
3197
|
async function postForm(url, fields) {
|
|
@@ -3219,7 +3223,7 @@ async function login(openBrowser2, { api = apiUrl(), timeoutMs = 10 * 60 * 1e3 }
|
|
|
3219
3223
|
token_endpoint_auth_method: "none"
|
|
3220
3224
|
})
|
|
3221
3225
|
});
|
|
3222
|
-
const client =
|
|
3226
|
+
const client = z17.object({ client_id: z17.string() }).safeParse(await registration2.json());
|
|
3223
3227
|
if (!registration2.ok || !client.success) {
|
|
3224
3228
|
throw new HerdError("The sign-in server refused to register this tool.");
|
|
3225
3229
|
}
|
|
@@ -5153,6 +5157,7 @@ var herdConfigIn = (herdHome2) => join7(herdHome2, "herd.config.ts");
|
|
|
5153
5157
|
|
|
5154
5158
|
// src/friday/home.ts
|
|
5155
5159
|
init_define_HERD_PACKAGE();
|
|
5160
|
+
init_src();
|
|
5156
5161
|
import { spawnSync } from "node:child_process";
|
|
5157
5162
|
import {
|
|
5158
5163
|
closeSync as closeSync2,
|
|
@@ -5165,7 +5170,7 @@ import {
|
|
|
5165
5170
|
writeFileSync as writeFileSync6
|
|
5166
5171
|
} from "node:fs";
|
|
5167
5172
|
import { dirname as dirname6, join as join8, resolve as resolve2 } from "node:path";
|
|
5168
|
-
var PACKAGE_NAME =
|
|
5173
|
+
var PACKAGE_NAME = FRIDAY_PACKAGE;
|
|
5169
5174
|
function fridayPaths(herdHome2) {
|
|
5170
5175
|
const logs = join8(herdHome2, "logs");
|
|
5171
5176
|
return {
|
|
@@ -5884,7 +5889,7 @@ async function ensureInstalled(options, print) {
|
|
|
5884
5889
|
if (current && !await versionRuns(paths.current, current, options.run)) return;
|
|
5885
5890
|
if (version === "dev" && !options.install?.spec) {
|
|
5886
5891
|
throw new StartError(
|
|
5887
|
-
|
|
5892
|
+
`This friday runs from the repo, which has no version to install. Run ${START_COMMAND}, or npx herd daemon to watch a daemon in the foreground.`
|
|
5888
5893
|
);
|
|
5889
5894
|
}
|
|
5890
5895
|
print(`Installing Friday ${version}.`);
|
|
@@ -6288,7 +6293,7 @@ function runStatus(deps) {
|
|
|
6288
6293
|
pin = "";
|
|
6289
6294
|
}
|
|
6290
6295
|
if (!version && !running) {
|
|
6291
|
-
print(
|
|
6296
|
+
print(`Friday isn't set up on this computer. Run ${START_COMMAND} in its root.`);
|
|
6292
6297
|
return 1;
|
|
6293
6298
|
}
|
|
6294
6299
|
const daemon = running && status2.daemonPid && alive2(status2.daemonPid);
|