@herdingchats/friday 0.1.660 → 0.1.663
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 +739 -652
- package/package.json +2 -2
package/herd.mjs
CHANGED
|
@@ -18,7 +18,7 @@ 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.663", gitHead: "8ba46f6a5262b074559ade9422eb6ff6a3326b3f" };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
|
|
@@ -472,8 +472,69 @@ var init_github = __esm({
|
|
|
472
472
|
}
|
|
473
473
|
});
|
|
474
474
|
|
|
475
|
-
// ../common-chat/src/
|
|
475
|
+
// ../common-chat/src/terminals.ts
|
|
476
476
|
import { z as z6 } from "zod";
|
|
477
|
+
var terminalAccessSchema, machineTerminalsSchema, terminalModeSchema, terminalTargetSchema, terminalClosedReasonSchema, size, terminalFrameSchema, TERMINAL_DIAL_MS, TERMINAL_IDLE_MS, TERMINAL_MAX_MS, TERMINAL_PROOF_MS;
|
|
478
|
+
var init_terminals = __esm({
|
|
479
|
+
"../common-chat/src/terminals.ts"() {
|
|
480
|
+
"use strict";
|
|
481
|
+
init_define_HERD_PACKAGE();
|
|
482
|
+
terminalAccessSchema = z6.enum(["drive", "watch", "off"]);
|
|
483
|
+
machineTerminalsSchema = z6.object({ remote: terminalAccessSchema });
|
|
484
|
+
terminalModeSchema = z6.enum(["watch", "drive"]);
|
|
485
|
+
terminalTargetSchema = z6.discriminatedUnion("kind", [
|
|
486
|
+
z6.object({ kind: z6.literal("conversation"), conversationId: z6.string().min(1) }),
|
|
487
|
+
z6.object({ kind: z6.literal("activation"), agent: z6.string().min(1) })
|
|
488
|
+
]);
|
|
489
|
+
terminalClosedReasonSchema = z6.enum([
|
|
490
|
+
// The page closed it, or the person let it go.
|
|
491
|
+
"closed",
|
|
492
|
+
// The machine never dialed, or its socket dropped.
|
|
493
|
+
"expired",
|
|
494
|
+
"machine_gone",
|
|
495
|
+
// Its limits: no input for a while, too long in all, or the browser's sign-in is due a check.
|
|
496
|
+
"idle",
|
|
497
|
+
"too_long",
|
|
498
|
+
"reauthorize",
|
|
499
|
+
// A newer session took its place on the machine.
|
|
500
|
+
"superseded",
|
|
501
|
+
// The machine wouldn't open it, saying why in `detail`.
|
|
502
|
+
"refused",
|
|
503
|
+
// The terminal itself exited.
|
|
504
|
+
"exited"
|
|
505
|
+
]);
|
|
506
|
+
size = {
|
|
507
|
+
cols: z6.number().int().min(10).max(1e3),
|
|
508
|
+
rows: z6.number().int().min(5).max(1e3)
|
|
509
|
+
};
|
|
510
|
+
terminalFrameSchema = z6.discriminatedUnion("type", [
|
|
511
|
+
z6.object({ type: z6.literal("snapshot"), data: z6.string() }),
|
|
512
|
+
z6.object({ type: z6.literal("data"), data: z6.string() }),
|
|
513
|
+
z6.object({ type: z6.literal("exit"), exitCode: z6.number().int().nullable() }),
|
|
514
|
+
z6.object({ type: z6.literal("mode"), mode: terminalModeSchema }),
|
|
515
|
+
z6.object({ type: z6.literal("input"), data: z6.string().max(64 * 1024) }),
|
|
516
|
+
z6.object({ type: z6.literal("resize"), ...size }),
|
|
517
|
+
z6.object({ type: z6.literal("drive") }),
|
|
518
|
+
z6.object({ type: z6.literal("watch") }),
|
|
519
|
+
z6.object({
|
|
520
|
+
type: z6.literal("closed"),
|
|
521
|
+
reason: terminalClosedReasonSchema,
|
|
522
|
+
detail: z6.string().max(500).optional()
|
|
523
|
+
}),
|
|
524
|
+
z6.object({
|
|
525
|
+
type: z6.literal("refused"),
|
|
526
|
+
code: z6.enum(["confirmation_needed", "watch_only", "not_driving"])
|
|
527
|
+
})
|
|
528
|
+
]);
|
|
529
|
+
TERMINAL_DIAL_MS = 60 * 1e3;
|
|
530
|
+
TERMINAL_IDLE_MS = 15 * 60 * 1e3;
|
|
531
|
+
TERMINAL_MAX_MS = 2 * 60 * 60 * 1e3;
|
|
532
|
+
TERMINAL_PROOF_MS = 60 * 60 * 1e3;
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// ../common-chat/src/usage.ts
|
|
537
|
+
import { z as z7 } from "zod";
|
|
477
538
|
function currentUsage(usage, now) {
|
|
478
539
|
if (!usage) return void 0;
|
|
479
540
|
const fresh = (window) => window && window.resetsAt > now ? window : void 0;
|
|
@@ -491,38 +552,38 @@ var init_usage = __esm({
|
|
|
491
552
|
"../common-chat/src/usage.ts"() {
|
|
492
553
|
"use strict";
|
|
493
554
|
init_define_HERD_PACKAGE();
|
|
494
|
-
usageWindowSchema =
|
|
495
|
-
usedPercentage:
|
|
496
|
-
resetsAt:
|
|
555
|
+
usageWindowSchema = z7.object({
|
|
556
|
+
usedPercentage: z7.number().min(0).max(100),
|
|
557
|
+
resetsAt: z7.number().int().nonnegative()
|
|
497
558
|
});
|
|
498
559
|
USAGE_AGENTS = {
|
|
499
560
|
"claude-code": "Claude",
|
|
500
561
|
codex: "Codex",
|
|
501
562
|
agy: "Antigravity"
|
|
502
563
|
};
|
|
503
|
-
usageSchema =
|
|
564
|
+
usageSchema = z7.object({
|
|
504
565
|
fiveHour: usageWindowSchema.optional(),
|
|
505
566
|
sevenDay: usageWindowSchema.optional(),
|
|
506
|
-
agent:
|
|
567
|
+
agent: z7.enum(["claude-code", "codex", "agy"]).optional()
|
|
507
568
|
}).refine((usage) => usage.fiveHour || usage.sevenDay, "Usage needs at least one window");
|
|
508
569
|
MAX_ACTIVITY_LENGTH = 150;
|
|
509
|
-
activityTextSchema =
|
|
570
|
+
activityTextSchema = z7.string().trim().min(1).max(MAX_ACTIVITY_LENGTH).regex(/^[^\r\n]+$/);
|
|
510
571
|
MAX_TITLE_LENGTH = 40;
|
|
511
|
-
titleSchema =
|
|
512
|
-
listedWindowSchema =
|
|
572
|
+
titleSchema = z7.string().trim().min(1).max(MAX_TITLE_LENGTH).regex(/^[^\r\n]+$/);
|
|
573
|
+
listedWindowSchema = z7.union([
|
|
513
574
|
usageWindowSchema,
|
|
514
|
-
|
|
575
|
+
z7.object({ reset: z7.literal(true), resetsAt: z7.number().int().nonnegative() })
|
|
515
576
|
]);
|
|
516
|
-
listedUsageSchema =
|
|
577
|
+
listedUsageSchema = z7.object({
|
|
517
578
|
fiveHour: listedWindowSchema.optional(),
|
|
518
579
|
sevenDay: listedWindowSchema.optional(),
|
|
519
|
-
agent:
|
|
580
|
+
agent: z7.enum(["claude-code", "codex", "agy"]).optional()
|
|
520
581
|
});
|
|
521
582
|
}
|
|
522
583
|
});
|
|
523
584
|
|
|
524
585
|
// ../common-chat/src/workers.ts
|
|
525
|
-
import { z as
|
|
586
|
+
import { z as z8 } from "zod";
|
|
526
587
|
function agentShortName(cli) {
|
|
527
588
|
return AGENTS[cli]?.short ?? cli;
|
|
528
589
|
}
|
|
@@ -558,11 +619,11 @@ var init_workers = __esm({
|
|
|
558
619
|
"xcode",
|
|
559
620
|
"image_generation"
|
|
560
621
|
];
|
|
561
|
-
capabilitySchema =
|
|
622
|
+
capabilitySchema = z8.enum(CAPABILITIES);
|
|
562
623
|
PLATFORMS = ["macos", "linux", "windows"];
|
|
563
|
-
platformSchema =
|
|
624
|
+
platformSchema = z8.enum(PLATFORMS);
|
|
564
625
|
TOOLS = ["xcode", "gpu"];
|
|
565
|
-
toolSchema =
|
|
626
|
+
toolSchema = z8.enum(TOOLS);
|
|
566
627
|
CAPABILITY_WORDING = {
|
|
567
628
|
macos: "a Mac running macOS",
|
|
568
629
|
linux: "a Linux computer",
|
|
@@ -580,51 +641,51 @@ var init_workers = __esm({
|
|
|
580
641
|
PHRASE_MAX = 100;
|
|
581
642
|
PHRASES_MAX = 10;
|
|
582
643
|
ABOUT_MAX = 500;
|
|
583
|
-
phrase =
|
|
584
|
-
phrases =
|
|
644
|
+
phrase = z8.string().trim().min(1).max(PHRASE_MAX, `at most ${PHRASE_MAX} characters`);
|
|
645
|
+
phrases = z8.array(phrase).max(PHRASES_MAX, `at most ${PHRASES_MAX} phrases`);
|
|
585
646
|
SHARES = ["off", "little", "some", "lot"];
|
|
586
|
-
shareSchema =
|
|
647
|
+
shareSchema = z8.enum(SHARES);
|
|
587
648
|
SHARE_LABELS = {
|
|
588
649
|
off: "off",
|
|
589
650
|
little: "a little",
|
|
590
651
|
some: "some",
|
|
591
652
|
lot: "a lot"
|
|
592
653
|
};
|
|
593
|
-
harnessConfigSchema =
|
|
654
|
+
harnessConfigSchema = z8.object({
|
|
594
655
|
share: shareSchema.optional(),
|
|
595
656
|
/** Read as `share: "off"` when false, from files written before shares. */
|
|
596
|
-
enabled:
|
|
657
|
+
enabled: z8.boolean().optional(),
|
|
597
658
|
only: phrases.optional(),
|
|
598
659
|
great: phrases.optional(),
|
|
599
660
|
good: phrases.optional(),
|
|
600
661
|
okay: phrases.optional(),
|
|
601
662
|
cant: phrases.optional(),
|
|
602
663
|
/** false starts the harness's profile empty, rather than from herd's defaults. */
|
|
603
|
-
defaults:
|
|
664
|
+
defaults: z8.boolean().optional(),
|
|
604
665
|
/** Read as `great`, from files written before profiles. */
|
|
605
666
|
prefer: phrases.optional(),
|
|
606
667
|
/** Read as `cant`, from files written before profiles. */
|
|
607
668
|
avoid: phrases.optional(),
|
|
608
|
-
priority:
|
|
669
|
+
priority: z8.number().int().min(-100).max(100).optional()
|
|
609
670
|
}).strict();
|
|
610
671
|
BUILDS_MAX = 4;
|
|
611
|
-
buildsSettingSchema =
|
|
612
|
-
|
|
613
|
-
|
|
672
|
+
buildsSettingSchema = z8.union([
|
|
673
|
+
z8.literal(true),
|
|
674
|
+
z8.object({ max: z8.number().int().min(1).max(BUILDS_MAX) }).strict()
|
|
614
675
|
]);
|
|
615
676
|
CONFIG_REPOS_MAX = 50;
|
|
616
|
-
configRepoSchema =
|
|
617
|
-
remote:
|
|
618
|
-
about:
|
|
677
|
+
configRepoSchema = z8.object({
|
|
678
|
+
remote: z8.string().trim().min(1).max(300),
|
|
679
|
+
about: z8.string().trim().max(PHRASE_MAX, `at most ${PHRASE_MAX} characters`).optional()
|
|
619
680
|
}).strict();
|
|
620
|
-
herdConfigSchema =
|
|
621
|
-
about:
|
|
681
|
+
herdConfigSchema = z8.object({
|
|
682
|
+
about: z8.string().trim().max(ABOUT_MAX, `at most ${ABOUT_MAX} characters`).optional(),
|
|
622
683
|
cant: phrases.optional(),
|
|
623
684
|
/** Read as `cant`, from files written before profiles. */
|
|
624
685
|
avoid: phrases.optional(),
|
|
625
|
-
harnesses:
|
|
686
|
+
harnesses: z8.record(z8.string().regex(/^[a-z][a-z0-9-]*$/), harnessConfigSchema).optional(),
|
|
626
687
|
builds: buildsSettingSchema.optional(),
|
|
627
|
-
repos:
|
|
688
|
+
repos: z8.array(configRepoSchema).max(CONFIG_REPOS_MAX, `at most ${CONFIG_REPOS_MAX} repos`).optional()
|
|
628
689
|
}).strict();
|
|
629
690
|
HERD_CONFIG_TYPE = `type HerdConfig = {
|
|
630
691
|
/** What this machine is for, in plain words. At most ${ABOUT_MAX} characters. */
|
|
@@ -675,54 +736,55 @@ export default {
|
|
|
675
736
|
harnesses: { claude: { great: ["code review"] }, codex: { cant: ["the billing service"] } },
|
|
676
737
|
} satisfies HerdConfig;`;
|
|
677
738
|
PROFILE_LEVELS = ["great", "good", "okay", "cant"];
|
|
678
|
-
profileEntrySchema =
|
|
679
|
-
statement:
|
|
680
|
-
level:
|
|
681
|
-
source:
|
|
682
|
-
});
|
|
683
|
-
workerSchema =
|
|
684
|
-
key:
|
|
685
|
-
name:
|
|
686
|
-
machineId:
|
|
687
|
-
machineName:
|
|
688
|
-
agent:
|
|
689
|
-
capabilities:
|
|
690
|
-
about:
|
|
691
|
-
only:
|
|
739
|
+
profileEntrySchema = z8.object({
|
|
740
|
+
statement: z8.string().min(1),
|
|
741
|
+
level: z8.enum(PROFILE_LEVELS),
|
|
742
|
+
source: z8.enum(["default", "owner"])
|
|
743
|
+
});
|
|
744
|
+
workerSchema = z8.object({
|
|
745
|
+
key: z8.string().min(1),
|
|
746
|
+
name: z8.string().min(1),
|
|
747
|
+
machineId: z8.string().min(1),
|
|
748
|
+
machineName: z8.string().min(1),
|
|
749
|
+
agent: z8.string().min(1),
|
|
750
|
+
capabilities: z8.array(capabilitySchema),
|
|
751
|
+
about: z8.string().optional(),
|
|
752
|
+
only: z8.array(z8.string()),
|
|
692
753
|
/** What it's great, good and okay at, and can't do: its agent's defaults with its owner's word. */
|
|
693
|
-
profile:
|
|
694
|
-
priority:
|
|
754
|
+
profile: z8.array(profileEntrySchema),
|
|
755
|
+
priority: z8.number().int(),
|
|
695
756
|
/** How much of its agent its owner has. Servers from before shares send none, which is "some". */
|
|
696
757
|
share: shareSchema.default("some"),
|
|
697
|
-
enabled:
|
|
758
|
+
enabled: z8.boolean(),
|
|
698
759
|
/** Whether its agent checked in from herd's terminal on this version, so it's offered work. */
|
|
699
|
-
activated:
|
|
760
|
+
activated: z8.boolean(),
|
|
700
761
|
activation: agentActivationSchema.optional(),
|
|
701
|
-
online:
|
|
762
|
+
online: z8.boolean(),
|
|
702
763
|
/** A folder its machine works in that isn't there, so it's offered no work until it is. */
|
|
703
|
-
folderUnavailable:
|
|
764
|
+
folderUnavailable: z8.object({ path: z8.string().min(1), target: z8.string().min(1).optional() }).optional(),
|
|
704
765
|
// Its machine's repos, each marked whether herd has cloned it there. Older daemons send no `cloned`.
|
|
705
|
-
repos:
|
|
706
|
-
|
|
766
|
+
repos: z8.array(
|
|
767
|
+
z8.object({ name: z8.string(), remote: z8.string(), cloned: z8.boolean().optional() })
|
|
707
768
|
),
|
|
708
|
-
machineCreatedAt:
|
|
769
|
+
machineCreatedAt: z8.number().int().nonnegative()
|
|
709
770
|
});
|
|
710
771
|
}
|
|
711
772
|
});
|
|
712
773
|
|
|
713
774
|
// ../common-chat/src/machines.ts
|
|
714
|
-
import { z as
|
|
775
|
+
import { z as z9 } from "zod";
|
|
715
776
|
var nonEmpty4, time2, terminalStateSchema, agentStatusSchema, machineRepoSchema, isCloned, machineCliSchema, folderUnavailableSchema, machineRegistrationSchema, machineSchema, machinePresenceSchema, worktreeSchema, MAX_REPO_HINTS, repoHintSchema, terminalSchema, offerSchema, offerAnswerSchema, dispatchFrameSchema, machineMessageSchema;
|
|
716
777
|
var init_machines = __esm({
|
|
717
778
|
"../common-chat/src/machines.ts"() {
|
|
718
779
|
"use strict";
|
|
719
780
|
init_define_HERD_PACKAGE();
|
|
720
781
|
init_activation();
|
|
782
|
+
init_terminals();
|
|
721
783
|
init_usage();
|
|
722
784
|
init_workers();
|
|
723
|
-
nonEmpty4 =
|
|
724
|
-
time2 =
|
|
725
|
-
terminalStateSchema =
|
|
785
|
+
nonEmpty4 = z9.string().min(1);
|
|
786
|
+
time2 = z9.number().int().nonnegative();
|
|
787
|
+
terminalStateSchema = z9.enum([
|
|
726
788
|
"working",
|
|
727
789
|
"idle",
|
|
728
790
|
"waiting_on_someone",
|
|
@@ -730,64 +792,66 @@ var init_machines = __esm({
|
|
|
730
792
|
"signed_out",
|
|
731
793
|
"unknown"
|
|
732
794
|
]);
|
|
733
|
-
agentStatusSchema =
|
|
734
|
-
machineRepoSchema =
|
|
795
|
+
agentStatusSchema = z9.enum(["working", "idle", "waiting_on_someone", "exited"]);
|
|
796
|
+
machineRepoSchema = z9.object({
|
|
735
797
|
name: nonEmpty4,
|
|
736
798
|
remote: nonEmpty4,
|
|
737
|
-
cloned:
|
|
799
|
+
cloned: z9.boolean().optional()
|
|
738
800
|
});
|
|
739
801
|
isCloned = (repo) => repo.cloned !== false;
|
|
740
|
-
machineCliSchema =
|
|
802
|
+
machineCliSchema = z9.object({
|
|
741
803
|
name: nonEmpty4,
|
|
742
804
|
version: nonEmpty4,
|
|
743
|
-
runnable:
|
|
744
|
-
capabilities:
|
|
805
|
+
runnable: z9.boolean().optional(),
|
|
806
|
+
capabilities: z9.array(capabilitySchema).optional(),
|
|
745
807
|
activation: agentActivationSchema.optional()
|
|
746
808
|
});
|
|
747
|
-
folderUnavailableSchema =
|
|
748
|
-
path:
|
|
749
|
-
target:
|
|
809
|
+
folderUnavailableSchema = z9.object({
|
|
810
|
+
path: z9.string().min(1).max(1e3),
|
|
811
|
+
target: z9.string().min(1).max(1e3).optional()
|
|
750
812
|
});
|
|
751
|
-
machineRegistrationSchema =
|
|
813
|
+
machineRegistrationSchema = z9.object({
|
|
752
814
|
id: nonEmpty4,
|
|
753
815
|
name: nonEmpty4,
|
|
754
|
-
repos:
|
|
755
|
-
clis:
|
|
816
|
+
repos: z9.array(machineRepoSchema),
|
|
817
|
+
clis: z9.array(machineCliSchema),
|
|
756
818
|
// The platform the agent actually runs on, and tools from herd's fixed list.
|
|
757
819
|
platform: platformSchema.optional(),
|
|
758
|
-
tools:
|
|
820
|
+
tools: z9.array(toolSchema).optional(),
|
|
759
821
|
// The machine's validated `herd.config.ts`, and why the file on disk didn't load if it didn't.
|
|
760
822
|
config: herdConfigSchema.optional(),
|
|
761
|
-
configError:
|
|
823
|
+
configError: z9.string().max(1e3).optional(),
|
|
762
824
|
// Whether its GitHub CLI is signed in, and as whom.
|
|
763
825
|
gh: gitHubCliSchema.optional(),
|
|
764
826
|
// A folder it works in that isn't there, while it takes no work.
|
|
765
827
|
folderUnavailable: folderUnavailableSchema.optional(),
|
|
766
828
|
// The daemon's own package version, or `dev` from a checkout. Daemons from before send none,
|
|
767
829
|
// which reads as older than any that does.
|
|
768
|
-
herdVersion:
|
|
830
|
+
herdVersion: z9.string().min(1).max(50).optional(),
|
|
831
|
+
// What the web may do with its terminals. A daemon from before terminal sessions doesn't say.
|
|
832
|
+
terminals: machineTerminalsSchema.optional()
|
|
769
833
|
});
|
|
770
834
|
machineSchema = machineRegistrationSchema.extend({
|
|
771
835
|
ownerId: nonEmpty4,
|
|
772
|
-
online:
|
|
836
|
+
online: z9.boolean(),
|
|
773
837
|
lastSeenAt: time2,
|
|
774
838
|
createdAt: time2
|
|
775
839
|
});
|
|
776
|
-
machinePresenceSchema =
|
|
777
|
-
worktreeSchema =
|
|
840
|
+
machinePresenceSchema = z9.object({ name: nonEmpty4, online: z9.boolean() });
|
|
841
|
+
worktreeSchema = z9.object({ repo: nonEmpty4, branch: nonEmpty4 });
|
|
778
842
|
MAX_REPO_HINTS = 10;
|
|
779
|
-
repoHintSchema =
|
|
843
|
+
repoHintSchema = z9.object({
|
|
780
844
|
remote: nonEmpty4,
|
|
781
845
|
branch: nonEmpty4.optional(),
|
|
782
846
|
folder: nonEmpty4.optional()
|
|
783
847
|
});
|
|
784
|
-
terminalSchema =
|
|
848
|
+
terminalSchema = z9.object({
|
|
785
849
|
id: nonEmpty4,
|
|
786
850
|
name: nonEmpty4,
|
|
787
851
|
machineId: nonEmpty4,
|
|
788
852
|
conversationId: nonEmpty4,
|
|
789
853
|
// The lead terminal receives the conversation's notices. Others are started with `herd run`.
|
|
790
|
-
lead:
|
|
854
|
+
lead: z9.boolean(),
|
|
791
855
|
// Only for a conversation from before folders, which works in one repo's worktree.
|
|
792
856
|
worktree: worktreeSchema.optional(),
|
|
793
857
|
// The program the screen reader recognized, such as `claude-code` or `shell`, when it knows.
|
|
@@ -795,7 +859,7 @@ var init_machines = __esm({
|
|
|
795
859
|
state: terminalStateSchema,
|
|
796
860
|
updatedAt: time2
|
|
797
861
|
});
|
|
798
|
-
offerSchema =
|
|
862
|
+
offerSchema = z9.object({
|
|
799
863
|
id: nonEmpty4,
|
|
800
864
|
conversationId: nonEmpty4,
|
|
801
865
|
machineId: nonEmpty4,
|
|
@@ -803,33 +867,41 @@ var init_machines = __esm({
|
|
|
803
867
|
expiresAt: time2,
|
|
804
868
|
// The repos the work hints, which the machine adds to the conversation's folder before the agent
|
|
805
869
|
// starts. Hints never decide which machines are offered the work.
|
|
806
|
-
repos:
|
|
870
|
+
repos: z9.array(repoHintSchema).max(MAX_REPO_HINTS).optional(),
|
|
807
871
|
// The first hint's remote, for daemons from before `repos`, which work in that one repo.
|
|
808
872
|
repo: nonEmpty4.optional(),
|
|
809
873
|
// The agent CLI of the worker it's offered to. Without one, it's Claude Code.
|
|
810
874
|
agent: nonEmpty4.optional(),
|
|
811
875
|
// A handed-off conversation restores each of its repos from its branch, if the remote has it.
|
|
812
|
-
handoff:
|
|
876
|
+
handoff: z9.boolean().optional()
|
|
813
877
|
});
|
|
814
|
-
offerAnswerSchema =
|
|
815
|
-
|
|
816
|
-
|
|
878
|
+
offerAnswerSchema = z9.discriminatedUnion("answer", [
|
|
879
|
+
z9.object({ answer: z9.literal("accept") }),
|
|
880
|
+
z9.object({ answer: z9.literal("refuse"), reason: nonEmpty4 })
|
|
817
881
|
]);
|
|
818
|
-
dispatchFrameSchema =
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
type:
|
|
882
|
+
dispatchFrameSchema = z9.discriminatedUnion("type", [
|
|
883
|
+
z9.object({ type: z9.literal("offer"), offer: offerSchema }),
|
|
884
|
+
z9.object({
|
|
885
|
+
type: z9.literal("message"),
|
|
822
886
|
conversationId: nonEmpty4,
|
|
823
|
-
delivery:
|
|
887
|
+
delivery: z9.enum(["interrupt", "defer"])
|
|
824
888
|
}),
|
|
825
|
-
|
|
889
|
+
z9.object({ type: z9.literal("reconnect") }),
|
|
826
890
|
// Its owner asked for a sign-in on this machine, which the daemon runs and reports on.
|
|
827
|
-
|
|
891
|
+
z9.object({ type: z9.literal("sign_in"), signInId: nonEmpty4, tool: signInToolSchema }),
|
|
892
|
+
// Its owner opened a terminal session from the web, which the daemon dials. An older daemon
|
|
893
|
+
// ignores it, and the session expires.
|
|
894
|
+
z9.object({
|
|
895
|
+
type: z9.literal("terminal_open"),
|
|
896
|
+
sessionId: nonEmpty4,
|
|
897
|
+
target: terminalTargetSchema,
|
|
898
|
+
mode: terminalModeSchema
|
|
899
|
+
})
|
|
828
900
|
]);
|
|
829
|
-
machineMessageSchema =
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
type:
|
|
901
|
+
machineMessageSchema = z9.discriminatedUnion("type", [
|
|
902
|
+
z9.object({ type: z9.literal("ack"), conversationId: nonEmpty4 }),
|
|
903
|
+
z9.object({
|
|
904
|
+
type: z9.literal("usage"),
|
|
833
905
|
/** The worker's agent on this machine, such as `claude-code`. */
|
|
834
906
|
agent: nonEmpty4,
|
|
835
907
|
usage: usageSchema,
|
|
@@ -840,39 +912,39 @@ var init_machines = __esm({
|
|
|
840
912
|
});
|
|
841
913
|
|
|
842
914
|
// ../common-chat/src/prompts.ts
|
|
843
|
-
import { z as
|
|
915
|
+
import { z as z10 } from "zod";
|
|
844
916
|
var nonEmpty5, id, promptKindSchema, promptOptionSchema, promptQuestionSchema, promptRequestSchema, promptOutcomeSchema;
|
|
845
917
|
var init_prompts = __esm({
|
|
846
918
|
"../common-chat/src/prompts.ts"() {
|
|
847
919
|
"use strict";
|
|
848
920
|
init_define_HERD_PACKAGE();
|
|
849
|
-
nonEmpty5 =
|
|
850
|
-
id =
|
|
851
|
-
promptKindSchema =
|
|
852
|
-
promptOptionSchema =
|
|
921
|
+
nonEmpty5 = z10.string().min(1);
|
|
922
|
+
id = z10.string().regex(/^[A-Za-z0-9_-]{1,40}$/).describe("Short, so it fits in a button's value and action ID");
|
|
923
|
+
promptKindSchema = z10.enum(["permission", "question", "plan", "automation"]);
|
|
924
|
+
promptOptionSchema = z10.object({
|
|
853
925
|
id,
|
|
854
|
-
label:
|
|
855
|
-
description:
|
|
926
|
+
label: z10.string().trim().min(1).max(75),
|
|
927
|
+
description: z10.string().max(200).optional(),
|
|
856
928
|
// How a button for it is drawn: `primary` to go ahead, `danger` to refuse.
|
|
857
|
-
style:
|
|
929
|
+
style: z10.enum(["primary", "danger"]).optional()
|
|
858
930
|
});
|
|
859
|
-
promptQuestionSchema =
|
|
931
|
+
promptQuestionSchema = z10.object({
|
|
860
932
|
id,
|
|
861
|
-
text:
|
|
862
|
-
options:
|
|
933
|
+
text: z10.string().trim().min(1).max(300),
|
|
934
|
+
options: z10.array(promptOptionSchema).min(1).max(10)
|
|
863
935
|
});
|
|
864
|
-
promptRequestSchema =
|
|
936
|
+
promptRequestSchema = z10.object({
|
|
865
937
|
kind: promptKindSchema,
|
|
866
|
-
title:
|
|
867
|
-
detail:
|
|
868
|
-
questions:
|
|
938
|
+
title: z10.string().trim().min(1).max(150),
|
|
939
|
+
detail: z10.string().max(2800).optional(),
|
|
940
|
+
questions: z10.array(promptQuestionSchema).min(1).max(4)
|
|
869
941
|
});
|
|
870
|
-
promptOutcomeSchema =
|
|
942
|
+
promptOutcomeSchema = z10.enum(["answered", "cancelled"]);
|
|
871
943
|
}
|
|
872
944
|
});
|
|
873
945
|
|
|
874
946
|
// ../common-chat/src/pull-requests.ts
|
|
875
|
-
import { z as
|
|
947
|
+
import { z as z11 } from "zod";
|
|
876
948
|
function statusOfPhase(phase) {
|
|
877
949
|
return phase === "merged" ? "done" : phase === "closed" ? "closed" : "open";
|
|
878
950
|
}
|
|
@@ -911,8 +983,8 @@ var init_pull_requests = __esm({
|
|
|
911
983
|
"../common-chat/src/pull-requests.ts"() {
|
|
912
984
|
"use strict";
|
|
913
985
|
init_define_HERD_PACKAGE();
|
|
914
|
-
time3 =
|
|
915
|
-
pullRequestPhaseSchema =
|
|
986
|
+
time3 = z11.number().int().nonnegative();
|
|
987
|
+
pullRequestPhaseSchema = z11.enum([
|
|
916
988
|
"draft",
|
|
917
989
|
"checks_running",
|
|
918
990
|
"checks_failed",
|
|
@@ -923,7 +995,7 @@ var init_pull_requests = __esm({
|
|
|
923
995
|
"merged",
|
|
924
996
|
"closed"
|
|
925
997
|
]);
|
|
926
|
-
pullRequestMoveSchema =
|
|
998
|
+
pullRequestMoveSchema = z11.enum(["you", "agent", "others", "nobody"]);
|
|
927
999
|
PHASE_LABELS = {
|
|
928
1000
|
draft: "draft",
|
|
929
1001
|
checks_running: "checks running",
|
|
@@ -935,22 +1007,22 @@ var init_pull_requests = __esm({
|
|
|
935
1007
|
merged: "merged",
|
|
936
1008
|
closed: "closed"
|
|
937
1009
|
};
|
|
938
|
-
leadChangeSchema =
|
|
1010
|
+
leadChangeSchema = z11.object({
|
|
939
1011
|
/** Its repo and number, such as `api#104`, or "a pull request" when hidden. */
|
|
940
|
-
label:
|
|
1012
|
+
label: z11.string().min(1),
|
|
941
1013
|
phase: pullRequestPhaseSchema,
|
|
942
1014
|
move: pullRequestMoveSchema,
|
|
943
1015
|
changedAt: time3,
|
|
944
1016
|
/** How many of the conversation's other open pull requests are also the person's move. */
|
|
945
|
-
moreForYou:
|
|
1017
|
+
moreForYou: z11.number().int().nonnegative(),
|
|
946
1018
|
/** Absent when hidden. */
|
|
947
|
-
url:
|
|
1019
|
+
url: z11.string().optional()
|
|
948
1020
|
});
|
|
949
1021
|
}
|
|
950
1022
|
});
|
|
951
1023
|
|
|
952
1024
|
// ../common-chat/src/work-objects.ts
|
|
953
|
-
import { z as
|
|
1025
|
+
import { z as z12 } from "zod";
|
|
954
1026
|
function workLine(work) {
|
|
955
1027
|
const parts = [
|
|
956
1028
|
work.phase ? `${work.kind} ${PHASE_LABELS[work.phase]}` : `${work.kind} ${work.status}`
|
|
@@ -965,21 +1037,21 @@ var init_work_objects = __esm({
|
|
|
965
1037
|
"use strict";
|
|
966
1038
|
init_define_HERD_PACKAGE();
|
|
967
1039
|
init_pull_requests();
|
|
968
|
-
time4 =
|
|
969
|
-
workKindSchema =
|
|
970
|
-
workStatusSchema =
|
|
971
|
-
workSourceSchema =
|
|
1040
|
+
time4 = z12.number().int().nonnegative();
|
|
1041
|
+
workKindSchema = z12.enum(["change", "ticket", "deploy", "document", "other"]);
|
|
1042
|
+
workStatusSchema = z12.enum(["open", "done", "closed"]);
|
|
1043
|
+
workSourceSchema = z12.enum(["agent", "provider"]);
|
|
972
1044
|
MAX_WORK_TITLE = 200;
|
|
973
1045
|
MAX_WORK_DETAIL = 100;
|
|
974
1046
|
MAX_WORK_URL = 2048;
|
|
975
|
-
workObjectSchema =
|
|
976
|
-
url:
|
|
1047
|
+
workObjectSchema = z12.object({
|
|
1048
|
+
url: z12.string().min(1).max(MAX_WORK_URL),
|
|
977
1049
|
kind: workKindSchema,
|
|
978
|
-
title:
|
|
1050
|
+
title: z12.string().min(1).max(MAX_WORK_TITLE),
|
|
979
1051
|
status: workStatusSchema,
|
|
980
|
-
detail:
|
|
1052
|
+
detail: z12.string().max(MAX_WORK_DETAIL).nullable(),
|
|
981
1053
|
/** Whether the conversation made it, rather than only being about it. */
|
|
982
|
-
made:
|
|
1054
|
+
made: z12.boolean(),
|
|
983
1055
|
changedAt: time4,
|
|
984
1056
|
changedBy: workSourceSchema,
|
|
985
1057
|
createdAt: time4,
|
|
@@ -987,21 +1059,21 @@ var init_work_objects = __esm({
|
|
|
987
1059
|
phase: pullRequestPhaseSchema.nullable().optional(),
|
|
988
1060
|
move: pullRequestMoveSchema.nullable().optional(),
|
|
989
1061
|
/** The delegate holding it, when it's read from an ancestor. */
|
|
990
|
-
conversationId:
|
|
1062
|
+
conversationId: z12.string().min(1).optional()
|
|
991
1063
|
});
|
|
992
|
-
workChangeSchema =
|
|
993
|
-
url:
|
|
1064
|
+
workChangeSchema = z12.object({
|
|
1065
|
+
url: z12.string().trim().min(1).max(MAX_WORK_URL),
|
|
994
1066
|
kind: workKindSchema.optional(),
|
|
995
|
-
title:
|
|
1067
|
+
title: z12.string().trim().min(1).max(2e3).optional(),
|
|
996
1068
|
status: workStatusSchema.optional(),
|
|
997
|
-
detail:
|
|
998
|
-
made:
|
|
1069
|
+
detail: z12.string().trim().max(2e3).nullable().optional(),
|
|
1070
|
+
made: z12.boolean().optional(),
|
|
999
1071
|
/** Only for a `change`. Its status then follows it. */
|
|
1000
1072
|
phase: pullRequestPhaseSchema.optional(),
|
|
1001
1073
|
/** Set by a provider, which knows who was asked to review. Otherwise it follows the phase. */
|
|
1002
1074
|
move: pullRequestMoveSchema.optional()
|
|
1003
1075
|
});
|
|
1004
|
-
workFieldSchema =
|
|
1076
|
+
workFieldSchema = z12.enum([
|
|
1005
1077
|
"kind",
|
|
1006
1078
|
"title",
|
|
1007
1079
|
"status",
|
|
@@ -1010,27 +1082,27 @@ var init_work_objects = __esm({
|
|
|
1010
1082
|
"phase",
|
|
1011
1083
|
"move"
|
|
1012
1084
|
]);
|
|
1013
|
-
workObjectSummarySchema =
|
|
1085
|
+
workObjectSummarySchema = z12.object({
|
|
1014
1086
|
kind: workKindSchema,
|
|
1015
1087
|
status: workStatusSchema,
|
|
1016
|
-
made:
|
|
1088
|
+
made: z12.boolean(),
|
|
1017
1089
|
changedAt: time4,
|
|
1018
1090
|
/** A pull request's phase and move, which say nothing of its content, so they're never hidden. */
|
|
1019
1091
|
phase: pullRequestPhaseSchema.nullable().optional(),
|
|
1020
1092
|
move: pullRequestMoveSchema.nullable().optional(),
|
|
1021
|
-
url:
|
|
1022
|
-
title:
|
|
1023
|
-
detail:
|
|
1093
|
+
url: z12.string().optional(),
|
|
1094
|
+
title: z12.string().optional(),
|
|
1095
|
+
detail: z12.string().nullable().optional(),
|
|
1024
1096
|
/** The delegate holding it, when it isn't the item's own conversation. */
|
|
1025
|
-
conversationId:
|
|
1097
|
+
conversationId: z12.string().min(1).optional()
|
|
1026
1098
|
});
|
|
1027
1099
|
}
|
|
1028
1100
|
});
|
|
1029
1101
|
|
|
1030
1102
|
// ../common-chat/src/events.ts
|
|
1031
|
-
import { z as
|
|
1103
|
+
import { z as z13 } from "zod";
|
|
1032
1104
|
function event(type, payload) {
|
|
1033
|
-
return
|
|
1105
|
+
return z13.object({ ...eventBase, type: z13.literal(type), payload: z13.object(payload) });
|
|
1034
1106
|
}
|
|
1035
1107
|
var routeSchema, deliveryModeSchema, eventSourceSchema, nonEmpty6, actorSchema, eventBase, entryIds, routingRecordSchema, threadChangeSchema, conversationEventSchema, conversationVisibilitySchema, conversationStatusSchema, conversationSummarySchema, placementSchema, treeSummarySchema, conversationSnapshotSchema, liveFrameSchema, adapterCapabilitiesSchema;
|
|
1036
1108
|
var init_events = __esm({
|
|
@@ -1045,141 +1117,141 @@ var init_events = __esm({
|
|
|
1045
1117
|
init_usage();
|
|
1046
1118
|
init_work_objects();
|
|
1047
1119
|
init_workers();
|
|
1048
|
-
routeSchema =
|
|
1049
|
-
deliveryModeSchema =
|
|
1050
|
-
eventSourceSchema =
|
|
1051
|
-
nonEmpty6 =
|
|
1052
|
-
actorSchema =
|
|
1120
|
+
routeSchema = z13.enum(["direct", "mention", "joined"]);
|
|
1121
|
+
deliveryModeSchema = z13.enum(["interrupt", "defer"]);
|
|
1122
|
+
eventSourceSchema = z13.enum(["slack", "discord", "web", "api", "cli", "mcp", "system"]);
|
|
1123
|
+
nonEmpty6 = z13.string().min(1);
|
|
1124
|
+
actorSchema = z13.discriminatedUnion("kind", [
|
|
1053
1125
|
// Someone signed in to this system. `id` is the stable person identifier.
|
|
1054
|
-
|
|
1126
|
+
z13.object({ kind: z13.literal("person"), id: nonEmpty6, name: nonEmpty6 }),
|
|
1055
1127
|
// An account on a platform, which may or may not be linked to a person.
|
|
1056
|
-
|
|
1057
|
-
kind:
|
|
1128
|
+
z13.object({
|
|
1129
|
+
kind: z13.literal("account"),
|
|
1058
1130
|
provider: nonEmpty6,
|
|
1059
1131
|
tenant: nonEmpty6,
|
|
1060
1132
|
subject: nonEmpty6,
|
|
1061
|
-
name:
|
|
1062
|
-
isBot:
|
|
1133
|
+
name: z13.string().optional(),
|
|
1134
|
+
isBot: z13.boolean()
|
|
1063
1135
|
}),
|
|
1064
|
-
|
|
1136
|
+
z13.object({ kind: z13.literal("system") })
|
|
1065
1137
|
]);
|
|
1066
1138
|
eventBase = {
|
|
1067
|
-
seq:
|
|
1139
|
+
seq: z13.number().int().positive(),
|
|
1068
1140
|
source: eventSourceSchema,
|
|
1069
1141
|
actor: actorSchema,
|
|
1070
|
-
createdAt:
|
|
1142
|
+
createdAt: z13.number().int().nonnegative()
|
|
1071
1143
|
};
|
|
1072
|
-
entryIds =
|
|
1073
|
-
routingRecordSchema =
|
|
1074
|
-
eligible:
|
|
1075
|
-
questions:
|
|
1076
|
-
|
|
1144
|
+
entryIds = z13.array(nonEmpty6);
|
|
1145
|
+
routingRecordSchema = z13.object({
|
|
1146
|
+
eligible: z13.array(z13.object({ key: nonEmpty6, name: nonEmpty6 })),
|
|
1147
|
+
questions: z13.array(
|
|
1148
|
+
z13.object({
|
|
1077
1149
|
id: nonEmpty6,
|
|
1078
1150
|
question: nonEmpty6,
|
|
1079
|
-
probability:
|
|
1151
|
+
probability: z13.number().min(0).max(1).nullable()
|
|
1080
1152
|
})
|
|
1081
1153
|
),
|
|
1082
1154
|
model: nonEmpty6.optional(),
|
|
1083
1155
|
// Why the model's answers weren't used, when they weren't.
|
|
1084
|
-
fallback:
|
|
1085
|
-
removed:
|
|
1086
|
-
order:
|
|
1156
|
+
fallback: z13.string().optional(),
|
|
1157
|
+
removed: z13.array(z13.object({ key: nonEmpty6, name: nonEmpty6, rule: nonEmpty6 })),
|
|
1158
|
+
order: z13.array(nonEmpty6),
|
|
1087
1159
|
// Each ordered worker's fit, and the profile statement and level that gave it, when the model
|
|
1088
1160
|
// answered.
|
|
1089
|
-
fits:
|
|
1090
|
-
|
|
1161
|
+
fits: z13.array(
|
|
1162
|
+
z13.object({
|
|
1091
1163
|
key: nonEmpty6,
|
|
1092
|
-
fit:
|
|
1093
|
-
statement:
|
|
1094
|
-
level:
|
|
1164
|
+
fit: z13.number().min(0).max(1),
|
|
1165
|
+
statement: z13.string().optional(),
|
|
1166
|
+
level: z13.enum(["great", "good", "okay"]).optional()
|
|
1095
1167
|
})
|
|
1096
1168
|
).optional(),
|
|
1097
1169
|
// Profile statements left out to keep within the most questions one call asks.
|
|
1098
|
-
dropped:
|
|
1170
|
+
dropped: z13.array(z13.string()).optional(),
|
|
1099
1171
|
// The repos the work hinted, and the workers whose machine had cloned every one, which go first
|
|
1100
1172
|
// among workers that tie on fit and priority.
|
|
1101
|
-
hints:
|
|
1102
|
-
warm:
|
|
1173
|
+
hints: z13.array(nonEmpty6).optional(),
|
|
1174
|
+
warm: z13.array(nonEmpty6).optional(),
|
|
1103
1175
|
// Each ordered worker's share, how its weekly usage is pacing, and the weight that gives it. The
|
|
1104
1176
|
// first worker was drawn by weight from those in `drawn`, which suited the work equally.
|
|
1105
|
-
shares:
|
|
1106
|
-
|
|
1177
|
+
shares: z13.array(
|
|
1178
|
+
z13.object({
|
|
1107
1179
|
key: nonEmpty6,
|
|
1108
1180
|
share: shareSchema,
|
|
1109
|
-
pacing:
|
|
1110
|
-
weight:
|
|
1181
|
+
pacing: z13.enum(["ahead", "even", "under", "unknown"]),
|
|
1182
|
+
weight: z13.number().nonnegative()
|
|
1111
1183
|
})
|
|
1112
1184
|
).optional(),
|
|
1113
|
-
drawn:
|
|
1185
|
+
drawn: z13.array(nonEmpty6).optional()
|
|
1114
1186
|
});
|
|
1115
|
-
threadChangeSchema =
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
kind:
|
|
1187
|
+
threadChangeSchema = z13.discriminatedUnion("kind", [
|
|
1188
|
+
z13.object({ kind: z13.literal("edited"), messageId: nonEmpty6, previous: z13.string() }),
|
|
1189
|
+
z13.object({
|
|
1190
|
+
kind: z13.literal("reacted"),
|
|
1119
1191
|
messageId: nonEmpty6,
|
|
1120
1192
|
reaction: nonEmpty6,
|
|
1121
1193
|
/** The words of the message reacted to, cut short. */
|
|
1122
|
-
target:
|
|
1194
|
+
target: z13.string(),
|
|
1123
1195
|
/** Whether Friday wrote that message. */
|
|
1124
|
-
onBot:
|
|
1196
|
+
onBot: z13.boolean()
|
|
1125
1197
|
})
|
|
1126
1198
|
]);
|
|
1127
|
-
conversationEventSchema =
|
|
1199
|
+
conversationEventSchema = z13.discriminatedUnion("type", [
|
|
1128
1200
|
event("message.created", {
|
|
1129
1201
|
messageId: nonEmpty6,
|
|
1130
|
-
text:
|
|
1131
|
-
direction:
|
|
1202
|
+
text: z13.string(),
|
|
1203
|
+
direction: z13.enum(["inbound", "outbound"]),
|
|
1132
1204
|
route: routeSchema.optional(),
|
|
1133
1205
|
// Why the message did or didn't wake the conversation.
|
|
1134
|
-
reason:
|
|
1206
|
+
reason: z13.string().optional(),
|
|
1135
1207
|
// Loaded from before the conversation joined the thread, so it never waits for a response.
|
|
1136
|
-
isContext:
|
|
1208
|
+
isContext: z13.boolean().optional(),
|
|
1137
1209
|
// Set when the message was deleted on its platform. `text` is then empty.
|
|
1138
|
-
deleted:
|
|
1210
|
+
deleted: z13.boolean().optional(),
|
|
1139
1211
|
// Sent through the API but kept out of the platform, so only clients see it.
|
|
1140
|
-
quiet:
|
|
1212
|
+
quiet: z13.boolean().optional(),
|
|
1141
1213
|
// The client an agent sent it through, such as "Claude Code". Such a message is the agent's.
|
|
1142
|
-
client:
|
|
1214
|
+
client: z13.string().optional(),
|
|
1143
1215
|
// How to read `text`. Absent means plain text, as every message before this field was.
|
|
1144
|
-
format:
|
|
1216
|
+
format: z13.enum(["markdown"]).optional(),
|
|
1145
1217
|
// Files attached to it, kept with the conversation.
|
|
1146
|
-
files:
|
|
1218
|
+
files: z13.array(messageFileSchema).optional(),
|
|
1147
1219
|
// A platform's own layout, shown there in place of `text`. Every other surface shows `text`.
|
|
1148
|
-
layout:
|
|
1220
|
+
layout: z13.object({ platform: layoutPlatformSchema, blocks: z13.array(z13.unknown()) }).optional(),
|
|
1149
1221
|
// Set when this was posted in another channel, starting the conversation named here.
|
|
1150
1222
|
post: postTargetSchema.optional(),
|
|
1151
1223
|
// Set on a channel post's own conversation: the conversation that posted it. Its ID is left
|
|
1152
1224
|
// out for anyone who can't read that conversation.
|
|
1153
|
-
origin:
|
|
1225
|
+
origin: z13.object({ conversationId: nonEmpty6.optional() }).optional(),
|
|
1154
1226
|
// Set on Friday's one notice that a firing with no thread can't run yet, saying why.
|
|
1155
1227
|
threadNotice: nonEmpty6.optional(),
|
|
1156
1228
|
// Set when this reply answered an open prompt, so it never waits as a message of its own.
|
|
1157
1229
|
answersPrompt: nonEmpty6.optional(),
|
|
1158
1230
|
// Set on a child conversation's first message: the brief its parent's agent wrote, from the
|
|
1159
1231
|
// principal's own account. `by` is the parent's worker.
|
|
1160
|
-
delegation:
|
|
1232
|
+
delegation: z13.object({ parent: nonEmpty6, by: nonEmpty6 }).optional(),
|
|
1161
1233
|
// Set on a message from another of the principal's conversations' agents, which is that agent's
|
|
1162
1234
|
// words, not a person's. `posted` means a delegate already posted it in the thread, and
|
|
1163
1235
|
// `outsideTree` that the sender isn't in this conversation's tree.
|
|
1164
|
-
agentMessage:
|
|
1236
|
+
agentMessage: z13.object({
|
|
1165
1237
|
from: nonEmpty6,
|
|
1166
1238
|
worker: nonEmpty6,
|
|
1167
|
-
posted:
|
|
1168
|
-
overdue:
|
|
1239
|
+
posted: z13.boolean().optional(),
|
|
1240
|
+
overdue: z13.boolean().optional(),
|
|
1169
1241
|
// herd's own note about the delegate, such as that it's waiting for its worker.
|
|
1170
|
-
notice:
|
|
1171
|
-
outsideTree:
|
|
1242
|
+
notice: z13.boolean().optional(),
|
|
1243
|
+
outsideTree: z13.boolean().optional()
|
|
1172
1244
|
}).optional(),
|
|
1173
1245
|
// Set on a message a root posted for one of its children, which is labelled as the child's.
|
|
1174
|
-
forChild:
|
|
1246
|
+
forChild: z13.object({ id: nonEmpty6, worker: nonEmpty6, for: nonEmpty6 }).optional(),
|
|
1175
1247
|
// Set on an automation's firing, whose `text` is the owner's instructions, and on the opening
|
|
1176
1248
|
// post that starts a conversation for one. `payload` is what the trigger brought: untrusted.
|
|
1177
|
-
automation:
|
|
1249
|
+
automation: z13.object({
|
|
1178
1250
|
id: nonEmpty6,
|
|
1179
1251
|
name: nonEmpty6,
|
|
1180
1252
|
reason: nonEmpty6,
|
|
1181
1253
|
key: nonEmpty6,
|
|
1182
|
-
payload:
|
|
1254
|
+
payload: z13.string().optional(),
|
|
1183
1255
|
// The opening post a firing's reactions are shown on, in a conversation it started.
|
|
1184
1256
|
opener: nonEmpty6.optional()
|
|
1185
1257
|
}).optional(),
|
|
@@ -1190,27 +1262,27 @@ var init_events = __esm({
|
|
|
1190
1262
|
// quiet waking work. For an edit `text` is the new words, and for a reaction its emoji.
|
|
1191
1263
|
threadChange: threadChangeSchema.optional()
|
|
1192
1264
|
}),
|
|
1193
|
-
event("message.updated", { messageId: nonEmpty6, text:
|
|
1265
|
+
event("message.updated", { messageId: nonEmpty6, text: z13.string() }),
|
|
1194
1266
|
// A decision model judged whether a reply in a joined thread was meant for the bot. `for_bot`
|
|
1195
1267
|
// woke the conversation. `failed` means it couldn't be decided in time, so nothing woke.
|
|
1196
1268
|
event("message.decided", {
|
|
1197
1269
|
messageId: nonEmpty6,
|
|
1198
|
-
messageSeq:
|
|
1199
|
-
outcome:
|
|
1200
|
-
probability:
|
|
1270
|
+
messageSeq: z13.number().int().positive(),
|
|
1271
|
+
outcome: z13.enum(["for_bot", "not_for_bot", "failed"]),
|
|
1272
|
+
probability: z13.number().min(0).max(1).optional(),
|
|
1201
1273
|
model: nonEmpty6,
|
|
1202
|
-
error:
|
|
1274
|
+
error: z13.string().optional()
|
|
1203
1275
|
}),
|
|
1204
1276
|
// A decision model judged whether the bot's last message of a turn asks a person to answer,
|
|
1205
1277
|
// decide, provide or confirm something before it can carry on. `asks` keeps the conversation
|
|
1206
1278
|
// waiting on them. `failed` means it couldn't be judged in time, so nothing changed.
|
|
1207
1279
|
event("message.asked", {
|
|
1208
1280
|
messageId: nonEmpty6,
|
|
1209
|
-
messageSeq:
|
|
1210
|
-
outcome:
|
|
1211
|
-
probability:
|
|
1281
|
+
messageSeq: z13.number().int().positive(),
|
|
1282
|
+
outcome: z13.enum(["asks", "doesnt_ask", "failed"]),
|
|
1283
|
+
probability: z13.number().min(0).max(1).optional(),
|
|
1212
1284
|
model: nonEmpty6,
|
|
1213
|
-
error:
|
|
1285
|
+
error: z13.string().optional()
|
|
1214
1286
|
}),
|
|
1215
1287
|
// One of an incoming message's files arrived, or couldn't. `file` replaces the one with its ID.
|
|
1216
1288
|
event("message.file_changed", { messageId: nonEmpty6, file: messageFileSchema }),
|
|
@@ -1222,21 +1294,21 @@ var init_events = __esm({
|
|
|
1222
1294
|
event("context.unavailable", { reason: nonEmpty6 }),
|
|
1223
1295
|
event("mailbox.queued", {
|
|
1224
1296
|
entryId: nonEmpty6,
|
|
1225
|
-
messageSeq:
|
|
1297
|
+
messageSeq: z13.number().int().positive(),
|
|
1226
1298
|
delivery: deliveryModeSchema
|
|
1227
1299
|
}),
|
|
1228
1300
|
event("mailbox.claimed", {
|
|
1229
1301
|
claimId: nonEmpty6,
|
|
1230
1302
|
entryIds,
|
|
1231
1303
|
holder: nonEmpty6,
|
|
1232
|
-
expiresAt:
|
|
1304
|
+
expiresAt: z13.number().int()
|
|
1233
1305
|
}),
|
|
1234
|
-
event("mailbox.renewed", { claimId: nonEmpty6, expiresAt:
|
|
1306
|
+
event("mailbox.renewed", { claimId: nonEmpty6, expiresAt: z13.number().int() }),
|
|
1235
1307
|
event("mailbox.released", {
|
|
1236
1308
|
claimId: nonEmpty6,
|
|
1237
1309
|
entryIds,
|
|
1238
1310
|
// `delegates` means messages held for delegates are waiting again now that they've settled.
|
|
1239
|
-
reason:
|
|
1311
|
+
reason: z13.enum(["released", "expired", "delegates"])
|
|
1240
1312
|
}),
|
|
1241
1313
|
// A turn ended with delegates still open, so the messages it worked on wait for them, still ⏳.
|
|
1242
1314
|
event("mailbox.held", { claimId: nonEmpty6, entryIds }),
|
|
@@ -1244,7 +1316,7 @@ var init_events = __esm({
|
|
|
1244
1316
|
event("mailbox.completed", {
|
|
1245
1317
|
entryIds,
|
|
1246
1318
|
claimId: nonEmpty6.optional(),
|
|
1247
|
-
outcome:
|
|
1319
|
+
outcome: z13.enum(["passed"]).optional()
|
|
1248
1320
|
}),
|
|
1249
1321
|
event("mailbox.cancelled", { entryIds, reason: nonEmpty6 }),
|
|
1250
1322
|
// A person asked for what's waiting to be delivered again. The entries stay waiting.
|
|
@@ -1261,15 +1333,15 @@ var init_events = __esm({
|
|
|
1261
1333
|
// The message it was delivering, when it was one of the conversation's own messages.
|
|
1262
1334
|
messageId: nonEmpty6.optional(),
|
|
1263
1335
|
// For `kind: "files"`, which of that message's files didn't arrive.
|
|
1264
|
-
fileIds:
|
|
1336
|
+
fileIds: z13.array(nonEmpty6).optional()
|
|
1265
1337
|
}),
|
|
1266
1338
|
event("status.changed", { status: agentStatusSchema }),
|
|
1267
1339
|
// A work object was added or changed: the whole of it as it now stands, which fields changed, and
|
|
1268
1340
|
// whether the agent or a provider changed them. Recording one never wakes the conversation.
|
|
1269
1341
|
event("work.recorded", {
|
|
1270
1342
|
work: workObjectSchema.omit({ conversationId: true }),
|
|
1271
|
-
changed:
|
|
1272
|
-
added:
|
|
1343
|
+
changed: z13.array(workFieldSchema),
|
|
1344
|
+
added: z13.boolean(),
|
|
1273
1345
|
by: workSourceSchema
|
|
1274
1346
|
}),
|
|
1275
1347
|
event("work.removed", { url: nonEmpty6, by: workSourceSchema }),
|
|
@@ -1282,7 +1354,7 @@ var init_events = __esm({
|
|
|
1282
1354
|
event("prompt.opened", {
|
|
1283
1355
|
promptId: nonEmpty6,
|
|
1284
1356
|
...promptRequestSchema.shape,
|
|
1285
|
-
forChild:
|
|
1357
|
+
forChild: z13.object({ id: nonEmpty6, worker: nonEmpty6, promptId: nonEmpty6 }).optional()
|
|
1286
1358
|
}),
|
|
1287
1359
|
// A reply in the thread answers with its `messageId`, and with `text` when it was taken as the
|
|
1288
1360
|
// answer in its own words rather than as naming an option.
|
|
@@ -1291,12 +1363,12 @@ var init_events = __esm({
|
|
|
1291
1363
|
questionId: nonEmpty6,
|
|
1292
1364
|
optionId: nonEmpty6.optional(),
|
|
1293
1365
|
messageId: nonEmpty6.optional(),
|
|
1294
|
-
text:
|
|
1366
|
+
text: z13.string().optional()
|
|
1295
1367
|
}),
|
|
1296
1368
|
event("prompt.closed", {
|
|
1297
1369
|
promptId: nonEmpty6,
|
|
1298
1370
|
outcome: promptOutcomeSchema,
|
|
1299
|
-
reason:
|
|
1371
|
+
reason: z13.string().optional()
|
|
1300
1372
|
}),
|
|
1301
1373
|
// Dispatch: which machine the conversation was offered to, and which one holds it.
|
|
1302
1374
|
event("dispatch.offered", {
|
|
@@ -1320,19 +1392,19 @@ var init_events = __esm({
|
|
|
1320
1392
|
// An agent started a child conversation on another worker, and how the child has gone since.
|
|
1321
1393
|
event("delegation.started", {
|
|
1322
1394
|
childId: nonEmpty6,
|
|
1323
|
-
workers:
|
|
1324
|
-
routed:
|
|
1395
|
+
workers: z13.array(nonEmpty6),
|
|
1396
|
+
routed: z13.boolean()
|
|
1325
1397
|
}),
|
|
1326
1398
|
event("delegation.settled", { childId: nonEmpty6 }),
|
|
1327
1399
|
event("delegation.overdue", { childId: nonEmpty6 }),
|
|
1328
|
-
event("delegation.waiting", { childId: nonEmpty6, waiting:
|
|
1400
|
+
event("delegation.waiting", { childId: nonEmpty6, waiting: z13.boolean() }),
|
|
1329
1401
|
// An agent asked for its conversation to move to another worker once its turn ends.
|
|
1330
1402
|
event("dispatch.handoff_requested", { workerKey: nonEmpty6, workerName: nonEmpty6 }),
|
|
1331
1403
|
// Terminals on the bound machine. Their output never enters the history, only these facts.
|
|
1332
1404
|
event("terminal.opened", {
|
|
1333
1405
|
terminalId: nonEmpty6,
|
|
1334
1406
|
machineId: nonEmpty6,
|
|
1335
|
-
lead:
|
|
1407
|
+
lead: z13.boolean(),
|
|
1336
1408
|
// Only for a conversation from before folders, which works in one repo's worktree.
|
|
1337
1409
|
worktree: worktreeSchema.optional()
|
|
1338
1410
|
}),
|
|
@@ -1344,9 +1416,9 @@ var init_events = __esm({
|
|
|
1344
1416
|
folder: nonEmpty6,
|
|
1345
1417
|
branch: nonEmpty6,
|
|
1346
1418
|
base: nonEmpty6.optional(),
|
|
1347
|
-
fetchFailed:
|
|
1419
|
+
fetchFailed: z13.string().max(1e3).optional()
|
|
1348
1420
|
}),
|
|
1349
|
-
event("terminal.exited", { terminalId: nonEmpty6, exitCode:
|
|
1421
|
+
event("terminal.exited", { terminalId: nonEmpty6, exitCode: z13.number().int().nullable() }),
|
|
1350
1422
|
event("terminal.notice_failed", { terminalId: nonEmpty6, reason: nonEmpty6 }),
|
|
1351
1423
|
/**
|
|
1352
1424
|
* The agent's start didn't check in with `herd inbox` within its window, so it looks like it
|
|
@@ -1357,29 +1429,43 @@ var init_events = __esm({
|
|
|
1357
1429
|
terminalId: nonEmpty6,
|
|
1358
1430
|
agent: nonEmpty6,
|
|
1359
1431
|
machineName: nonEmpty6,
|
|
1360
|
-
detail:
|
|
1432
|
+
detail: z13.string().max(200).optional()
|
|
1361
1433
|
}),
|
|
1362
1434
|
/** A start that needed attention checked in after all. */
|
|
1363
1435
|
event("terminal.checked_in", { terminalId: nonEmpty6 }),
|
|
1364
1436
|
/** The daemon closed one of Claude Code's own dialogs that it has recorded, named by its title. */
|
|
1365
1437
|
event("terminal.dialog_closed", { terminalId: nonEmpty6, dialog: nonEmpty6 }),
|
|
1438
|
+
/**
|
|
1439
|
+
* Someone watched the conversation's terminal from the web, or typed into it, from `startedAt`
|
|
1440
|
+
* until `endedAt`, and why it ended. Nothing of what was shown or typed is ever recorded.
|
|
1441
|
+
*/
|
|
1442
|
+
event("terminal.watched", {
|
|
1443
|
+
startedAt: z13.number().int(),
|
|
1444
|
+
endedAt: z13.number().int(),
|
|
1445
|
+
reason: nonEmpty6
|
|
1446
|
+
}),
|
|
1447
|
+
event("terminal.driven", {
|
|
1448
|
+
startedAt: z13.number().int(),
|
|
1449
|
+
endedAt: z13.number().int(),
|
|
1450
|
+
reason: nonEmpty6
|
|
1451
|
+
}),
|
|
1366
1452
|
// A subscribed event that didn't wake the conversation, with the reason. One that woke it is a
|
|
1367
1453
|
// quiet inbound message carrying `github`, so it waits like any waking work.
|
|
1368
1454
|
event("github.event", githubEventSummarySchema.shape),
|
|
1369
1455
|
// A pull request's status card, queued for the conversation's thread.
|
|
1370
1456
|
event("github.card", {
|
|
1371
1457
|
resource: nonEmpty6,
|
|
1372
|
-
url:
|
|
1458
|
+
url: z13.url(),
|
|
1373
1459
|
label: nonEmpty6,
|
|
1374
|
-
title:
|
|
1460
|
+
title: z13.string(),
|
|
1375
1461
|
phase: pullRequestPhaseSchema,
|
|
1376
1462
|
move: pullRequestMoveSchema.nullable(),
|
|
1377
|
-
detail:
|
|
1463
|
+
detail: z13.string().nullable()
|
|
1378
1464
|
}),
|
|
1379
1465
|
event("subscription.created", {
|
|
1380
1466
|
resource: nonEmpty6,
|
|
1381
1467
|
label: nonEmpty6,
|
|
1382
|
-
url:
|
|
1468
|
+
url: z13.url(),
|
|
1383
1469
|
subscriber: nonEmpty6,
|
|
1384
1470
|
createdBy: subscriptionOriginSchema
|
|
1385
1471
|
}),
|
|
@@ -1391,72 +1477,72 @@ var init_events = __esm({
|
|
|
1391
1477
|
// A subscription reached its hourly limit of wakes, noted once each hour.
|
|
1392
1478
|
event("subscription.limited", { resource: nonEmpty6 })
|
|
1393
1479
|
]);
|
|
1394
|
-
conversationVisibilitySchema =
|
|
1395
|
-
conversationStatusSchema =
|
|
1396
|
-
conversationSummarySchema =
|
|
1480
|
+
conversationVisibilitySchema = z13.enum(["public", "private"]);
|
|
1481
|
+
conversationStatusSchema = z13.enum(["idle", "waiting", "working"]);
|
|
1482
|
+
conversationSummarySchema = z13.object({
|
|
1397
1483
|
id: nonEmpty6,
|
|
1398
1484
|
provider: nonEmpty6,
|
|
1399
1485
|
visibility: conversationVisibilitySchema,
|
|
1400
1486
|
title: nonEmpty6,
|
|
1401
1487
|
// Where the conversation lives on its platform, when it has a link.
|
|
1402
|
-
placeUrl:
|
|
1488
|
+
placeUrl: z13.string().nullable(),
|
|
1403
1489
|
status: conversationStatusSchema,
|
|
1404
|
-
waitingCount:
|
|
1405
|
-
createdAt:
|
|
1406
|
-
lastActivityAt:
|
|
1407
|
-
expiresAt:
|
|
1408
|
-
});
|
|
1409
|
-
placementSchema =
|
|
1410
|
-
|
|
1411
|
-
kind:
|
|
1412
|
-
machine:
|
|
1490
|
+
waitingCount: z13.number().int().nonnegative(),
|
|
1491
|
+
createdAt: z13.number().int(),
|
|
1492
|
+
lastActivityAt: z13.number().int(),
|
|
1493
|
+
expiresAt: z13.number().int()
|
|
1494
|
+
});
|
|
1495
|
+
placementSchema = z13.discriminatedUnion("kind", [
|
|
1496
|
+
z13.object({
|
|
1497
|
+
kind: z13.literal("bound"),
|
|
1498
|
+
machine: z13.object({ name: nonEmpty6, online: z13.boolean() }),
|
|
1413
1499
|
// The worker's name, such as `mac-mini/claude`, and never its configuration or capabilities.
|
|
1414
1500
|
worker: nonEmpty6.optional()
|
|
1415
1501
|
}),
|
|
1416
|
-
|
|
1417
|
-
|
|
1502
|
+
z13.object({ kind: z13.literal("waiting_for_machine") }),
|
|
1503
|
+
z13.object({ kind: z13.literal("author_not_linked") })
|
|
1418
1504
|
]);
|
|
1419
|
-
treeSummarySchema =
|
|
1505
|
+
treeSummarySchema = z13.object({
|
|
1420
1506
|
parent: nonEmpty6.nullable(),
|
|
1421
1507
|
root: nonEmpty6,
|
|
1422
|
-
children:
|
|
1423
|
-
|
|
1508
|
+
children: z13.array(
|
|
1509
|
+
z13.object({
|
|
1424
1510
|
id: nonEmpty6,
|
|
1425
1511
|
title: nonEmpty6,
|
|
1426
|
-
state:
|
|
1427
|
-
createdAt:
|
|
1512
|
+
state: z13.string().nullable(),
|
|
1513
|
+
createdAt: z13.number()
|
|
1428
1514
|
})
|
|
1429
1515
|
)
|
|
1430
1516
|
});
|
|
1431
|
-
conversationSnapshotSchema =
|
|
1517
|
+
conversationSnapshotSchema = z13.object({
|
|
1432
1518
|
conversation: conversationSummarySchema,
|
|
1433
|
-
events:
|
|
1519
|
+
events: z13.array(conversationEventSchema),
|
|
1434
1520
|
/**
|
|
1435
1521
|
* Each person actor's display name, by ID, as it is now. A person is shown by this, never by
|
|
1436
1522
|
* the name stored with an event, which for older events was their address.
|
|
1437
1523
|
*/
|
|
1438
|
-
people:
|
|
1524
|
+
people: z13.record(z13.string(), z13.string()).optional(),
|
|
1439
1525
|
placement: placementSchema.nullable().optional(),
|
|
1440
1526
|
tree: treeSummarySchema.optional()
|
|
1441
1527
|
});
|
|
1442
|
-
liveFrameSchema =
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1528
|
+
liveFrameSchema = z13.discriminatedUnion("type", [
|
|
1529
|
+
z13.object({ type: z13.literal("event"), event: conversationEventSchema }),
|
|
1530
|
+
z13.object({ type: z13.literal("reconnect") }),
|
|
1531
|
+
z13.object({ type: z13.literal("expired") })
|
|
1446
1532
|
]);
|
|
1447
|
-
adapterCapabilitiesSchema =
|
|
1448
|
-
messages:
|
|
1449
|
-
edits:
|
|
1450
|
-
deletes:
|
|
1451
|
-
reactions:
|
|
1452
|
-
status:
|
|
1453
|
-
search:
|
|
1533
|
+
adapterCapabilitiesSchema = z13.object({
|
|
1534
|
+
messages: z13.enum(["push", "window"]),
|
|
1535
|
+
edits: z13.enum(["push", "rescan"]),
|
|
1536
|
+
deletes: z13.enum(["push", "rescan"]),
|
|
1537
|
+
reactions: z13.enum(["push", "counts"]),
|
|
1538
|
+
status: z13.boolean(),
|
|
1539
|
+
search: z13.boolean()
|
|
1454
1540
|
});
|
|
1455
1541
|
}
|
|
1456
1542
|
});
|
|
1457
1543
|
|
|
1458
1544
|
// ../common-chat/src/conversation-state.ts
|
|
1459
|
-
import { z as
|
|
1545
|
+
import { z as z14 } from "zod";
|
|
1460
1546
|
function openRank(item) {
|
|
1461
1547
|
if (item.state === "stuck") return 0;
|
|
1462
1548
|
if (leadOpen(item.lead) && item.lead?.move === "you") return 1;
|
|
@@ -1493,8 +1579,8 @@ var init_conversation_state = __esm({
|
|
|
1493
1579
|
init_machines();
|
|
1494
1580
|
init_pull_requests();
|
|
1495
1581
|
init_work_objects();
|
|
1496
|
-
nonEmpty7 =
|
|
1497
|
-
time5 =
|
|
1582
|
+
nonEmpty7 = z14.string().min(1);
|
|
1583
|
+
time5 = z14.number().int().nonnegative();
|
|
1498
1584
|
REACTIONS = {
|
|
1499
1585
|
waiting: "eyes",
|
|
1500
1586
|
working: "hourglass_flowing_sand",
|
|
@@ -1503,14 +1589,14 @@ var init_conversation_state = __esm({
|
|
|
1503
1589
|
// Stuck because it's waiting on a person's answer, approval or decision, rather than on a fault.
|
|
1504
1590
|
asking: "question"
|
|
1505
1591
|
};
|
|
1506
|
-
conversationStateSchema =
|
|
1592
|
+
conversationStateSchema = z14.enum([
|
|
1507
1593
|
"waiting",
|
|
1508
1594
|
"working",
|
|
1509
1595
|
"stuck",
|
|
1510
1596
|
"unanswered",
|
|
1511
1597
|
"done"
|
|
1512
1598
|
]);
|
|
1513
|
-
stuckReasonSchema =
|
|
1599
|
+
stuckReasonSchema = z14.enum([
|
|
1514
1600
|
"approval",
|
|
1515
1601
|
"waiting_on_someone",
|
|
1516
1602
|
// A delegate has an open prompt or is waiting on a person.
|
|
@@ -1533,43 +1619,43 @@ var init_conversation_state = __esm({
|
|
|
1533
1619
|
"awaiting_answer"
|
|
1534
1620
|
]);
|
|
1535
1621
|
STUCK_REASONS = stuckReasonSchema.options;
|
|
1536
|
-
placeKindSchema =
|
|
1537
|
-
conversationSourceSchema =
|
|
1622
|
+
placeKindSchema = z14.enum(["channel", "direct", "group", "web"]);
|
|
1623
|
+
conversationSourceSchema = z14.object({
|
|
1538
1624
|
provider: nonEmpty7,
|
|
1539
1625
|
kind: placeKindSchema,
|
|
1540
1626
|
/** Such as a Slack channel's name, without its `#`. Left out where it's unknown or hidden. */
|
|
1541
|
-
name:
|
|
1627
|
+
name: z14.string().optional()
|
|
1542
1628
|
});
|
|
1543
1629
|
LATEST_MESSAGE_LENGTH = 200;
|
|
1544
|
-
latestMessageSchema =
|
|
1545
|
-
text:
|
|
1630
|
+
latestMessageSchema = z14.object({
|
|
1631
|
+
text: z14.string().max(LATEST_MESSAGE_LENGTH),
|
|
1546
1632
|
/** A person wrote it, or the agent did. */
|
|
1547
|
-
from:
|
|
1633
|
+
from: z14.enum(["person", "agent"]),
|
|
1548
1634
|
at: time5
|
|
1549
1635
|
});
|
|
1550
1636
|
listMachineSchema = machinePresenceSchema.extend({
|
|
1551
|
-
mine:
|
|
1637
|
+
mine: z14.boolean().optional(),
|
|
1552
1638
|
/** The agent holding it on that machine, such as `Claude Code`, when it's known. */
|
|
1553
|
-
agent:
|
|
1639
|
+
agent: z14.string().optional()
|
|
1554
1640
|
});
|
|
1555
|
-
conversationListItemSchema =
|
|
1641
|
+
conversationListItemSchema = z14.object({
|
|
1556
1642
|
id: nonEmpty7,
|
|
1557
1643
|
title: nonEmpty7,
|
|
1558
1644
|
visibility: conversationVisibilitySchema,
|
|
1559
1645
|
/** The conversation's page. */
|
|
1560
1646
|
url: nonEmpty7,
|
|
1561
1647
|
/** Its thread on its platform, when it has a link. */
|
|
1562
|
-
placeUrl:
|
|
1648
|
+
placeUrl: z14.string().nullable(),
|
|
1563
1649
|
state: conversationStateSchema,
|
|
1564
1650
|
// A reason this version no longer gives, such as one stored before it, reads as none.
|
|
1565
1651
|
reason: stuckReasonSchema.nullable().catch(null),
|
|
1566
1652
|
/** The start of the latest waking message. */
|
|
1567
|
-
latestRequest:
|
|
1653
|
+
latestRequest: z14.string().nullable(),
|
|
1568
1654
|
lastRequestAt: time5.nullable(),
|
|
1569
1655
|
/** When the bot last posted in the thread. */
|
|
1570
1656
|
lastReplyAt: time5.nullable(),
|
|
1571
1657
|
/** What the agent says it's doing, while it works. */
|
|
1572
|
-
activity:
|
|
1658
|
+
activity: z14.string().nullable(),
|
|
1573
1659
|
/** The machine holding it, by name and presence only, and whether it's the reader's own. */
|
|
1574
1660
|
machine: listMachineSchema.nullable(),
|
|
1575
1661
|
lastActivityAt: time5,
|
|
@@ -1580,28 +1666,28 @@ var init_conversation_state = __esm({
|
|
|
1580
1666
|
/** When its activity last changed, which says how long an agent has been quiet. */
|
|
1581
1667
|
activityAt: time5.nullable().optional(),
|
|
1582
1668
|
/** Set when the title, latest request, link and activity were left out because it's private. */
|
|
1583
|
-
hidden:
|
|
1669
|
+
hidden: z14.boolean().optional(),
|
|
1584
1670
|
/**
|
|
1585
1671
|
* What it's about, its delegates' included: at most 5, open ones first. Missing, from servers
|
|
1586
1672
|
* older than work objects, means none.
|
|
1587
1673
|
*/
|
|
1588
|
-
work:
|
|
1674
|
+
work: z14.array(workObjectSummarySchema).optional(),
|
|
1589
1675
|
/** How many more work objects it holds than `work` carries. */
|
|
1590
|
-
moreWork:
|
|
1676
|
+
moreWork: z14.number().int().nonnegative().optional(),
|
|
1591
1677
|
/** The pull request it leads with, from all of its tree's, not only those in `work`. */
|
|
1592
1678
|
lead: leadChangeSchema.nullable().optional()
|
|
1593
1679
|
});
|
|
1594
|
-
conversationListSchema =
|
|
1595
|
-
items:
|
|
1680
|
+
conversationListSchema = z14.object({
|
|
1681
|
+
items: z14.array(conversationListItemSchema),
|
|
1596
1682
|
/** Present when there's more, to pass back as `next` for the following page. */
|
|
1597
|
-
next:
|
|
1683
|
+
next: z14.string().optional()
|
|
1598
1684
|
});
|
|
1599
|
-
listFrameSchema =
|
|
1600
|
-
|
|
1685
|
+
listFrameSchema = z14.discriminatedUnion("type", [
|
|
1686
|
+
z14.object({ type: z14.literal("changed"), conversations: z14.array(nonEmpty7).min(1) }),
|
|
1601
1687
|
/** A machine went online or offline, or a worker's usage changed. */
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1688
|
+
z14.object({ type: z14.literal("machines") }),
|
|
1689
|
+
z14.object({ type: z14.literal("reconnect") }),
|
|
1690
|
+
z14.object({ type: z14.literal("expired") })
|
|
1605
1691
|
]);
|
|
1606
1692
|
STATE_REACTIONS = {
|
|
1607
1693
|
stuck: REACTIONS.stuck,
|
|
@@ -1642,7 +1728,7 @@ var init_conversation_state = __esm({
|
|
|
1642
1728
|
});
|
|
1643
1729
|
|
|
1644
1730
|
// ../common-chat/src/board.ts
|
|
1645
|
-
import { z as
|
|
1731
|
+
import { z as z15 } from "zod";
|
|
1646
1732
|
var nonEmpty8, time6, BOARD_ITEMS, boardItemSchema, boardWorkerSchema, boardMachineSchema, boardSchema;
|
|
1647
1733
|
var init_board = __esm({
|
|
1648
1734
|
"../common-chat/src/board.ts"() {
|
|
@@ -1651,27 +1737,27 @@ var init_board = __esm({
|
|
|
1651
1737
|
init_conversation_state();
|
|
1652
1738
|
init_pull_requests();
|
|
1653
1739
|
init_usage();
|
|
1654
|
-
nonEmpty8 =
|
|
1655
|
-
time6 =
|
|
1740
|
+
nonEmpty8 = z15.string().min(1);
|
|
1741
|
+
time6 = z15.number().int().nonnegative();
|
|
1656
1742
|
BOARD_ITEMS = 8;
|
|
1657
|
-
boardItemSchema =
|
|
1743
|
+
boardItemSchema = z15.object({
|
|
1658
1744
|
id: nonEmpty8,
|
|
1659
1745
|
/** `HIDDEN_TITLE` when the item is private and the board doesn't show private titles. */
|
|
1660
1746
|
title: nonEmpty8,
|
|
1661
1747
|
state: conversationStateSchema,
|
|
1662
1748
|
reason: stuckReasonSchema.nullable().catch(null),
|
|
1663
1749
|
/** Where the work came from, such as `#herd-dev` or a direct message, when it's known. */
|
|
1664
|
-
source:
|
|
1750
|
+
source: z15.string().nullable(),
|
|
1665
1751
|
/** What the agent says it's doing, while it works. */
|
|
1666
|
-
activity:
|
|
1752
|
+
activity: z15.string().nullable(),
|
|
1667
1753
|
lastActivityAt: time6,
|
|
1668
1754
|
/** The machine and agent holding it, such as `mac-mini` and `Claude Code`, once it's bound. */
|
|
1669
|
-
heldBy:
|
|
1755
|
+
heldBy: z15.object({ machine: nonEmpty8, agent: nonEmpty8 }).nullable().optional(),
|
|
1670
1756
|
/** The pull request it leads with, and how many more are the person's move. */
|
|
1671
1757
|
change: leadChangeSchema.nullable().optional(),
|
|
1672
|
-
hidden:
|
|
1758
|
+
hidden: z15.boolean().optional()
|
|
1673
1759
|
});
|
|
1674
|
-
boardWorkerSchema =
|
|
1760
|
+
boardWorkerSchema = z15.object({
|
|
1675
1761
|
/** The worker's short name, such as `claude`, under its machine. */
|
|
1676
1762
|
name: nonEmpty8,
|
|
1677
1763
|
/** Its agent CLI, such as `claude-code`, which names it on the board. */
|
|
@@ -1680,33 +1766,33 @@ var init_board = __esm({
|
|
|
1680
1766
|
usage: usageSchema.nullable(),
|
|
1681
1767
|
reportedAt: time6.nullable(),
|
|
1682
1768
|
/** What it's great at, from its profile: its owner's statements, or herd's defaults. */
|
|
1683
|
-
strengths:
|
|
1769
|
+
strengths: z15.array(z15.string().min(1).max(100)).max(3).optional()
|
|
1684
1770
|
});
|
|
1685
|
-
boardMachineSchema =
|
|
1771
|
+
boardMachineSchema = z15.object({
|
|
1686
1772
|
name: nonEmpty8,
|
|
1687
|
-
online:
|
|
1688
|
-
workers:
|
|
1773
|
+
online: z15.boolean(),
|
|
1774
|
+
workers: z15.array(boardWorkerSchema).max(8)
|
|
1689
1775
|
});
|
|
1690
|
-
boardSchema =
|
|
1776
|
+
boardSchema = z15.object({
|
|
1691
1777
|
/** How many are in each open state: every state but `done`, which is counted for the last day. */
|
|
1692
|
-
counts:
|
|
1693
|
-
stuck:
|
|
1694
|
-
unanswered:
|
|
1695
|
-
waiting:
|
|
1696
|
-
working:
|
|
1778
|
+
counts: z15.object({
|
|
1779
|
+
stuck: z15.number().int().nonnegative(),
|
|
1780
|
+
unanswered: z15.number().int().nonnegative(),
|
|
1781
|
+
waiting: z15.number().int().nonnegative(),
|
|
1782
|
+
working: z15.number().int().nonnegative(),
|
|
1697
1783
|
/** Open pull requests the person's conversations made that are their move, each counted. */
|
|
1698
|
-
pullRequests:
|
|
1784
|
+
pullRequests: z15.number().int().nonnegative().optional()
|
|
1699
1785
|
}),
|
|
1700
1786
|
/** How many became `done` in the last 24 hours. */
|
|
1701
|
-
doneToday:
|
|
1787
|
+
doneToday: z15.number().int().nonnegative(),
|
|
1702
1788
|
/**
|
|
1703
1789
|
* What needs the person (stuck, then pull requests that are their move), then what's working or
|
|
1704
1790
|
* has a pull request under way, then what's queued, then the latest finished to fill the rest.
|
|
1705
1791
|
*/
|
|
1706
|
-
items:
|
|
1707
|
-
machines:
|
|
1792
|
+
items: z15.array(boardItemSchema).max(BOARD_ITEMS),
|
|
1793
|
+
machines: z15.array(boardMachineSchema).max(16),
|
|
1708
1794
|
/** Changes whenever anything the board shows changes, and only then. */
|
|
1709
|
-
stamp:
|
|
1795
|
+
stamp: z15.string().regex(/^[0-9a-f]{12}$/),
|
|
1710
1796
|
/** When its content last changed. */
|
|
1711
1797
|
changedAt: time6
|
|
1712
1798
|
});
|
|
@@ -1728,31 +1814,31 @@ var init_bot = __esm({
|
|
|
1728
1814
|
});
|
|
1729
1815
|
|
|
1730
1816
|
// ../common-chat/src/builds.ts
|
|
1731
|
-
import { z as
|
|
1817
|
+
import { z as z16 } from "zod";
|
|
1732
1818
|
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;
|
|
1733
1819
|
var init_builds = __esm({
|
|
1734
1820
|
"../common-chat/src/builds.ts"() {
|
|
1735
1821
|
"use strict";
|
|
1736
1822
|
init_define_HERD_PACKAGE();
|
|
1737
1823
|
init_workers();
|
|
1738
|
-
nonEmpty9 =
|
|
1739
|
-
time7 =
|
|
1824
|
+
nonEmpty9 = z16.string().min(1);
|
|
1825
|
+
time7 = z16.number().int().nonnegative();
|
|
1740
1826
|
BUILD_LEASE_MS = 5 * 60 * 1e3;
|
|
1741
1827
|
BUILD_CLAIM_WINDOW_MS = 15 * 1e3;
|
|
1742
1828
|
MAX_LOG_CHUNK_BYTES = 256 * 1024;
|
|
1743
1829
|
MAX_LOG_BYTES = 5 * 1024 * 1024;
|
|
1744
1830
|
MAX_NODE_MODULES_PART_BYTES = 95 * 1024 * 1024;
|
|
1745
|
-
shaSchema =
|
|
1746
|
-
buildOfferSchema =
|
|
1831
|
+
shaSchema = z16.string().regex(/^[0-9a-f]{40}$/);
|
|
1832
|
+
buildOfferSchema = z16.object({
|
|
1747
1833
|
id: nonEmpty9,
|
|
1748
1834
|
offerId: nonEmpty9,
|
|
1749
1835
|
repo: nonEmpty9,
|
|
1750
1836
|
sha: shaSchema,
|
|
1751
1837
|
ref: nonEmpty9,
|
|
1752
|
-
main:
|
|
1838
|
+
main: z16.boolean(),
|
|
1753
1839
|
expiresAt: time7
|
|
1754
1840
|
});
|
|
1755
|
-
buildCancelReasonSchema =
|
|
1841
|
+
buildCancelReasonSchema = z16.enum([
|
|
1756
1842
|
// A newer push to the same branch replaced it.
|
|
1757
1843
|
"superseded",
|
|
1758
1844
|
// The branch was deleted.
|
|
@@ -1762,7 +1848,7 @@ var init_builds = __esm({
|
|
|
1762
1848
|
// Stopped for another reason, such as the repo being removed.
|
|
1763
1849
|
"cancelled"
|
|
1764
1850
|
]);
|
|
1765
|
-
runnerMessageSchema =
|
|
1851
|
+
runnerMessageSchema = z16.discriminatedUnion("type", [
|
|
1766
1852
|
/**
|
|
1767
1853
|
* Sent first, and again whenever any of it changes. `capacity` comes from `herd.config.ts`'s
|
|
1768
1854
|
* `builds` through `runnerCapacity`, `repos` are the normalized remotes of the repos herd has
|
|
@@ -1770,82 +1856,82 @@ var init_builds = __esm({
|
|
|
1770
1856
|
* any of its owner's repos, cloning one it hasn't got, and `repos` only puts it first for those.
|
|
1771
1857
|
* A daemon from before herd's root sent its configured checkouts here, which it builds from.
|
|
1772
1858
|
*/
|
|
1773
|
-
|
|
1774
|
-
type:
|
|
1859
|
+
z16.object({
|
|
1860
|
+
type: z16.literal("hello"),
|
|
1775
1861
|
/** How many builds at once. 0 when the machine can't sandbox a build, so it takes none. */
|
|
1776
|
-
capacity:
|
|
1777
|
-
repos:
|
|
1778
|
-
running:
|
|
1862
|
+
capacity: z16.number().int().min(0).max(BUILDS_MAX),
|
|
1863
|
+
repos: z16.array(nonEmpty9.max(300)).max(100),
|
|
1864
|
+
running: z16.array(nonEmpty9.max(100)).max(BUILDS_MAX * 2)
|
|
1779
1865
|
}),
|
|
1780
1866
|
/** An answer to an offer, before its `expiresAt`. A refusal may say why. */
|
|
1781
|
-
|
|
1782
|
-
type:
|
|
1867
|
+
z16.object({
|
|
1868
|
+
type: z16.literal("answer"),
|
|
1783
1869
|
buildId: nonEmpty9,
|
|
1784
1870
|
offerId: nonEmpty9,
|
|
1785
|
-
answer:
|
|
1786
|
-
reason:
|
|
1871
|
+
answer: z16.enum(["accept", "refuse"]),
|
|
1872
|
+
reason: z16.string().max(500).optional()
|
|
1787
1873
|
})
|
|
1788
1874
|
]);
|
|
1789
|
-
serviceMessageSchema =
|
|
1790
|
-
|
|
1875
|
+
serviceMessageSchema = z16.discriminatedUnion("type", [
|
|
1876
|
+
z16.object({ type: z16.literal("build"), build: buildOfferSchema }),
|
|
1791
1877
|
/** An accepted offer: the build's own secret, and how long its claim lasts between renewals. */
|
|
1792
|
-
|
|
1793
|
-
type:
|
|
1878
|
+
z16.object({
|
|
1879
|
+
type: z16.literal("accepted"),
|
|
1794
1880
|
buildId: nonEmpty9,
|
|
1795
1881
|
secret: nonEmpty9,
|
|
1796
|
-
leaseMs:
|
|
1882
|
+
leaseMs: z16.number().int().positive()
|
|
1797
1883
|
}),
|
|
1798
1884
|
/**
|
|
1799
1885
|
* Stop a build this runner holds, within 5 seconds. An accept that came too late, for an offer
|
|
1800
1886
|
* that had expired or was withdrawn, gets this too, with the reason `cancelled`.
|
|
1801
1887
|
*/
|
|
1802
|
-
|
|
1888
|
+
z16.object({ type: z16.literal("build-cancel"), buildId: nonEmpty9, reason: buildCancelReasonSchema }),
|
|
1803
1889
|
/** Connect again. Sent before the service closes a socket that another replaced. */
|
|
1804
|
-
|
|
1890
|
+
z16.object({ type: z16.literal("reconnect") })
|
|
1805
1891
|
]);
|
|
1806
|
-
runnerRegisterRequestSchema =
|
|
1807
|
-
runnerRegisterResponseSchema =
|
|
1892
|
+
runnerRegisterRequestSchema = z16.object({ name: z16.string().trim().min(1).max(100) });
|
|
1893
|
+
runnerRegisterResponseSchema = z16.object({
|
|
1808
1894
|
/** Shown to the owner, so they can match the approval page to the machine. */
|
|
1809
1895
|
code: nonEmpty9,
|
|
1810
1896
|
/** The page the owner opens, signed in, to approve it. */
|
|
1811
|
-
approveUrl:
|
|
1897
|
+
approveUrl: z16.url(),
|
|
1812
1898
|
/** Sent to `POST /runners/register/poll`. Only this machine has it. */
|
|
1813
1899
|
pollToken: nonEmpty9,
|
|
1814
1900
|
expiresAt: time7.optional(),
|
|
1815
1901
|
/** How often to poll. */
|
|
1816
|
-
pollMs:
|
|
1902
|
+
pollMs: z16.number().int().positive().optional()
|
|
1817
1903
|
});
|
|
1818
|
-
runnerPollRequestSchema =
|
|
1819
|
-
runnerPollResponseSchema =
|
|
1820
|
-
|
|
1904
|
+
runnerPollRequestSchema = z16.object({ pollToken: nonEmpty9.max(200) });
|
|
1905
|
+
runnerPollResponseSchema = z16.discriminatedUnion("status", [
|
|
1906
|
+
z16.object({ status: z16.literal("waiting") }),
|
|
1821
1907
|
/** Approved. The key is returned this once, and the service keeps only its hash. */
|
|
1822
|
-
|
|
1908
|
+
z16.object({ status: z16.literal("approved"), runnerId: nonEmpty9, key: nonEmpty9 }),
|
|
1823
1909
|
/** Expired, or the key was already collected. Start again. */
|
|
1824
|
-
|
|
1910
|
+
z16.object({ status: z16.literal("expired") })
|
|
1825
1911
|
]);
|
|
1826
|
-
buildStepSchema =
|
|
1827
|
-
label:
|
|
1828
|
-
key:
|
|
1829
|
-
status:
|
|
1830
|
-
ms:
|
|
1912
|
+
buildStepSchema = z16.object({
|
|
1913
|
+
label: z16.string().min(1).max(200),
|
|
1914
|
+
key: z16.string().regex(/^[0-9a-zA-Z_-]{8,128}$/),
|
|
1915
|
+
status: z16.enum(["passed", "failed", "remembered"]),
|
|
1916
|
+
ms: z16.number().int().nonnegative(),
|
|
1831
1917
|
/** Only some of the step's tests ran, so its pass isn't shared. */
|
|
1832
|
-
partial:
|
|
1833
|
-
budgetMs:
|
|
1918
|
+
partial: z16.boolean().default(false),
|
|
1919
|
+
budgetMs: z16.number().int().positive().nullable().default(null)
|
|
1834
1920
|
});
|
|
1835
|
-
buildFinishSchema =
|
|
1836
|
-
status:
|
|
1837
|
-
summary:
|
|
1838
|
-
deployed:
|
|
1921
|
+
buildFinishSchema = z16.object({
|
|
1922
|
+
status: z16.enum(["success", "failure", "error"]),
|
|
1923
|
+
summary: z16.string().max(2e3).default(""),
|
|
1924
|
+
deployed: z16.boolean().default(false)
|
|
1839
1925
|
});
|
|
1840
|
-
sharedPassSchema =
|
|
1926
|
+
sharedPassSchema = z16.object({
|
|
1841
1927
|
step: nonEmpty9,
|
|
1842
1928
|
passedAt: time7,
|
|
1843
1929
|
sha: nonEmpty9,
|
|
1844
1930
|
runner: nonEmpty9,
|
|
1845
|
-
partial:
|
|
1931
|
+
partial: z16.boolean()
|
|
1846
1932
|
});
|
|
1847
|
-
passesResponseSchema =
|
|
1848
|
-
deployCredentialsSchema =
|
|
1933
|
+
passesResponseSchema = z16.object({ passes: z16.record(z16.string(), sharedPassSchema) });
|
|
1934
|
+
deployCredentialsSchema = z16.object({
|
|
1849
1935
|
cloudflareToken: nonEmpty9,
|
|
1850
1936
|
/** Publishes `@herdingchats/friday`. Missing when the build service has none set. */
|
|
1851
1937
|
npmToken: nonEmpty9.optional(),
|
|
@@ -1854,20 +1940,20 @@ var init_builds = __esm({
|
|
|
1854
1940
|
/** `owner/name`, for moving `deployed`. */
|
|
1855
1941
|
repo: nonEmpty9,
|
|
1856
1942
|
/** The commit being built, which `deployed` moves to. Older services don't send it. */
|
|
1857
|
-
sha:
|
|
1943
|
+
sha: z16.string().regex(/^[0-9a-f]{40}$/).optional(),
|
|
1858
1944
|
/** Each Worker's key at its last successful deploy. */
|
|
1859
|
-
lastDeployed:
|
|
1945
|
+
lastDeployed: z16.record(z16.string(), z16.string())
|
|
1860
1946
|
});
|
|
1861
|
-
deployedSchema =
|
|
1862
|
-
worker:
|
|
1863
|
-
key:
|
|
1947
|
+
deployedSchema = z16.object({
|
|
1948
|
+
worker: z16.string().regex(/^[a-z][a-z0-9-]{0,62}$/),
|
|
1949
|
+
key: z16.string().regex(/^[0-9a-zA-Z_-]{8,128}$/)
|
|
1864
1950
|
});
|
|
1865
|
-
healthSchema =
|
|
1951
|
+
healthSchema = z16.object({ ok: z16.boolean(), version: z16.string() });
|
|
1866
1952
|
}
|
|
1867
1953
|
});
|
|
1868
1954
|
|
|
1869
1955
|
// ../common-chat/src/setup.ts
|
|
1870
|
-
import { z as
|
|
1956
|
+
import { z as z17 } from "zod";
|
|
1871
1957
|
function actionText(action) {
|
|
1872
1958
|
if (action.kind === "link") return `${action.label}: ${action.url}`;
|
|
1873
1959
|
if (action.kind === "sign_in") {
|
|
@@ -1902,42 +1988,42 @@ var init_setup = __esm({
|
|
|
1902
1988
|
init_activation();
|
|
1903
1989
|
init_bot();
|
|
1904
1990
|
SETUP_STEP_IDS = ["slack", "machine", "github", "repos"];
|
|
1905
|
-
setupActionSchema =
|
|
1991
|
+
setupActionSchema = z17.discriminatedUnion("kind", [
|
|
1906
1992
|
/** A page to open, which signs in to HerdingChats first. */
|
|
1907
|
-
|
|
1993
|
+
z17.object({ kind: z17.literal("link"), url: z17.string(), label: z17.string() }),
|
|
1908
1994
|
/** A command to run on the computer. */
|
|
1909
|
-
|
|
1995
|
+
z17.object({ kind: z17.literal("command"), command: z17.string() }),
|
|
1910
1996
|
/**
|
|
1911
1997
|
* A sign-in herd starts on one of the person's machines, from Slack or the page, whose code
|
|
1912
1998
|
* Friday sends to their direct message.
|
|
1913
1999
|
*/
|
|
1914
|
-
|
|
1915
|
-
kind:
|
|
1916
|
-
machineId:
|
|
2000
|
+
z17.object({
|
|
2001
|
+
kind: z17.literal("sign_in"),
|
|
2002
|
+
machineId: z17.string(),
|
|
1917
2003
|
tool: signInToolSchema,
|
|
1918
|
-
label:
|
|
2004
|
+
label: z17.string()
|
|
1919
2005
|
})
|
|
1920
2006
|
]);
|
|
1921
|
-
setupStepSchema =
|
|
1922
|
-
id:
|
|
2007
|
+
setupStepSchema = z17.object({
|
|
2008
|
+
id: z17.enum(SETUP_STEP_IDS),
|
|
1923
2009
|
/** `unavailable` is a step nobody can take yet, such as GitHub linking before an admin turns it on. */
|
|
1924
|
-
state:
|
|
1925
|
-
optional:
|
|
1926
|
-
title:
|
|
2010
|
+
state: z17.enum(["done", "todo", "unavailable"]),
|
|
2011
|
+
optional: z17.boolean(),
|
|
2012
|
+
title: z17.string(),
|
|
1927
2013
|
/** What was found, such as the machine and whether it's online, or why it can't be done yet. */
|
|
1928
|
-
detail:
|
|
2014
|
+
detail: z17.string().nullable(),
|
|
1929
2015
|
/** What to do next. None once it's done, or while it's unavailable. */
|
|
1930
2016
|
action: setupActionSchema.nullable(),
|
|
1931
2017
|
/**
|
|
1932
2018
|
* More that can be done, which doesn't decide whether the step is done, such as signing in a
|
|
1933
2019
|
* computer's GitHub CLI. Shown whatever the step's state.
|
|
1934
2020
|
*/
|
|
1935
|
-
extra:
|
|
2021
|
+
extra: z17.array(setupActionSchema).optional()
|
|
1936
2022
|
});
|
|
1937
|
-
setupStatusSchema =
|
|
1938
|
-
steps:
|
|
2023
|
+
setupStatusSchema = z17.object({
|
|
2024
|
+
steps: z17.array(setupStepSchema),
|
|
1939
2025
|
/** Whether every step that isn't optional is done, so Friday can take work. */
|
|
1940
|
-
ready:
|
|
2026
|
+
ready: z17.boolean()
|
|
1941
2027
|
});
|
|
1942
2028
|
READY_TEXT = `You're set up: mention @${BOT_NAME} in any channel it's in, or message it directly.`;
|
|
1943
2029
|
READY_SUGGESTIONS_TITLE = "Some things to try:";
|
|
@@ -1979,6 +2065,7 @@ var init_src = __esm({
|
|
|
1979
2065
|
init_pull_requests();
|
|
1980
2066
|
init_setup();
|
|
1981
2067
|
init_state();
|
|
2068
|
+
init_terminals();
|
|
1982
2069
|
init_usage();
|
|
1983
2070
|
init_work_objects();
|
|
1984
2071
|
init_workers();
|
|
@@ -2158,7 +2245,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2158
2245
|
function Text({
|
|
2159
2246
|
theme,
|
|
2160
2247
|
children,
|
|
2161
|
-
size = "md",
|
|
2248
|
+
size: size2 = "md",
|
|
2162
2249
|
bold,
|
|
2163
2250
|
muted,
|
|
2164
2251
|
faint,
|
|
@@ -2171,7 +2258,7 @@ function Text({
|
|
|
2171
2258
|
{
|
|
2172
2259
|
style: {
|
|
2173
2260
|
display: "flex",
|
|
2174
|
-
fontSize: theme.size[
|
|
2261
|
+
fontSize: theme.size[size2],
|
|
2175
2262
|
fontWeight: bold ? 700 : 400,
|
|
2176
2263
|
color: faint ? theme.faint : muted ? theme.muted : theme.ink,
|
|
2177
2264
|
lineHeight: 1.2,
|
|
@@ -2183,9 +2270,9 @@ function Text({
|
|
|
2183
2270
|
}
|
|
2184
2271
|
);
|
|
2185
2272
|
}
|
|
2186
|
-
function Icon({ icon: icon2, color, size }) {
|
|
2273
|
+
function Icon({ icon: icon2, color, size: size2 }) {
|
|
2187
2274
|
const { d, label: label3 } = ICON_PATHS[icon2];
|
|
2188
|
-
return /* @__PURE__ */ jsx("svg", { width:
|
|
2275
|
+
return /* @__PURE__ */ jsx("svg", { width: size2, height: size2, viewBox: "0 0 24 24", role: "img", "aria-label": label3, children: /* @__PURE__ */ jsx(
|
|
2189
2276
|
"path",
|
|
2190
2277
|
{
|
|
2191
2278
|
d,
|
|
@@ -2388,7 +2475,7 @@ var init_widget = __esm({
|
|
|
2388
2475
|
});
|
|
2389
2476
|
|
|
2390
2477
|
// ../common-board/src/widgets/conversations.tsx
|
|
2391
|
-
import { z as
|
|
2478
|
+
import { z as z30 } from "zod";
|
|
2392
2479
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2393
2480
|
function badge(item) {
|
|
2394
2481
|
if (pullRequestBadge(item)) {
|
|
@@ -2432,10 +2519,10 @@ var init_conversations = __esm({
|
|
|
2432
2519
|
conversations2 = defineWidget({
|
|
2433
2520
|
kind: "conversations",
|
|
2434
2521
|
describe: "Blocked, working and queued conversations, then the latest done, with what each is doing, where it came from and who holds it",
|
|
2435
|
-
options:
|
|
2436
|
-
states:
|
|
2437
|
-
limit:
|
|
2438
|
-
show:
|
|
2522
|
+
options: z30.object({
|
|
2523
|
+
states: z30.array(conversationStateSchema).min(1).default(["stuck", "working", "waiting", "done"]),
|
|
2524
|
+
limit: z30.number().int().min(1).max(BOARD_ITEMS).default(4),
|
|
2525
|
+
show: z30.array(z30.enum(DETAILS)).default([...DETAILS])
|
|
2439
2526
|
}),
|
|
2440
2527
|
reads: ["items", "machines"],
|
|
2441
2528
|
Component: ({ board, options, theme, now }) => {
|
|
@@ -2479,7 +2566,7 @@ var init_conversations = __esm({
|
|
|
2479
2566
|
});
|
|
2480
2567
|
|
|
2481
2568
|
// ../common-board/src/widgets/counts.tsx
|
|
2482
|
-
import { z as
|
|
2569
|
+
import { z as z31 } from "zod";
|
|
2483
2570
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2484
2571
|
var COUNTS, LABELS2, counts;
|
|
2485
2572
|
var init_counts = __esm({
|
|
@@ -2499,8 +2586,8 @@ var init_counts = __esm({
|
|
|
2499
2586
|
counts = defineWidget({
|
|
2500
2587
|
kind: "counts",
|
|
2501
2588
|
describe: "How many conversations are stuck, unanswered, waiting and working, and done today",
|
|
2502
|
-
options:
|
|
2503
|
-
show:
|
|
2589
|
+
options: z31.object({
|
|
2590
|
+
show: z31.array(z31.enum(COUNTS)).min(1).max(5).default([...COUNTS])
|
|
2504
2591
|
}),
|
|
2505
2592
|
reads: ["counts", "doneToday"],
|
|
2506
2593
|
Component: ({ board, options, theme }) => {
|
|
@@ -2539,7 +2626,7 @@ var init_counts = __esm({
|
|
|
2539
2626
|
});
|
|
2540
2627
|
|
|
2541
2628
|
// ../common-board/src/widgets/header.tsx
|
|
2542
|
-
import { z as
|
|
2629
|
+
import { z as z32 } from "zod";
|
|
2543
2630
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2544
2631
|
function summary(board) {
|
|
2545
2632
|
const parts = [
|
|
@@ -2564,9 +2651,9 @@ var init_header = __esm({
|
|
|
2564
2651
|
header = defineWidget({
|
|
2565
2652
|
kind: "header",
|
|
2566
2653
|
describe: "The board's title, a line of how much is open, and when it was drawn",
|
|
2567
|
-
options:
|
|
2568
|
-
title:
|
|
2569
|
-
summary:
|
|
2654
|
+
options: z32.object({
|
|
2655
|
+
title: z32.string().min(1).max(40).default(`@${BOT_NAME}`),
|
|
2656
|
+
summary: z32.boolean().default(true)
|
|
2570
2657
|
}),
|
|
2571
2658
|
reads: ["counts"],
|
|
2572
2659
|
Component: ({ board, options, theme, now }) => {
|
|
@@ -2584,7 +2671,7 @@ var init_header = __esm({
|
|
|
2584
2671
|
});
|
|
2585
2672
|
|
|
2586
2673
|
// ../common-board/src/widgets/machines.tsx
|
|
2587
|
-
import { z as
|
|
2674
|
+
import { z as z33 } from "zod";
|
|
2588
2675
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2589
2676
|
function usageText(worker) {
|
|
2590
2677
|
const usage = worker.usage;
|
|
@@ -2615,7 +2702,7 @@ var init_machines2 = __esm({
|
|
|
2615
2702
|
machines = defineWidget({
|
|
2616
2703
|
kind: "machines",
|
|
2617
2704
|
describe: "One bubble per agent on an online machine, with its usage, most recently active first",
|
|
2618
|
-
options:
|
|
2705
|
+
options: z33.object({ limit: z33.number().int().min(1).max(8).default(3) }),
|
|
2619
2706
|
reads: ["machines"],
|
|
2620
2707
|
Component: ({ board, options, theme }) => {
|
|
2621
2708
|
const workers2 = board.machines.filter((machine) => machine.online).flatMap((machine) => machine.workers.map((worker) => ({ ...worker, machine: machine.name }))).sort((a, b) => (b.reportedAt ?? 0) - (a.reportedAt ?? 0));
|
|
@@ -2732,9 +2819,9 @@ var init_board2 = __esm({
|
|
|
2732
2819
|
});
|
|
2733
2820
|
|
|
2734
2821
|
// ../common-board/src/composition.ts
|
|
2735
|
-
import { z as
|
|
2822
|
+
import { z as z34 } from "zod";
|
|
2736
2823
|
function readComposition(stored) {
|
|
2737
|
-
const shape =
|
|
2824
|
+
const shape = z34.object({ widgets: z34.array(placedWidgetSchema) }).safeParse(stored);
|
|
2738
2825
|
if (!shape.success) return DEFAULT_COMPOSITION;
|
|
2739
2826
|
const known = shape.data.widgets.filter(
|
|
2740
2827
|
(widget) => WIDGETS[widget.kind]?.options.safeParse(widget.options).success
|
|
@@ -2749,11 +2836,11 @@ var init_composition = __esm({
|
|
|
2749
2836
|
init_registry();
|
|
2750
2837
|
MAX_WIDGETS = 12;
|
|
2751
2838
|
MAX_COMPOSITION_BYTES = 4096;
|
|
2752
|
-
placedWidgetSchema =
|
|
2753
|
-
kind:
|
|
2754
|
-
options:
|
|
2839
|
+
placedWidgetSchema = z34.object({
|
|
2840
|
+
kind: z34.string().min(1),
|
|
2841
|
+
options: z34.record(z34.string(), z34.unknown()).default({})
|
|
2755
2842
|
});
|
|
2756
|
-
compositionSchema =
|
|
2843
|
+
compositionSchema = z34.object({ widgets: z34.array(placedWidgetSchema).max(MAX_WIDGETS) }).superRefine((composition, context2) => {
|
|
2757
2844
|
if (JSON.stringify(composition).length > MAX_COMPOSITION_BYTES) {
|
|
2758
2845
|
context2.addIssue({
|
|
2759
2846
|
code: "custom",
|
|
@@ -3213,7 +3300,7 @@ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node
|
|
|
3213
3300
|
import { homedir as homedir5 } from "node:os";
|
|
3214
3301
|
import { dirname as dirname10, join as join16 } from "node:path";
|
|
3215
3302
|
import { createInterface } from "node:readline/promises";
|
|
3216
|
-
import { z as
|
|
3303
|
+
import { z as z23 } from "zod";
|
|
3217
3304
|
|
|
3218
3305
|
// src/auth.ts
|
|
3219
3306
|
init_define_HERD_PACKAGE();
|
|
@@ -3222,21 +3309,21 @@ import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:
|
|
|
3222
3309
|
import { createServer } from "node:http";
|
|
3223
3310
|
import { homedir } from "node:os";
|
|
3224
3311
|
import { join } from "node:path";
|
|
3225
|
-
import { z as
|
|
3312
|
+
import { z as z18 } from "zod";
|
|
3226
3313
|
var herdHome = () => process.env.HERD_HOME ?? join(homedir(), ".herd");
|
|
3227
3314
|
var apiUrl = () => (process.env.HERD_API_URL ?? "https://api.herdingchats.com").replace(/\/+$/, "");
|
|
3228
3315
|
var isLocal = (url) => /^http:\/\/localhost:\d+\/?$/.test(url);
|
|
3229
3316
|
var localSignIn = () => process.env.HERD_LOCAL_SLACK ? { "X-Herd-Local-Slack": process.env.HERD_LOCAL_SLACK } : {};
|
|
3230
3317
|
var HerdError = class extends Error {
|
|
3231
3318
|
};
|
|
3232
|
-
var credentialsSchema =
|
|
3233
|
-
api:
|
|
3234
|
-
tokenEndpoint:
|
|
3235
|
-
revocationEndpoint:
|
|
3236
|
-
clientId:
|
|
3237
|
-
accessToken:
|
|
3238
|
-
accessTokenExpiresAt:
|
|
3239
|
-
refreshToken:
|
|
3319
|
+
var credentialsSchema = z18.object({
|
|
3320
|
+
api: z18.string(),
|
|
3321
|
+
tokenEndpoint: z18.string(),
|
|
3322
|
+
revocationEndpoint: z18.string().optional(),
|
|
3323
|
+
clientId: z18.string(),
|
|
3324
|
+
accessToken: z18.string(),
|
|
3325
|
+
accessTokenExpiresAt: z18.number(),
|
|
3326
|
+
refreshToken: z18.string()
|
|
3240
3327
|
});
|
|
3241
3328
|
var credentialsPath = () => join(herdHome(), "credentials.json");
|
|
3242
3329
|
function readCredentials() {
|
|
@@ -3252,16 +3339,16 @@ function writeCredentials(credentials) {
|
|
|
3252
3339
|
writeFileSync(credentialsPath(), JSON.stringify(credentials, null, 2), { mode: 384 });
|
|
3253
3340
|
chmodSync(credentialsPath(), 384);
|
|
3254
3341
|
}
|
|
3255
|
-
var metadataSchema =
|
|
3256
|
-
authorization_endpoint:
|
|
3257
|
-
token_endpoint:
|
|
3258
|
-
registration_endpoint:
|
|
3259
|
-
revocation_endpoint:
|
|
3342
|
+
var metadataSchema = z18.object({
|
|
3343
|
+
authorization_endpoint: z18.string(),
|
|
3344
|
+
token_endpoint: z18.string(),
|
|
3345
|
+
registration_endpoint: z18.string(),
|
|
3346
|
+
revocation_endpoint: z18.string().optional()
|
|
3260
3347
|
});
|
|
3261
|
-
var tokenSchema =
|
|
3262
|
-
access_token:
|
|
3263
|
-
refresh_token:
|
|
3264
|
-
expires_in:
|
|
3348
|
+
var tokenSchema = z18.object({
|
|
3349
|
+
access_token: z18.string().min(1),
|
|
3350
|
+
refresh_token: z18.string().min(1),
|
|
3351
|
+
expires_in: z18.number()
|
|
3265
3352
|
});
|
|
3266
3353
|
var base64url = (bytes) => bytes.toString("base64url");
|
|
3267
3354
|
async function postForm(url, fields) {
|
|
@@ -3293,7 +3380,7 @@ async function login(openBrowser2, { api = apiUrl(), timeoutMs = 10 * 60 * 1e3 }
|
|
|
3293
3380
|
token_endpoint_auth_method: "none"
|
|
3294
3381
|
})
|
|
3295
3382
|
});
|
|
3296
|
-
const client =
|
|
3383
|
+
const client = z18.object({ client_id: z18.string() }).safeParse(await registration2.json());
|
|
3297
3384
|
if (!registration2.ok || !client.success) {
|
|
3298
3385
|
throw new HerdError("The sign-in server refused to register this tool.");
|
|
3299
3386
|
}
|
|
@@ -3527,7 +3614,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3527
3614
|
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync4, realpathSync as realpathSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
3528
3615
|
import { homedir as homedir3, hostname } from "node:os";
|
|
3529
3616
|
import { basename, dirname as dirname4, join as join6, resolve } from "node:path";
|
|
3530
|
-
import { z as
|
|
3617
|
+
import { z as z19 } from "zod";
|
|
3531
3618
|
|
|
3532
3619
|
// src/login-shell.ts
|
|
3533
3620
|
init_define_HERD_PACKAGE();
|
|
@@ -3653,16 +3740,16 @@ function recordTime(line2) {
|
|
|
3653
3740
|
return Number.isNaN(time8) ? 0 : time8;
|
|
3654
3741
|
}
|
|
3655
3742
|
function readNew(path, offset) {
|
|
3656
|
-
let
|
|
3743
|
+
let size2;
|
|
3657
3744
|
try {
|
|
3658
|
-
|
|
3745
|
+
size2 = statSync(path).size;
|
|
3659
3746
|
} catch {
|
|
3660
3747
|
return { events: [], offset };
|
|
3661
3748
|
}
|
|
3662
|
-
if (
|
|
3749
|
+
if (size2 <= offset) return { events: [], offset };
|
|
3663
3750
|
const fd = openSync(path, "r");
|
|
3664
3751
|
try {
|
|
3665
|
-
const buffer = Buffer.alloc(
|
|
3752
|
+
const buffer = Buffer.alloc(size2 - offset);
|
|
3666
3753
|
const read = readSync(fd, buffer, 0, buffer.length, offset);
|
|
3667
3754
|
const chunk = buffer.subarray(0, read);
|
|
3668
3755
|
const end = chunk.lastIndexOf(10);
|
|
@@ -3763,9 +3850,9 @@ function latestCodexUsage(home = codexHome()) {
|
|
|
3763
3850
|
if (!newest) return null;
|
|
3764
3851
|
let tail3;
|
|
3765
3852
|
try {
|
|
3766
|
-
const
|
|
3767
|
-
const start = Math.max(0,
|
|
3768
|
-
const buffer = Buffer.alloc(
|
|
3853
|
+
const size2 = statSync(newest).size;
|
|
3854
|
+
const start = Math.max(0, size2 - USAGE_TAIL_BYTES);
|
|
3855
|
+
const buffer = Buffer.alloc(size2 - start);
|
|
3769
3856
|
const fd = openSync(newest, "r");
|
|
3770
3857
|
try {
|
|
3771
3858
|
readSync(fd, buffer, 0, buffer.length, start);
|
|
@@ -4306,13 +4393,13 @@ function hasUnpushed(path) {
|
|
|
4306
4393
|
|
|
4307
4394
|
// src/config.ts
|
|
4308
4395
|
init_self();
|
|
4309
|
-
var repoSchema =
|
|
4310
|
-
var configSchema =
|
|
4311
|
-
machineId:
|
|
4312
|
-
machineName:
|
|
4313
|
-
repos:
|
|
4396
|
+
var repoSchema = z19.object({ name: z19.string(), path: z19.string(), remote: z19.string() });
|
|
4397
|
+
var configSchema = z19.object({
|
|
4398
|
+
machineId: z19.string(),
|
|
4399
|
+
machineName: z19.string(),
|
|
4400
|
+
repos: z19.array(repoSchema),
|
|
4314
4401
|
/** The machine's root folder, holding herd's clones and its conversations' folders. */
|
|
4315
|
-
root:
|
|
4402
|
+
root: z19.string().optional()
|
|
4316
4403
|
});
|
|
4317
4404
|
var configPath = () => join6(herdHome(), "config.json");
|
|
4318
4405
|
function save(config) {
|
|
@@ -4528,23 +4615,23 @@ init_src();
|
|
|
4528
4615
|
import { randomBytes as randomBytes4, randomUUID as randomUUID3 } from "node:crypto";
|
|
4529
4616
|
import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, renameSync as renameSync2, rmSync as rmSync6, statSync as statSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
4530
4617
|
import { dirname as dirname5, join as join8 } from "node:path";
|
|
4531
|
-
import { z as
|
|
4618
|
+
import { z as z22 } from "zod";
|
|
4532
4619
|
|
|
4533
4620
|
// src/permissions.ts
|
|
4534
4621
|
init_define_HERD_PACKAGE();
|
|
4535
4622
|
init_src();
|
|
4536
4623
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
4537
|
-
import { z as
|
|
4624
|
+
import { z as z21 } from "zod";
|
|
4538
4625
|
|
|
4539
4626
|
// src/local-socket.ts
|
|
4540
4627
|
init_define_HERD_PACKAGE();
|
|
4541
4628
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
4542
4629
|
import { chmodSync as chmodSync2, existsSync as existsSync4, rmSync as rmSync4 } from "node:fs";
|
|
4543
4630
|
import { connect, createServer as createServer2 } from "node:net";
|
|
4544
|
-
import { z as
|
|
4545
|
-
var localRequestSchema =
|
|
4546
|
-
secret:
|
|
4547
|
-
op:
|
|
4631
|
+
import { z as z20 } from "zod";
|
|
4632
|
+
var localRequestSchema = z20.object({
|
|
4633
|
+
secret: z20.string().min(1),
|
|
4634
|
+
op: z20.enum([
|
|
4548
4635
|
"inbox",
|
|
4549
4636
|
"send",
|
|
4550
4637
|
"run",
|
|
@@ -4576,32 +4663,32 @@ var localRequestSchema = z19.object({
|
|
|
4576
4663
|
"activate"
|
|
4577
4664
|
]),
|
|
4578
4665
|
// The key of the agent's start, from `HERD_START`, which `herd inbox` proves the start with.
|
|
4579
|
-
start:
|
|
4666
|
+
start: z20.string().min(1).max(100).optional(),
|
|
4580
4667
|
// `herd repo`: the repo it added to the conversation's folder, for the daemon to record.
|
|
4581
|
-
repo:
|
|
4582
|
-
remote:
|
|
4583
|
-
folder:
|
|
4584
|
-
base:
|
|
4585
|
-
fetchFailed:
|
|
4668
|
+
repo: z20.object({
|
|
4669
|
+
remote: z20.string().min(1).max(500),
|
|
4670
|
+
folder: z20.string().min(1).max(100),
|
|
4671
|
+
base: z20.string().min(1).max(300).optional(),
|
|
4672
|
+
fetchFailed: z20.string().max(1e3).optional()
|
|
4586
4673
|
}).optional(),
|
|
4587
4674
|
// `herd repo`: what the agent named and the folder it asked for, for the daemon to add.
|
|
4588
|
-
repoAdd:
|
|
4589
|
-
asked:
|
|
4590
|
-
folder:
|
|
4675
|
+
repoAdd: z20.object({
|
|
4676
|
+
asked: z20.string().min(1).max(500),
|
|
4677
|
+
folder: z20.string().min(1).max(100).optional()
|
|
4591
4678
|
}).optional(),
|
|
4592
4679
|
// `herd delegate --repo`, given once for each repo the delegate works in.
|
|
4593
|
-
repos:
|
|
4680
|
+
repos: z20.array(z20.string().min(1).max(500)).max(10).optional(),
|
|
4594
4681
|
// `herd watch`, `herd unwatch` and `herd watching`: what to do, and the pull request.
|
|
4595
|
-
watch:
|
|
4596
|
-
action:
|
|
4597
|
-
url:
|
|
4682
|
+
watch: z20.object({
|
|
4683
|
+
action: z20.enum(["watch", "unwatch", "list"]),
|
|
4684
|
+
url: z20.string().min(1).max(500).optional()
|
|
4598
4685
|
}).optional(),
|
|
4599
4686
|
// `herd delegate`, `herd tell` and `herd handoff`: the worker or conversation they name.
|
|
4600
|
-
worker:
|
|
4601
|
-
to:
|
|
4687
|
+
worker: z20.string().min(1).max(200).optional(),
|
|
4688
|
+
to: z20.string().min(1).max(200).optional(),
|
|
4602
4689
|
// `herd automations`: what to do, to which automation, and the definition or change it sends.
|
|
4603
|
-
automation:
|
|
4604
|
-
action:
|
|
4690
|
+
automation: z20.object({
|
|
4691
|
+
action: z20.enum([
|
|
4605
4692
|
"list",
|
|
4606
4693
|
"show",
|
|
4607
4694
|
"create",
|
|
@@ -4612,47 +4699,47 @@ var localRequestSchema = z19.object({
|
|
|
4612
4699
|
"test",
|
|
4613
4700
|
"rotate"
|
|
4614
4701
|
]),
|
|
4615
|
-
id:
|
|
4616
|
-
body:
|
|
4617
|
-
waitMs:
|
|
4702
|
+
id: z20.string().min(1).max(100).optional(),
|
|
4703
|
+
body: z20.record(z20.string(), z20.unknown()).optional(),
|
|
4704
|
+
waitMs: z20.number().int().min(0).max(6e5).optional()
|
|
4618
4705
|
}).optional(),
|
|
4619
4706
|
// `herd work`: list, record or remove one, with the change the daemon checks again.
|
|
4620
|
-
work:
|
|
4621
|
-
action:
|
|
4622
|
-
change:
|
|
4623
|
-
url:
|
|
4707
|
+
work: z20.object({
|
|
4708
|
+
action: z20.enum(["list", "record", "remove"]),
|
|
4709
|
+
change: z20.unknown().optional(),
|
|
4710
|
+
url: z20.string().min(1).max(2048).optional()
|
|
4624
4711
|
}).optional(),
|
|
4625
4712
|
// `herd conversations --about <url>`: only the owner's conversations about that URL.
|
|
4626
|
-
about:
|
|
4713
|
+
about: z20.string().min(1).max(2048).optional(),
|
|
4627
4714
|
// `herd investigate screen` or `herd investigate propose`, with the proposal the daemon checks.
|
|
4628
|
-
action:
|
|
4629
|
-
proposal:
|
|
4715
|
+
action: z20.enum(["screen", "propose"]).optional(),
|
|
4716
|
+
proposal: z20.unknown().optional(),
|
|
4630
4717
|
// Commands may name a conversation, but only their own is ever allowed.
|
|
4631
|
-
conversationId:
|
|
4718
|
+
conversationId: z20.string().optional(),
|
|
4632
4719
|
// Where `conversations` is shown, which decides whether private titles are. Only the terminal's
|
|
4633
4720
|
// own conversation is ever allowed, so a terminal can't pick one that shows more.
|
|
4634
|
-
for:
|
|
4635
|
-
text:
|
|
4721
|
+
for: z20.string().optional(),
|
|
4722
|
+
text: z20.string().optional(),
|
|
4636
4723
|
// A whole message, from `herd send --json`, which the daemon checks again.
|
|
4637
|
-
message:
|
|
4638
|
-
idempotencyKey:
|
|
4639
|
-
command:
|
|
4724
|
+
message: z20.unknown().optional(),
|
|
4725
|
+
idempotencyKey: z20.string().optional(),
|
|
4726
|
+
command: z20.array(z20.string()).optional(),
|
|
4640
4727
|
// `status --clear`.
|
|
4641
|
-
clear:
|
|
4728
|
+
clear: z20.boolean().optional(),
|
|
4642
4729
|
// What an agent's status line reported, checked by the daemon.
|
|
4643
|
-
usage:
|
|
4730
|
+
usage: z20.unknown().optional(),
|
|
4644
4731
|
// Which agent and session a status line ran for. Its reports count only from the session herd
|
|
4645
4732
|
// started in the conversation's lead terminal.
|
|
4646
|
-
agent:
|
|
4647
|
-
sessionId:
|
|
4733
|
+
agent: z20.enum(["claude-code", "codex", "agy"]).optional(),
|
|
4734
|
+
sessionId: z20.string().min(1).max(200).optional(),
|
|
4648
4735
|
// What agy's status line says its agent is doing: `working` or `idle`.
|
|
4649
|
-
state:
|
|
4736
|
+
state: z20.enum(["working", "idle"]).optional(),
|
|
4650
4737
|
// A permission request from Claude Code's hook, with the key it keeps across reconnects.
|
|
4651
|
-
key:
|
|
4652
|
-
request:
|
|
4738
|
+
key: z20.string().min(1).max(200).optional(),
|
|
4739
|
+
request: z20.unknown().optional(),
|
|
4653
4740
|
// For one of Claude Code's other hooks: which event, and the JSON Claude Code gave it.
|
|
4654
|
-
event:
|
|
4655
|
-
input:
|
|
4741
|
+
event: z20.string().optional(),
|
|
4742
|
+
input: z20.record(z20.string(), z20.unknown()).optional()
|
|
4656
4743
|
});
|
|
4657
4744
|
var LocalSocket = class {
|
|
4658
4745
|
constructor(path, handle) {
|
|
@@ -4774,10 +4861,10 @@ function isAnswering(path) {
|
|
|
4774
4861
|
}
|
|
4775
4862
|
|
|
4776
4863
|
// src/permissions.ts
|
|
4777
|
-
var hookRequestSchema =
|
|
4778
|
-
tool_name:
|
|
4779
|
-
tool_input:
|
|
4780
|
-
permission_suggestions:
|
|
4864
|
+
var hookRequestSchema = z21.looseObject({
|
|
4865
|
+
tool_name: z21.string().min(1),
|
|
4866
|
+
tool_input: z21.record(z21.string(), z21.unknown()).default({}),
|
|
4867
|
+
permission_suggestions: z21.array(z21.unknown()).optional()
|
|
4781
4868
|
});
|
|
4782
4869
|
var DETAIL_LIMIT = 2800;
|
|
4783
4870
|
var REPLY_MESSAGE_LIMIT = 2e3;
|
|
@@ -5227,9 +5314,9 @@ var activationTerminal = (agent) => `herd-activate-${agentShortName(agent)}`;
|
|
|
5227
5314
|
var activationFolder = (root, agent) => join8(convosHome(root), ".activate", agentShortName(agent));
|
|
5228
5315
|
var recordSchema = agentActivationSchema.extend({
|
|
5229
5316
|
/** While it's waiting: the terminal it runs in, which `friday start` can attach to. */
|
|
5230
|
-
terminal:
|
|
5317
|
+
terminal: z22.string().optional()
|
|
5231
5318
|
});
|
|
5232
|
-
var storeSchema =
|
|
5319
|
+
var storeSchema = z22.object({ agents: z22.record(z22.string(), recordSchema) });
|
|
5233
5320
|
var activationsPath = (home = herdHome()) => join8(home, "activations.json");
|
|
5234
5321
|
var activationRequestPath = (home = herdHome()) => join8(home, "activate-request");
|
|
5235
5322
|
function readActivations(path = activationsPath()) {
|
|
@@ -6966,7 +7053,7 @@ function defaults() {
|
|
|
6966
7053
|
print: (line2) => console.log(line2)
|
|
6967
7054
|
};
|
|
6968
7055
|
}
|
|
6969
|
-
var releaseSchema =
|
|
7056
|
+
var releaseSchema = z23.object({ version: z23.string().min(1), integrity: z23.string().min(1) });
|
|
6970
7057
|
async function fetchRelease() {
|
|
6971
7058
|
const response = await apiFetch("/api/daemon/release");
|
|
6972
7059
|
if (response.status === 404) return null;
|
|
@@ -7607,11 +7694,11 @@ init_define_HERD_PACKAGE();
|
|
|
7607
7694
|
// src/investigator.ts
|
|
7608
7695
|
init_define_HERD_PACKAGE();
|
|
7609
7696
|
init_src();
|
|
7610
|
-
import { z as
|
|
7697
|
+
import { z as z24 } from "zod";
|
|
7611
7698
|
var INVESTIGATE_KEYS = ["escape", "up", "down", "enter", "tab"];
|
|
7612
|
-
var proposalSchema =
|
|
7613
|
-
key:
|
|
7614
|
-
reason:
|
|
7699
|
+
var proposalSchema = z24.object({
|
|
7700
|
+
key: z24.enum([...INVESTIGATE_KEYS, "none"]),
|
|
7701
|
+
reason: z24.string().trim().min(1).max(300)
|
|
7615
7702
|
});
|
|
7616
7703
|
var KEY_LABELS = {
|
|
7617
7704
|
escape: "Esc",
|
|
@@ -8021,12 +8108,12 @@ init_define_HERD_PACKAGE();
|
|
|
8021
8108
|
init_src();
|
|
8022
8109
|
import { chmodSync as chmodSync3, existsSync as existsSync14, mkdirSync as mkdirSync14, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
8023
8110
|
import { join as join19 } from "node:path";
|
|
8024
|
-
import { z as
|
|
8111
|
+
import { z as z25 } from "zod";
|
|
8025
8112
|
var BUILDS_URL = "https://builds.herdingchats.com";
|
|
8026
|
-
var runnerKeySchema =
|
|
8027
|
-
runnerId:
|
|
8028
|
-
key:
|
|
8029
|
-
url:
|
|
8113
|
+
var runnerKeySchema = z25.object({
|
|
8114
|
+
runnerId: z25.string().min(1),
|
|
8115
|
+
key: z25.string().min(20),
|
|
8116
|
+
url: z25.string().url()
|
|
8030
8117
|
});
|
|
8031
8118
|
var runnerKeyPath = () => join19(herdHome(), "build-runner.json");
|
|
8032
8119
|
function readRunnerKey() {
|
|
@@ -8095,33 +8182,33 @@ async function registerRunner({
|
|
|
8095
8182
|
|
|
8096
8183
|
// src/build-speed.ts
|
|
8097
8184
|
init_define_HERD_PACKAGE();
|
|
8098
|
-
import { z as
|
|
8099
|
-
var ms =
|
|
8100
|
-
var figuresSchema =
|
|
8101
|
-
var buildTimesSchema =
|
|
8102
|
-
var stepFiguresSchema =
|
|
8103
|
-
ran:
|
|
8104
|
-
remembered:
|
|
8185
|
+
import { z as z26 } from "zod";
|
|
8186
|
+
var ms = z26.number().int().nullable();
|
|
8187
|
+
var figuresSchema = z26.object({ count: z26.number().int(), median: ms, p90: ms });
|
|
8188
|
+
var buildTimesSchema = z26.object({ run: figuresSchema, push: figuresSchema });
|
|
8189
|
+
var stepFiguresSchema = z26.object({
|
|
8190
|
+
ran: z26.number().int(),
|
|
8191
|
+
remembered: z26.number().int(),
|
|
8105
8192
|
median: ms,
|
|
8106
8193
|
p90: ms,
|
|
8107
|
-
overBudget:
|
|
8194
|
+
overBudget: z26.number().int()
|
|
8108
8195
|
});
|
|
8109
|
-
var kindSchema =
|
|
8110
|
-
builds:
|
|
8111
|
-
steps:
|
|
8112
|
-
|
|
8196
|
+
var kindSchema = z26.object({
|
|
8197
|
+
builds: z26.object({ current: buildTimesSchema, previous: buildTimesSchema }),
|
|
8198
|
+
steps: z26.array(
|
|
8199
|
+
z26.object({ label: z26.string(), current: stepFiguresSchema, previous: stepFiguresSchema })
|
|
8113
8200
|
),
|
|
8114
|
-
overBudget:
|
|
8115
|
-
|
|
8201
|
+
overBudget: z26.array(
|
|
8202
|
+
z26.object({ label: z26.string(), current: z26.number().int(), previous: z26.number().int() })
|
|
8116
8203
|
)
|
|
8117
8204
|
});
|
|
8118
|
-
var range =
|
|
8119
|
-
var speedReportSchema =
|
|
8120
|
-
periods:
|
|
8121
|
-
repos:
|
|
8122
|
-
|
|
8123
|
-
repo:
|
|
8124
|
-
capped:
|
|
8205
|
+
var range = z26.object({ from: z26.number(), to: z26.number() });
|
|
8206
|
+
var speedReportSchema = z26.object({
|
|
8207
|
+
periods: z26.object({ current: range, previous: range }),
|
|
8208
|
+
repos: z26.array(
|
|
8209
|
+
z26.object({
|
|
8210
|
+
repo: z26.string(),
|
|
8211
|
+
capped: z26.boolean(),
|
|
8125
8212
|
pullRequests: kindSchema,
|
|
8126
8213
|
main: kindSchema
|
|
8127
8214
|
})
|
|
@@ -10847,7 +10934,7 @@ init_define_HERD_PACKAGE();
|
|
|
10847
10934
|
init_src();
|
|
10848
10935
|
init_self();
|
|
10849
10936
|
import { join as join28 } from "node:path";
|
|
10850
|
-
import { z as
|
|
10937
|
+
import { z as z27 } from "zod";
|
|
10851
10938
|
function hasThread(events) {
|
|
10852
10939
|
return events.some(
|
|
10853
10940
|
(event2) => event2.type === "prompt.opened" || event2.type === "message.created" && !(event2.payload.direction === "inbound" && event2.payload.automation) && !event2.payload.quiet && !event2.payload.post
|
|
@@ -10913,16 +11000,16 @@ var WAITING_NOTIFICATIONS = /* @__PURE__ */ new Set([
|
|
|
10913
11000
|
"agent_needs_input",
|
|
10914
11001
|
"elicitation_dialog"
|
|
10915
11002
|
]);
|
|
10916
|
-
var agentMessageSchema =
|
|
10917
|
-
text:
|
|
10918
|
-
files:
|
|
11003
|
+
var agentMessageSchema = z27.object({
|
|
11004
|
+
text: z27.string().trim().min(1).max(12e3),
|
|
11005
|
+
files: z27.array(z27.object({ path: z27.string().min(1), title: z27.string().optional() })).max(10).optional()
|
|
10919
11006
|
});
|
|
10920
|
-
var workspaceRepoSchema =
|
|
10921
|
-
folder:
|
|
10922
|
-
remote:
|
|
10923
|
-
branch:
|
|
11007
|
+
var workspaceRepoSchema = z27.object({
|
|
11008
|
+
folder: z27.string(),
|
|
11009
|
+
remote: z27.string(),
|
|
11010
|
+
branch: z27.string(),
|
|
10924
11011
|
/** For a conversation from before folders: the name of the repo it was allowed as. */
|
|
10925
|
-
name:
|
|
11012
|
+
name: z27.string().optional()
|
|
10926
11013
|
});
|
|
10927
11014
|
function fromBeforeFolders(raw) {
|
|
10928
11015
|
if (!raw || typeof raw !== "object" || "folder" in raw) return raw;
|
|
@@ -10943,106 +11030,106 @@ function fromBeforeFolders(raw) {
|
|
|
10943
11030
|
legacy: true
|
|
10944
11031
|
};
|
|
10945
11032
|
}
|
|
10946
|
-
var workspaceFields =
|
|
10947
|
-
conversationId:
|
|
11033
|
+
var workspaceFields = z27.object({
|
|
11034
|
+
conversationId: z27.string(),
|
|
10948
11035
|
/** The conversation's own folder, where its terminals start. */
|
|
10949
|
-
folder:
|
|
11036
|
+
folder: z27.string(),
|
|
10950
11037
|
/** The repos in it, in the order they were added. */
|
|
10951
|
-
worktrees:
|
|
11038
|
+
worktrees: z27.array(workspaceRepoSchema).default([]),
|
|
10952
11039
|
/** A conversation from before folders, which works in its one repo's worktree. */
|
|
10953
|
-
legacy:
|
|
10954
|
-
lead:
|
|
10955
|
-
secret:
|
|
10956
|
-
readSeq:
|
|
10957
|
-
claimId:
|
|
10958
|
-
claimRenewedAt:
|
|
10959
|
-
started:
|
|
11040
|
+
legacy: z27.boolean().default(false),
|
|
11041
|
+
lead: z27.string(),
|
|
11042
|
+
secret: z27.string(),
|
|
11043
|
+
readSeq: z27.number(),
|
|
11044
|
+
claimId: z27.string().nullable(),
|
|
11045
|
+
claimRenewedAt: z27.number(),
|
|
11046
|
+
started: z27.boolean(),
|
|
10960
11047
|
/** Messages to deliver once the current turn ends. */
|
|
10961
|
-
deferred:
|
|
11048
|
+
deferred: z27.boolean(),
|
|
10962
11049
|
/** A `herd run` command finished, which the agent hears about even with nothing to claim. */
|
|
10963
|
-
terminalNotice:
|
|
10964
|
-
status:
|
|
11050
|
+
terminalNotice: z27.boolean().default(false),
|
|
11051
|
+
status: z27.string().nullable(),
|
|
10965
11052
|
/** Set once the thread has been told the agent is waiting, so it's told once per wait. */
|
|
10966
|
-
toldWaiting:
|
|
10967
|
-
runs:
|
|
11053
|
+
toldWaiting: z27.boolean(),
|
|
11054
|
+
runs: z27.array(z27.object({ name: z27.string(), secret: z27.string(), reported: z27.boolean() })),
|
|
10968
11055
|
/** The subscription usage Claude Code last reported in this worktree. */
|
|
10969
11056
|
usage: usageSchema.nullable().default(null),
|
|
10970
11057
|
/** When that usage was reported, or 0 if it was before this was kept. */
|
|
10971
|
-
usageAt:
|
|
11058
|
+
usageAt: z27.number().default(0),
|
|
10972
11059
|
/** The lead agent's Claude Code session, as its `SessionStart` hook reported it. */
|
|
10973
|
-
sessionId:
|
|
11060
|
+
sessionId: z27.string().nullable().default(null),
|
|
10974
11061
|
/** When the agent's last turn ended with nothing left to do, for shutting it down later. */
|
|
10975
|
-
idleSince:
|
|
11062
|
+
idleSince: z27.number().nullable().default(null),
|
|
10976
11063
|
/** The agent ran `herd exit`, so its session ends after this turn. */
|
|
10977
|
-
exitRequested:
|
|
11064
|
+
exitRequested: z27.boolean().default(false),
|
|
10978
11065
|
/** Whether the agent sent anything with `herd send` this turn. */
|
|
10979
|
-
sentThisTurn:
|
|
11066
|
+
sentThisTurn: z27.boolean().default(false),
|
|
10980
11067
|
/** Whether it's been asked this turn to reply. */
|
|
10981
|
-
askedToReply:
|
|
11068
|
+
askedToReply: z27.boolean().default(false),
|
|
10982
11069
|
/** Whether it ran `herd handled` this turn, which handles the turn's messages with no reply. */
|
|
10983
|
-
handledThisTurn:
|
|
11070
|
+
handledThisTurn: z27.boolean().default(false),
|
|
10984
11071
|
/** The newest waiting message it's been pointed at, so one arrival is pointed out once. */
|
|
10985
|
-
nudgedSeq:
|
|
11072
|
+
nudgedSeq: z27.number().default(0),
|
|
10986
11073
|
/** When a `Stop` hook last ended a turn. */
|
|
10987
|
-
hookIdleAt:
|
|
11074
|
+
hookIdleAt: z27.number().default(0),
|
|
10988
11075
|
/** When a turn last ended with background work still running, which keeps its messages held. */
|
|
10989
|
-
pausedAt:
|
|
11076
|
+
pausedAt: z27.number().nullable().default(null),
|
|
10990
11077
|
/** The version of the terminal host the lead terminal was opened in, if it was recorded. */
|
|
10991
|
-
hostVersion:
|
|
11078
|
+
hostVersion: z27.string().nullable().default(null),
|
|
10992
11079
|
/** When a notice last failed for a reason other than someone's draft, to wait before retrying. */
|
|
10993
|
-
noticeFailedAt:
|
|
11080
|
+
noticeFailedAt: z27.number().nullable().default(null),
|
|
10994
11081
|
/** Why the last notice failed, so the history records each reason once, not every attempt. */
|
|
10995
|
-
noticeFailure:
|
|
11082
|
+
noticeFailure: z27.string().nullable().default(null),
|
|
10996
11083
|
/** A recorded dialog herd pressed its way out of, so a dialog that stays isn't pressed again. */
|
|
10997
|
-
closedDialog:
|
|
11084
|
+
closedDialog: z27.string().nullable().default(null),
|
|
10998
11085
|
/**
|
|
10999
11086
|
* Prompts Claude Code's hooks reported that haven't had their `Stop`. A turn is open while this
|
|
11000
11087
|
* is above zero. It's a count because a prompt queued mid-turn is reported as it's queued, and
|
|
11001
11088
|
* runs as a turn of its own, ending with a second `Stop`.
|
|
11002
11089
|
*/
|
|
11003
|
-
promptsOpen:
|
|
11090
|
+
promptsOpen: z27.number().default(0),
|
|
11004
11091
|
/** The messages the latest claim or addition took, for choosing which notice to type. */
|
|
11005
|
-
claimedSeqs:
|
|
11092
|
+
claimedSeqs: z27.array(z27.number()).default([]),
|
|
11006
11093
|
/** The investigator looking at a screen herd can't read, from opening to the owner's answer. */
|
|
11007
|
-
investigation:
|
|
11008
|
-
terminal:
|
|
11009
|
-
secret:
|
|
11010
|
-
startedAt:
|
|
11094
|
+
investigation: z27.object({
|
|
11095
|
+
terminal: z27.string(),
|
|
11096
|
+
secret: z27.string(),
|
|
11097
|
+
startedAt: z27.number(),
|
|
11011
11098
|
/** The stuck screen when it opened, saved with the key if the owner approves one. */
|
|
11012
|
-
screen:
|
|
11013
|
-
key:
|
|
11014
|
-
promptId:
|
|
11099
|
+
screen: z27.array(z27.string()),
|
|
11100
|
+
key: z27.string().nullable(),
|
|
11101
|
+
promptId: z27.string().nullable()
|
|
11015
11102
|
}).nullable().default(null),
|
|
11016
11103
|
/** The failed notice an investigator was opened for, so each failure gets one. */
|
|
11017
|
-
investigatedFailure:
|
|
11104
|
+
investigatedFailure: z27.number().nullable().default(null),
|
|
11018
11105
|
/** The agent CLI this conversation's worker runs, as its offer named it. */
|
|
11019
|
-
agent:
|
|
11106
|
+
agent: z27.string().default("claude-code"),
|
|
11020
11107
|
/** Whether what the current claim took needs a reply, which other agents' messages don't. */
|
|
11021
|
-
replyWanted:
|
|
11108
|
+
replyWanted: z27.boolean().default(true),
|
|
11022
11109
|
/** For a delegate: the conversation that started it, which its starting prompt names. */
|
|
11023
|
-
parent:
|
|
11110
|
+
parent: z27.string().nullable().default(null),
|
|
11024
11111
|
/** Codex's session file for this worktree, once found, and how far the daemon has read it. */
|
|
11025
|
-
codexFile:
|
|
11026
|
-
codexOffset:
|
|
11112
|
+
codexFile: z27.string().nullable().default(null),
|
|
11113
|
+
codexOffset: z27.number().default(0),
|
|
11027
11114
|
/** When the agent was last started, so Codex's new session file is told from older ones. */
|
|
11028
|
-
agentStartedAt:
|
|
11115
|
+
agentStartedAt: z27.number().default(0),
|
|
11029
11116
|
/**
|
|
11030
11117
|
* The key the agent was last started with, as `HERD_START`. Its `herd inbox` carrying this key
|
|
11031
11118
|
* is what proves the start works: never a hook, a prompt being taken, or the screen.
|
|
11032
11119
|
*/
|
|
11033
|
-
startKey:
|
|
11120
|
+
startKey: z27.string().nullable().default(null),
|
|
11034
11121
|
/** Whether the current start has checked in. One from before keys counts as proven. */
|
|
11035
|
-
startProven:
|
|
11122
|
+
startProven: z27.boolean().default(true),
|
|
11036
11123
|
/** When the check-in window of an unproven start began, or null once it's proven or for none. */
|
|
11037
|
-
checkInFrom:
|
|
11124
|
+
checkInFrom: z27.number().nullable().default(null),
|
|
11038
11125
|
/** Whether this start has been flagged as needing someone at its terminal, so it's said once. */
|
|
11039
|
-
needsAttention:
|
|
11126
|
+
needsAttention: z27.boolean().default(false),
|
|
11040
11127
|
/** What agy's status line last said its agent was doing, and when. */
|
|
11041
|
-
agentState:
|
|
11042
|
-
agentStateAt:
|
|
11128
|
+
agentState: z27.enum(["working", "idle"]).nullable().default(null),
|
|
11129
|
+
agentStateAt: z27.number().default(0)
|
|
11043
11130
|
});
|
|
11044
|
-
var workspaceSchema =
|
|
11045
|
-
var stateSchema =
|
|
11131
|
+
var workspaceSchema = z27.preprocess(fromBeforeFolders, workspaceFields);
|
|
11132
|
+
var stateSchema = z27.object({ workspaces: z27.record(z27.string(), workspaceSchema) });
|
|
11046
11133
|
|
|
11047
11134
|
// src/workspaces/claims.ts
|
|
11048
11135
|
var holder = (ws, workspace) => `${ws.options.machineName()}/${workspace.lead}`;
|
|
@@ -11123,7 +11210,7 @@ import { join as join29 } from "node:path";
|
|
|
11123
11210
|
|
|
11124
11211
|
// src/commands/repo.ts
|
|
11125
11212
|
init_define_HERD_PACKAGE();
|
|
11126
|
-
import { z as
|
|
11213
|
+
import { z as z28 } from "zod";
|
|
11127
11214
|
var REPO_HELP = `Usage: herd repo <url or owner/name> [folder]
|
|
11128
11215
|
|
|
11129
11216
|
Checks a repo out in this conversation's folder, on a branch named for the conversation, started
|
|
@@ -11137,16 +11224,16 @@ var REPOS_HELP = `Usage: herd repos [--json]
|
|
|
11137
11224
|
|
|
11138
11225
|
Lists the repos in this conversation's folder, the repos checked out in this machine's root, and
|
|
11139
11226
|
the repos your owner's herd.config.ts describes, with what each is for. Add one with herd repo.`;
|
|
11140
|
-
var repoContextSchema =
|
|
11141
|
-
folder:
|
|
11142
|
-
root:
|
|
11143
|
-
branch:
|
|
11144
|
-
legacy:
|
|
11145
|
-
legacyReason:
|
|
11146
|
-
recorded:
|
|
11147
|
-
cloned:
|
|
11148
|
-
described:
|
|
11149
|
-
|
|
11227
|
+
var repoContextSchema = z28.object({
|
|
11228
|
+
folder: z28.string(),
|
|
11229
|
+
root: z28.string(),
|
|
11230
|
+
branch: z28.string(),
|
|
11231
|
+
legacy: z28.boolean(),
|
|
11232
|
+
legacyReason: z28.string().optional(),
|
|
11233
|
+
recorded: z28.array(z28.object({ folder: z28.string(), remote: z28.string(), branch: z28.string() })),
|
|
11234
|
+
cloned: z28.array(z28.object({ key: z28.string(), remote: z28.string() })),
|
|
11235
|
+
described: z28.array(
|
|
11236
|
+
z28.object({ remote: z28.string(), key: z28.string().nullable(), about: z28.string().optional() })
|
|
11150
11237
|
)
|
|
11151
11238
|
});
|
|
11152
11239
|
var isUrl = (text4) => /^[a-z][a-z0-9+.-]*:\/\//i.test(text4) || text4.startsWith("/") || /^[^@/\s]+@[^:/\s]+:/.test(text4);
|
|
@@ -11203,7 +11290,7 @@ async function runRepo(rest) {
|
|
|
11203
11290
|
op: "repo-add",
|
|
11204
11291
|
repoAdd: { asked, ...folderName !== void 0 ? { folder: folderName } : {} }
|
|
11205
11292
|
});
|
|
11206
|
-
const lines =
|
|
11293
|
+
const lines = z28.array(z28.string()).safeParse(reply.lines);
|
|
11207
11294
|
if (!lines.success) throw new HerdError("The daemon's answer about this repo wasn't readable.");
|
|
11208
11295
|
console.log(lines.data.join("\n"));
|
|
11209
11296
|
return 0;
|
|
@@ -12382,21 +12469,21 @@ function resolveAttachments(worktree, files) {
|
|
|
12382
12469
|
// src/workers.ts
|
|
12383
12470
|
init_define_HERD_PACKAGE();
|
|
12384
12471
|
init_src();
|
|
12385
|
-
import { z as
|
|
12386
|
-
var workerListingSchema =
|
|
12387
|
-
workers:
|
|
12388
|
-
machines:
|
|
12389
|
-
|
|
12390
|
-
id:
|
|
12391
|
-
name:
|
|
12392
|
-
online:
|
|
12393
|
-
missing:
|
|
12394
|
-
configError:
|
|
12472
|
+
import { z as z29 } from "zod";
|
|
12473
|
+
var workerListingSchema = z29.object({
|
|
12474
|
+
workers: z29.array(workerSchema),
|
|
12475
|
+
machines: z29.array(
|
|
12476
|
+
z29.object({
|
|
12477
|
+
id: z29.string(),
|
|
12478
|
+
name: z29.string(),
|
|
12479
|
+
online: z29.boolean(),
|
|
12480
|
+
missing: z29.array(z29.string()),
|
|
12481
|
+
configError: z29.string().optional(),
|
|
12395
12482
|
// Servers from before versions were reported send none.
|
|
12396
|
-
herdVersion:
|
|
12483
|
+
herdVersion: z29.string().nullable().optional()
|
|
12397
12484
|
})
|
|
12398
12485
|
),
|
|
12399
|
-
configType:
|
|
12486
|
+
configType: z29.string()
|
|
12400
12487
|
});
|
|
12401
12488
|
async function readWorkers(fetch2) {
|
|
12402
12489
|
const response = await fetch2("/api/workers");
|
|
@@ -12464,20 +12551,20 @@ function formatWorkers(listing, current = null) {
|
|
|
12464
12551
|
);
|
|
12465
12552
|
return lines.join("\n");
|
|
12466
12553
|
}
|
|
12467
|
-
var routingCheckSchema =
|
|
12468
|
-
suits:
|
|
12469
|
-
eligible:
|
|
12470
|
-
removed:
|
|
12471
|
-
questions:
|
|
12472
|
-
|
|
12554
|
+
var routingCheckSchema = z29.object({
|
|
12555
|
+
suits: z29.array(z29.object({ key: z29.string(), name: z29.string() })),
|
|
12556
|
+
eligible: z29.array(z29.object({ key: z29.string(), name: z29.string() })),
|
|
12557
|
+
removed: z29.array(z29.object({ key: z29.string(), name: z29.string(), rule: z29.string() })),
|
|
12558
|
+
questions: z29.array(
|
|
12559
|
+
z29.object({ id: z29.string(), question: z29.string(), probability: z29.number().nullable() })
|
|
12473
12560
|
),
|
|
12474
|
-
fallback:
|
|
12475
|
-
fits:
|
|
12476
|
-
|
|
12477
|
-
key:
|
|
12478
|
-
fit:
|
|
12479
|
-
statement:
|
|
12480
|
-
level:
|
|
12561
|
+
fallback: z29.string().optional(),
|
|
12562
|
+
fits: z29.array(
|
|
12563
|
+
z29.object({
|
|
12564
|
+
key: z29.string(),
|
|
12565
|
+
fit: z29.number(),
|
|
12566
|
+
statement: z29.string().optional(),
|
|
12567
|
+
level: z29.string().optional()
|
|
12481
12568
|
})
|
|
12482
12569
|
).optional()
|
|
12483
12570
|
});
|
|
@@ -13332,8 +13419,8 @@ async function download(ws, workspace, file) {
|
|
|
13332
13419
|
Readable.fromWeb(response.body),
|
|
13333
13420
|
createWriteStream(partial, { flags: "wx" })
|
|
13334
13421
|
);
|
|
13335
|
-
const { size } = statSync10(partial);
|
|
13336
|
-
if (
|
|
13422
|
+
const { size: size2 } = statSync10(partial);
|
|
13423
|
+
if (size2 !== file.size) throw new Error(`it came to ${size2} bytes, not ${file.size}`);
|
|
13337
13424
|
renameSync7(partial, target);
|
|
13338
13425
|
} finally {
|
|
13339
13426
|
rmSync17(partial, { force: true });
|
|
@@ -14598,7 +14685,7 @@ var DETACH_KEY = "";
|
|
|
14598
14685
|
function attach(name, { stdin, stdout } = { stdin: process.stdin, stdout: process.stdout }, path = currentHostSocketPath(), { watch: watch2 = false } = {}) {
|
|
14599
14686
|
return new Promise((resolve8, reject) => {
|
|
14600
14687
|
const socket = connect4(path);
|
|
14601
|
-
const
|
|
14688
|
+
const size2 = () => ({ cols: stdout.columns || 120, rows: stdout.rows || 40 });
|
|
14602
14689
|
let buffer = "";
|
|
14603
14690
|
let started = false;
|
|
14604
14691
|
let ended = false;
|
|
@@ -14623,12 +14710,12 @@ function attach(name, { stdin, stdout } = { stdin: process.stdin, stdout: proces
|
|
|
14623
14710
|
finish("detached");
|
|
14624
14711
|
}
|
|
14625
14712
|
};
|
|
14626
|
-
const onResize = () => socket.write(`${JSON.stringify({ type: "resize", ...
|
|
14713
|
+
const onResize = () => socket.write(`${JSON.stringify({ type: "resize", ...size2() })}
|
|
14627
14714
|
`);
|
|
14628
14715
|
socket.on(
|
|
14629
14716
|
"connect",
|
|
14630
14717
|
() => socket.write(
|
|
14631
|
-
`${JSON.stringify(watch2 ? { op: "watch", name } : { op: "attach", name, ...
|
|
14718
|
+
`${JSON.stringify(watch2 ? { op: "watch", name } : { op: "attach", name, ...size2() })}
|
|
14632
14719
|
`
|
|
14633
14720
|
)
|
|
14634
14721
|
);
|
|
@@ -14901,7 +14988,7 @@ async function runWatch(command, rest) {
|
|
|
14901
14988
|
// src/commands/work.ts
|
|
14902
14989
|
init_define_HERD_PACKAGE();
|
|
14903
14990
|
init_src();
|
|
14904
|
-
import { z as
|
|
14991
|
+
import { z as z35 } from "zod";
|
|
14905
14992
|
var WORK_HELP = `Usage: herd work <url> [--kind <kind>] [--title "<title>"] [--status <status>]
|
|
14906
14993
|
[--detail "<detail>"] [--made] [--phase <phase>]
|
|
14907
14994
|
herd work --remove <url>
|
|
@@ -14993,9 +15080,9 @@ ${WORK_HELP}`
|
|
|
14993
15080
|
};
|
|
14994
15081
|
return { kind: "record", change, json };
|
|
14995
15082
|
}
|
|
14996
|
-
var followSchema =
|
|
14997
|
-
|
|
14998
|
-
|
|
15083
|
+
var followSchema = z35.union([
|
|
15084
|
+
z35.object({ following: z35.literal(true) }),
|
|
15085
|
+
z35.object({ following: z35.literal(false), reason: z35.string() })
|
|
14999
15086
|
]);
|
|
15000
15087
|
function formatFollow(follow) {
|
|
15001
15088
|
return follow.following ? "Following it: its reviews, CI and merge will reach herd inbox." : `Not followed: ${follow.reason}`;
|
|
@@ -15011,7 +15098,7 @@ function formatWork(work, own) {
|
|
|
15011
15098
|
return ` ${parts.join(" \xB7 ")}${work.made ? " made here" : ""}
|
|
15012
15099
|
${work.url}${whose}`;
|
|
15013
15100
|
}
|
|
15014
|
-
var listSchema =
|
|
15101
|
+
var listSchema = z35.array(workObjectSchema);
|
|
15015
15102
|
async function runWork(rest) {
|
|
15016
15103
|
const parsed = parseWork(rest);
|
|
15017
15104
|
if (parsed.kind === "help") {
|