@celsoft/coordinator 0.0.0 → 0.1.0
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/CHANGELOG.md +11 -0
- package/README.md +107 -0
- package/THIRD_PARTY_NOTICES.md +2005 -0
- package/agents/console.md +20 -0
- package/agents/free.md +110 -0
- package/build/0-JP6XL6LB.js +17 -0
- package/build/1-A52YZWNS.js +17 -0
- package/build/2-CLH2NM6F.js +32 -0
- package/build/3-4N467IB6.js +45 -0
- package/build/4-WL5H4LUW.js +29 -0
- package/build/_layout.svelte-KPUSX7LQ.js +27 -0
- package/build/_page.svelte-22H56UR6.js +7972 -0
- package/build/_page.svelte-CVWUNRQC.js +135 -0
- package/build/_page.svelte-LTZXBHMT.js +57 -0
- package/build/_server.ts-3KVBYN6P.js +20 -0
- package/build/_server.ts-3POPKVEM.js +47 -0
- package/build/_server.ts-5735T2V5.js +31 -0
- package/build/_server.ts-5VXGNWV2.js +38 -0
- package/build/_server.ts-645KP7WP.js +42 -0
- package/build/_server.ts-A3AA24Z2.js +28 -0
- package/build/_server.ts-CITUOEM6.js +58 -0
- package/build/_server.ts-I7HMTPOA.js +25 -0
- package/build/_server.ts-M5BQ4LLX.js +30 -0
- package/build/_server.ts-OB4O27HF.js +683 -0
- package/build/_server.ts-OJT7HE7M.js +15 -0
- package/build/_server.ts-OYGWVLZM.js +12 -0
- package/build/_server.ts-T75UVMQP.js +38 -0
- package/build/_server.ts-WYZYNHUZ.js +28 -0
- package/build/_server.ts-Z26EB47B.js +486 -0
- package/build/chunk-4CIG53L5.js +33 -0
- package/build/chunk-BJTJS3XY.js +338 -0
- package/build/chunk-F2CNWJZM.js +14 -0
- package/build/chunk-HGYE3UTU.js +416 -0
- package/build/chunk-KAYW2W7H.js +1311 -0
- package/build/chunk-LFP3UPCM.js +10 -0
- package/build/chunk-M44JEFEH.js +62 -0
- package/build/chunk-MC5AGLMY.js +39 -0
- package/build/chunk-NCZ77J5E.js +19798 -0
- package/build/chunk-NVNLDPUJ.js +2122 -0
- package/build/chunk-PDCON4KS.js +494 -0
- package/build/chunk-Q4OQNY5M.js +25 -0
- package/build/chunk-QCUOR2U5.js +75 -0
- package/build/chunk-R6RYZZWA.js +46 -0
- package/build/chunk-SOJTASZC.js +51 -0
- package/build/chunk-SU26PJVX.js +410 -0
- package/build/chunk-U5BSBG4R.js +506 -0
- package/build/chunk-UEKOZGRO.js +37 -0
- package/build/chunk-W6EFUWJ2.js +9 -0
- package/build/chunk-WOPREK6Q.js +117 -0
- package/build/chunk-WWJ3F4QS.js +127 -0
- package/build/chunk-ZGZJEEE3.js +1091 -0
- package/build/client/_app/immutable/assets/0.BGa5ZNDM.css +1 -0
- package/build/client/_app/immutable/chunks/BUrrLYDt.js +2 -0
- package/build/client/_app/immutable/chunks/BgFr_EyZ.js +4 -0
- package/build/client/_app/immutable/chunks/Bjy-W4x2.js +82 -0
- package/build/client/_app/immutable/chunks/C8qZab0y.js +56 -0
- package/build/client/_app/immutable/chunks/C90fLsA5.js +4 -0
- package/build/client/_app/immutable/chunks/CRzLMJPS.js +1 -0
- package/build/client/_app/immutable/chunks/DLT1iIlz.js +2 -0
- package/build/client/_app/immutable/chunks/pIrVVOVY.js +2 -0
- package/build/client/_app/immutable/entry/app.0DERehLW.js +3 -0
- package/build/client/_app/immutable/entry/payload.DSmR2FwN.js +2 -0
- package/build/client/_app/immutable/entry/start.B7srFiqh.js +3 -0
- package/build/client/_app/immutable/nodes/0.aD9vJoxR.js +2 -0
- package/build/client/_app/immutable/nodes/1.Br4FL91i.js +2 -0
- package/build/client/_app/immutable/nodes/2.vl6OYfu3.js +8 -0
- package/build/client/_app/immutable/nodes/3.VYqJOLAF.js +2 -0
- package/build/client/_app/immutable/nodes/4.jF9UVlFN.js +2 -0
- package/build/client/_app/version.json +1 -0
- package/build/client/apple-touch-icon.png +0 -0
- package/build/client/favicon.ico +0 -0
- package/build/client/favicon.svg +48 -0
- package/build/client/icon-192.png +0 -0
- package/build/client/icon-512.png +0 -0
- package/build/client/icon-maskable-512.png +0 -0
- package/build/client/icon.svg +44 -0
- package/build/client/manifest.webmanifest +15 -0
- package/build/error.svelte-JXZDY65F.js +51 -0
- package/build/handler.js +716 -0
- package/build/hooks.server-34IMHRKC.js +43 -0
- package/build/instance-NP3FJIWW.js +2967 -0
- package/client/client.mjs +28 -0
- package/client/hooks.mjs +7 -0
- package/client/register.mjs +5 -0
- package/dist/cli.js +62826 -0
- package/dist/port.js +36691 -0
- package/package.json +20 -1
- package/skills/agents/.claude-plugin/plugin.json +5 -0
- package/skills/agents/hooks/hooks.json +1 -0
- package/skills/agents/hooks/register.ts +57 -0
- package/skills/agents/skills/bus-work/SKILL.md +66 -0
- package/skills/agents/skills/plan/SKILL.md +98 -0
- package/skills/console/.claude-plugin/plugin.json +5 -0
- package/skills/console/hooks/hooks.json +1 -0
- package/skills/console/hooks/register.ts +10 -0
- package/skills/console/skills/bus/SKILL.md +61 -0
- package/skills/default/.claude-plugin/plugin.json +5 -0
- package/skills/default/skills/git-workflow/SKILL.md +294 -0
- package/skills/default/skills/git-workflow/mise-tasks/_lib.sh +107 -0
- package/skills/default/skills/git-workflow/mise-tasks/clone +36 -0
- package/skills/default/skills/git-workflow/mise-tasks/repo-list +8 -0
- package/skills/default/skills/git-workflow/mise-tasks/unpushed +26 -0
- package/skills/default/skills/git-workflow/mise-tasks/worktree-add +60 -0
- package/skills/default/skills/github/SKILL.md +208 -0
- package/skills/default/skills/github/scripts/gh-org +196 -0
- package/skills/default/skills/plan-page/SKILL.md +300 -0
- package/skills/default/skills/plan-page/assets/index.html +854 -0
- package/skills/default/skills/plan-page/scripts/inline +46 -0
- package/skills/default/skills/plan-page/scripts/stage +26 -0
- package/skills/default/skills/secrets/SKILL.md +134 -0
- package/skills/default/skills/secrets/scripts/secrets-check +87 -0
- package/skills/default/skills/writing-style/SKILL.md +45 -0
- package/skills/extra/.claude-plugin/plugin.json +5 -0
- package/skills/extra/skills/artifacts/SKILL.md +52 -0
- package/skills/extra/skills/github-actions/SKILL.md +78 -0
- package/skills/extra/skills/github-actions/scan +32 -0
- package/skills/extra/skills/markdown-review/SKILL.md +70 -0
- package/skills/extra/skills/markdown-review/assets/index.html +201 -0
- package/skills/extra/skills/markdown-review/scripts/stage +36 -0
- package/skills/extra/skills/mise-usage/SKILL.md +155 -0
- package/skills/extra/skills/plugin-authoring/SKILL.md +317 -0
- package/skills/extra/skills/project-conventions/SKILL.md +64 -0
- package/skills/extra/skills/questions/SKILL.md +156 -0
- package/skills/extra/skills/questions/assets/index.html +376 -0
- package/skills/extra/skills/questions/scripts/stage +26 -0
- package/skills/extra/skills/serve/SKILL.md +165 -0
- package/skills/extra/skills/serve/scripts/serve +268 -0
- package/skills/extra/skills/serve/scripts/server.py +345 -0
- package/skills/extra/skills/skill-dependencies/SKILL.md +65 -0
- package/skills/extra/skills/skill-maintenance/SKILL.md +101 -0
- package/skills/extra/skills/ticketing/SKILL.md +125 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
describe
|
|
4
|
+
} from "./chunk-UEKOZGRO.js";
|
|
5
|
+
import {
|
|
6
|
+
StageName
|
|
7
|
+
} from "./chunk-4CIG53L5.js";
|
|
8
|
+
import {
|
|
9
|
+
AskKind,
|
|
10
|
+
CONSOLE,
|
|
11
|
+
IssueMove,
|
|
12
|
+
IssueState,
|
|
13
|
+
IssueType,
|
|
14
|
+
Leash,
|
|
15
|
+
USER,
|
|
16
|
+
addressOfIssue,
|
|
17
|
+
cmp,
|
|
18
|
+
followersOf,
|
|
19
|
+
get,
|
|
20
|
+
isLive,
|
|
21
|
+
issueOrder,
|
|
22
|
+
latestPerSlot,
|
|
23
|
+
openAsk,
|
|
24
|
+
slotOf,
|
|
25
|
+
unfinishedFollowers,
|
|
26
|
+
waitingOn
|
|
27
|
+
} from "./chunk-PDCON4KS.js";
|
|
28
|
+
import {
|
|
29
|
+
json
|
|
30
|
+
} from "./chunk-SU26PJVX.js";
|
|
31
|
+
import {
|
|
32
|
+
CommitEmail,
|
|
33
|
+
CommitName,
|
|
34
|
+
GitHubName,
|
|
35
|
+
SshKey
|
|
36
|
+
} from "./chunk-Q4OQNY5M.js";
|
|
37
|
+
import {
|
|
38
|
+
SecretName
|
|
39
|
+
} from "./chunk-SOJTASZC.js";
|
|
40
|
+
import "./chunk-WOPREK6Q.js";
|
|
41
|
+
import {
|
|
42
|
+
DocName,
|
|
43
|
+
docAddress,
|
|
44
|
+
docOfPath,
|
|
45
|
+
docPath
|
|
46
|
+
} from "./chunk-MC5AGLMY.js";
|
|
47
|
+
import {
|
|
48
|
+
Branch,
|
|
49
|
+
EditableKind,
|
|
50
|
+
PartName,
|
|
51
|
+
RepoSettingsChange,
|
|
52
|
+
Slot,
|
|
53
|
+
Track,
|
|
54
|
+
WRITING_RULE,
|
|
55
|
+
isSlot
|
|
56
|
+
} from "./chunk-HGYE3UTU.js";
|
|
57
|
+
import {
|
|
58
|
+
Commit,
|
|
59
|
+
FollowerRepos,
|
|
60
|
+
IssueAddress,
|
|
61
|
+
IssueLink,
|
|
62
|
+
IssueTitle,
|
|
63
|
+
Link,
|
|
64
|
+
Repo,
|
|
65
|
+
Slug,
|
|
66
|
+
external_exports,
|
|
67
|
+
oneLine
|
|
68
|
+
} from "./chunk-NCZ77J5E.js";
|
|
69
|
+
import "./chunk-LFP3UPCM.js";
|
|
70
|
+
|
|
71
|
+
// node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/stringify.js
|
|
72
|
+
var HAS_WELLFORMED = !!"".isWellFormed;
|
|
73
|
+
|
|
74
|
+
// build/server/entries/endpoints/state.json/_server.ts.js
|
|
75
|
+
var VersionSchema = external_exports.object({
|
|
76
|
+
n: external_exports.number().int().positive(),
|
|
77
|
+
by: external_exports.string(),
|
|
78
|
+
at: external_exports.string()
|
|
79
|
+
});
|
|
80
|
+
external_exports.object({
|
|
81
|
+
format: external_exports.number().int().max(1, "a document record newer than this coordinator"),
|
|
82
|
+
issue: external_exports.string(),
|
|
83
|
+
name: external_exports.string(),
|
|
84
|
+
title: external_exports.string(),
|
|
85
|
+
by: external_exports.string(),
|
|
86
|
+
key: external_exports.string(),
|
|
87
|
+
created_at: external_exports.string(),
|
|
88
|
+
versions: external_exports.array(VersionSchema).min(1)
|
|
89
|
+
});
|
|
90
|
+
var latest = (record) => record.versions.at(-1).n;
|
|
91
|
+
var updatedAt = (record) => record.versions.at(-1).at;
|
|
92
|
+
var text$1 = (description) => external_exports.string().min(1).describe(description);
|
|
93
|
+
var Recipient = external_exports.string().transform((value) => value === "sean" ? USER : value).refine((value) => value === "user" || isSlot(value), { error: (i) => `'${String(i.input)}' is not a slot, org/repo@track` });
|
|
94
|
+
var repoField = (description) => Repo.describe(description);
|
|
95
|
+
var issueField = (description = "the issue, org/repo#slug") => IssueAddress.describe(description);
|
|
96
|
+
var SendBody = external_exports.strictObject({
|
|
97
|
+
to: Recipient.describe("a slot, org/repo@track, or user"),
|
|
98
|
+
text: text$1("the message"),
|
|
99
|
+
about: issueField("the issue it concerns, org/repo#slug").optional()
|
|
100
|
+
});
|
|
101
|
+
var existingField = external_exports.boolean().describe("when a follower repo's slot on the track already exists, or a worktree is at its place, make it the follower; left out, such a follower refuses the whole request");
|
|
102
|
+
var StartBody = external_exports.strictObject({
|
|
103
|
+
type: text$1("an Agent Type's name"),
|
|
104
|
+
track: Track.describe("the track it goes down, a valid git branch name (it names its tab and branch); agents in several repos share a track by naming the same one, and slashes group tracks, as in web/login"),
|
|
105
|
+
task: text$1("everything the agent needs to do its work"),
|
|
106
|
+
repo: repoField("the repo to start it in, as org/repo from the catalog's repos; default is your own").optional(),
|
|
107
|
+
profile: PartName.describe("a profile to give it on top of its repo's: its skills are added, and its handlers follow the repo's at each event").optional(),
|
|
108
|
+
leash: Leash.describe("gated (the default): it asks the user before building and before landing; free: it asks neither").optional(),
|
|
109
|
+
keep_open: external_exports.boolean().describe("keep it running after its work lands; default false, so the bus ends it").optional(),
|
|
110
|
+
issue: issueField("an issue of the repo for it to hold: the bus gives it to the new slot before starting, or holding, the agent, refuses the start if it cannot, and tells the agent in its task").optional(),
|
|
111
|
+
also: external_exports.array(IssueAddress).describe("other issues of the repo, related to issue, for it to hold and work in the same branch; each is given to the slot with issue, or the start is refused whole; none may name follower repos").optional(),
|
|
112
|
+
existing: existingField.optional()
|
|
113
|
+
});
|
|
114
|
+
var AskBody = external_exports.strictObject({
|
|
115
|
+
kind: AskKind.describe("plan: your approach, before building; done: your finished work, before landing; pr: a pr you are about to send; question: a decision"),
|
|
116
|
+
text: oneLine("An ask", 300).describe("what you ask, in one line of at most 300 characters, as the user will see it on their page and console"),
|
|
117
|
+
about: issueField("the issue it concerns, org/repo#slug").optional()
|
|
118
|
+
});
|
|
119
|
+
var LeashBody = external_exports.strictObject({
|
|
120
|
+
to: Slot.describe("the slot whose leash changes"),
|
|
121
|
+
leash: Leash.describe("gated or free").optional(),
|
|
122
|
+
keep_open: external_exports.boolean().describe("keep its agent running after its work lands").optional()
|
|
123
|
+
});
|
|
124
|
+
var LeadBody = external_exports.strictObject({
|
|
125
|
+
to: Slot.describe("the slot that follows"),
|
|
126
|
+
lead: Slot.describe("the slot that leads it; leave it out to clear its lead").optional()
|
|
127
|
+
});
|
|
128
|
+
var FollowerBody = external_exports.strictObject({
|
|
129
|
+
lead: Slot.describe("the slot that leads it: your own, unless you are user"),
|
|
130
|
+
repo: repoField("the follower repo, org/repo: its slot on the lead's track follows the lead"),
|
|
131
|
+
type: text$1("the Agent Type for a new agent there; default free").optional(),
|
|
132
|
+
task: text$1("what the follower is for, given to a new agent there; the bus adds that it follows the lead and introduces itself").optional(),
|
|
133
|
+
existing: existingField.optional()
|
|
134
|
+
});
|
|
135
|
+
var FollowerAnswerBody = external_exports.strictObject({
|
|
136
|
+
request: external_exports.number().int().min(1).describe("the follower request's id"),
|
|
137
|
+
approve: external_exports.boolean().describe("true runs it as if user sent it; false declines it"),
|
|
138
|
+
note: text$1("why, told to the lead").optional()
|
|
139
|
+
});
|
|
140
|
+
var IssueFollowersBody = external_exports.strictObject({
|
|
141
|
+
issue: IssueAddress.describe("the issue, org/repo#slug"),
|
|
142
|
+
repos: FollowerRepos.describe("the issue's follower repos, org/repo each, replacing the list; empty clears it")
|
|
143
|
+
});
|
|
144
|
+
var LandedBody = external_exports.strictObject({
|
|
145
|
+
commit: Commit.describe("the commit the work landed as, on the repo's default branch: its hash, short or full; the bus links it; leave it out when there was nothing to push").optional(),
|
|
146
|
+
note: text$1("what was done, in a line or two").optional(),
|
|
147
|
+
about: issueField("the issue the work was for, which this closes").optional()
|
|
148
|
+
});
|
|
149
|
+
var LandBody = external_exports.strictObject({
|
|
150
|
+
title: oneLine("A title", 200).describe("the work in one line of at most 200 characters: the PR's title, or what the push to the default branch carries"),
|
|
151
|
+
summary: oneLine("A summary", 300).describe("the change in one plain sentence of at most 300 characters, the line the repo's history shows under the title; required unless no_code").optional(),
|
|
152
|
+
built: external_exports.string().trim().min(1).max(4e3).describe("what was built, in a few plain lines, as the repo's history keeps it for this landing; required unless no_code").optional(),
|
|
153
|
+
challenges: external_exports.string().max(4e3).describe("what was hard along the way, in a few plain lines: dead ends, surprises, and above all any change a rebase forced on how something works; empty when nothing was").optional(),
|
|
154
|
+
body: external_exports.string().describe("the PR's description; left out, it is made from summary, built, and challenges").optional(),
|
|
155
|
+
about: issueField("the issue the work is for, which landing closes when end is set").optional(),
|
|
156
|
+
end: external_exports.boolean().describe("this is your last landing: close the issue in about and end you once you rest; leave it out to keep working").optional(),
|
|
157
|
+
also: external_exports.array(IssueAddress).describe("other issues you hold that this work finishes, closed with about when end is set").optional(),
|
|
158
|
+
no_code: external_exports.boolean().describe("your work has nothing to push: the bus checks your branch has no commits to land, pushes nothing, and finishes it as a landing with title as its note").optional()
|
|
159
|
+
}).superRefine((b, ctx) => {
|
|
160
|
+
if (b.no_code) return;
|
|
161
|
+
for (const field of ["summary", "built"]) if (!b[field]) ctx.addIssue({
|
|
162
|
+
code: "custom",
|
|
163
|
+
path: [field],
|
|
164
|
+
message: `${field} is required on a land with code: the repo's history keeps it for this landing`
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
var ChangesBody = external_exports.strictObject({
|
|
168
|
+
repo: repoField("the repo, org/repo, one the bus keeps"),
|
|
169
|
+
before: external_exports.number().int().min(1).describe("only those older than this id, for the page after one already read").optional(),
|
|
170
|
+
from: external_exports.string().trim().min(1).max(200).describe("with to, a commit or tag: only the landings whose commits are in from..to, oldest first, all at once").optional(),
|
|
171
|
+
to: external_exports.string().trim().min(1).max(200).describe("with from, a commit, tag, or branch; the default branch on origin when only from is given").optional()
|
|
172
|
+
});
|
|
173
|
+
var PushBody = external_exports.strictObject({});
|
|
174
|
+
var PrBody = external_exports.strictObject({
|
|
175
|
+
repo: repoField("the repo the PR is in, org/repo, one the bus keeps; default is your own").optional(),
|
|
176
|
+
head: Branch.describe("the branch the PR is from, a local branch of that repo's clone (any of its worktrees); the bus pushes it first"),
|
|
177
|
+
base: Branch.describe("the branch the PR goes into, on origin"),
|
|
178
|
+
title: oneLine("A title", 200).describe("the PR's title, in one line of at most 200 characters"),
|
|
179
|
+
body: external_exports.string().describe("the PR's description").optional(),
|
|
180
|
+
about: issueField("the issue the work is for; the PR is commented on it, and it is never closed by this").optional()
|
|
181
|
+
});
|
|
182
|
+
var PrCloseBody = external_exports.strictObject({
|
|
183
|
+
repo: repoField("the repo the PR is in, org/repo; default is your own").optional(),
|
|
184
|
+
number: external_exports.number().int().min(1).describe("the Work PR's number, as pr answered")
|
|
185
|
+
});
|
|
186
|
+
var GitHubBody = external_exports.strictObject({
|
|
187
|
+
what: external_exports.enum(["pr"]).describe("what to read: pr (its state, checks, mergeability, reviews, and comments)"),
|
|
188
|
+
number: external_exports.number().int().min(1).describe("the PR's number in your repo; default is your open PR").optional()
|
|
189
|
+
});
|
|
190
|
+
var RepoSettingsBody = external_exports.strictObject({
|
|
191
|
+
repo: repoField("the repo, org/repo"),
|
|
192
|
+
settings: RepoSettingsChange.describe("the settings to change, by name, each checked by its own rule; null clears one back to none chosen")
|
|
193
|
+
});
|
|
194
|
+
var StopBody = external_exports.strictObject({ to: Slot.describe("the slot of the agent to stop") });
|
|
195
|
+
var ResumeBody = external_exports.strictObject({ to: Slot.describe("the slot to bring back up") });
|
|
196
|
+
var AdoptBody = external_exports.strictObject({
|
|
197
|
+
type: text$1("the Agent Type that drives the slot once it is brought up"),
|
|
198
|
+
track: Track.describe("the track: the branch the worktree has checked out"),
|
|
199
|
+
repo: repoField("the repo, as org/repo from the catalog's repos"),
|
|
200
|
+
task: text$1("what the slot is for, given to its agent when it is brought up")
|
|
201
|
+
});
|
|
202
|
+
var IssueOpenBody = external_exports.strictObject({
|
|
203
|
+
slug: Slug.describe("a short name unique in its repo, such as fix-login"),
|
|
204
|
+
title: IssueTitle.describe("what it is, in one line of at most 120 characters"),
|
|
205
|
+
type: IssueType.describe("bug, feature, task, or chore; default task").optional(),
|
|
206
|
+
description: external_exports.string().default("").describe("the details"),
|
|
207
|
+
repo: repoField("the repo it is for, org/repo; default is your own").optional(),
|
|
208
|
+
holder: Slot.describe("a slot of that repo to hold it at once: your own, to come back to later, or one you work with").optional(),
|
|
209
|
+
blocked_by: external_exports.array(IssueAddress).describe("issues in any repo it waits on: it is blocked until each has landed").optional(),
|
|
210
|
+
links: external_exports.array(IssueLink).describe("links to its work outside the bus, such as its ticket").optional()
|
|
211
|
+
});
|
|
212
|
+
var IssueBody = external_exports.strictObject({ issue: issueField() });
|
|
213
|
+
var IssueAssignBody = external_exports.strictObject({
|
|
214
|
+
issue: issueField(),
|
|
215
|
+
to: Slot.describe("the slot of the issue's repo to hold it"),
|
|
216
|
+
existing: existingField.optional()
|
|
217
|
+
});
|
|
218
|
+
var IssueAskBody = external_exports.strictObject({
|
|
219
|
+
issue: issueField(),
|
|
220
|
+
reason: text$1("why you need it")
|
|
221
|
+
});
|
|
222
|
+
var IssueKeepBody = external_exports.strictObject({
|
|
223
|
+
issue: issueField(),
|
|
224
|
+
reason: text$1("why you are keeping it")
|
|
225
|
+
});
|
|
226
|
+
var IssueBlockBody = external_exports.strictObject({
|
|
227
|
+
issue: issueField(),
|
|
228
|
+
on: issueField("the issue it waits on, in any repo, org/repo#slug")
|
|
229
|
+
});
|
|
230
|
+
var IssueUnblockBody = external_exports.strictObject({
|
|
231
|
+
issue: issueField(),
|
|
232
|
+
on: issueField("the issue it should stop waiting on, org/repo#slug")
|
|
233
|
+
});
|
|
234
|
+
var IssueCommentBody = external_exports.strictObject({
|
|
235
|
+
issue: issueField(),
|
|
236
|
+
text: text$1("the comment")
|
|
237
|
+
});
|
|
238
|
+
var IssueLinkBody = external_exports.strictObject({
|
|
239
|
+
issue: issueField(),
|
|
240
|
+
...IssueLink.shape,
|
|
241
|
+
remove: external_exports.boolean().describe("true to take the link with this url away").optional()
|
|
242
|
+
});
|
|
243
|
+
var PlanLink = external_exports.string().refine((v) => Link.safeParse(v).success || /^(https?:\/\/[^/]+)?\//.test(v) && !!docOfPath(v), { error: "A link is an https URL, or a document link from doc_publish." });
|
|
244
|
+
var IssuePlanBody = external_exports.strictObject({
|
|
245
|
+
issue: issueField(),
|
|
246
|
+
link: PlanLink.describe("the plan's page: the link doc_publish answered, or an https URL; a new link adds a plan, a known one updates it"),
|
|
247
|
+
name: oneLine("A plan name", 60).describe("what this plan covers, any name that suits the work, such as Phase 2: the page; Plan when left out").optional(),
|
|
248
|
+
approved: external_exports.boolean().describe("true once the user has approved this plan; the bus is the record of approval").optional(),
|
|
249
|
+
replaces: PlanLink.describe("the link of a plan already on the issue that this link takes the place of, keeping its name and approval, such as a plan moved to a document").optional()
|
|
250
|
+
});
|
|
251
|
+
var IssuePlanDeleteBody = external_exports.strictObject({
|
|
252
|
+
issue: issueField(),
|
|
253
|
+
link: PlanLink.describe("the link of the plan to delete, as issue_plan recorded it or doc_publish answered it")
|
|
254
|
+
});
|
|
255
|
+
var DocPublishBody = external_exports.strictObject({
|
|
256
|
+
issue: issueField("the issue it belongs to, org/repo#slug, of your own repo"),
|
|
257
|
+
name: DocName.describe("its name in the issue, a slug such as store-design; a new name makes a document, a known one replaces its newest version until the issue lands, then adds the next"),
|
|
258
|
+
title: oneLine("A title", 120).describe("its title, as the issue and its page show it"),
|
|
259
|
+
path: text$1("the page to publish: an HTML file, or a folder with an index.html and the files it loads (plan.json, mockups, images), at most 64MB")
|
|
260
|
+
});
|
|
261
|
+
var IssueCloseBody = external_exports.strictObject({
|
|
262
|
+
issue: issueField(),
|
|
263
|
+
note: text$1("what was done, or why it is closed")
|
|
264
|
+
});
|
|
265
|
+
var IssuesBody = external_exports.strictObject({
|
|
266
|
+
repo: repoField("only this repo, org/repo").optional(),
|
|
267
|
+
state: IssueState.describe("open (no slot holds it), held (a slot holds it), or closed").optional(),
|
|
268
|
+
holder: Slot.describe("only issues this slot holds").optional()
|
|
269
|
+
});
|
|
270
|
+
var IssueTakeBody = external_exports.strictObject({ issue: issueField("the issue, org/repo#slug; leave it out to take the first free open issue in your repo's order").optional() });
|
|
271
|
+
var IssueMoveBody = external_exports.strictObject({
|
|
272
|
+
issue: issueField(),
|
|
273
|
+
to: IssueMove.describe("top, up, or down in its repo's order of open issues")
|
|
274
|
+
});
|
|
275
|
+
var IssueHandOverBody = IssueBody;
|
|
276
|
+
var IssueReleaseBody = IssueBody;
|
|
277
|
+
var BADGE_TONES = [
|
|
278
|
+
"neutral",
|
|
279
|
+
"info",
|
|
280
|
+
"success",
|
|
281
|
+
"warning",
|
|
282
|
+
"danger"
|
|
283
|
+
];
|
|
284
|
+
var SlotBody = external_exports.strictObject({ slot: Slot.describe("the slot, org/repo@track") });
|
|
285
|
+
var SlotPropertyBody = external_exports.strictObject({
|
|
286
|
+
slot: Slot.describe("the slot, org/repo@track"),
|
|
287
|
+
name: oneLine("A name", 40).describe("its name, shown as its key; setting it again replaces it"),
|
|
288
|
+
value: oneLine("A value", 200).describe("its value; leave it out to clear the property").optional(),
|
|
289
|
+
link: Link.describe("an https URL its value opens").optional()
|
|
290
|
+
});
|
|
291
|
+
var SlotBadgeBody = external_exports.strictObject({
|
|
292
|
+
slot: Slot.describe("the slot, org/repo@track"),
|
|
293
|
+
name: oneLine("A name", 40).describe("its key, never shown; setting it again replaces the badge in place"),
|
|
294
|
+
label: oneLine("A label", 40).describe("the words it shows; leave it out to clear the badge").optional(),
|
|
295
|
+
tone: external_exports.enum(BADGE_TONES).default("neutral").describe("its color: neutral, info, success, warning, or danger")
|
|
296
|
+
});
|
|
297
|
+
var SlotsBody = external_exports.strictObject({
|
|
298
|
+
track: Track.describe("only slots on this track").optional(),
|
|
299
|
+
repo: repoField("only slots of this repo, org/repo").optional(),
|
|
300
|
+
live: external_exports.boolean().describe("only slots with an agent running").optional()
|
|
301
|
+
});
|
|
302
|
+
var ReposBody = external_exports.strictObject({
|
|
303
|
+
repo: repoField("one repo, org/repo: its branches and worktrees, each joined to its slot, agent, and issues").optional(),
|
|
304
|
+
fresh: external_exports.boolean().describe("read git again now, and the default branch, rather than what was read in the last few seconds").optional()
|
|
305
|
+
});
|
|
306
|
+
var RepoAddBody = external_exports.strictObject({ repo: text$1("org/repo, or any GitHub URL to the repo or a page in it") });
|
|
307
|
+
var SecretKeyBody = external_exports.strictObject({
|
|
308
|
+
name: SecretName.describe("the secret's name, an environment variable's: capitals, digits, and underscores, such as STRIPE_KEY"),
|
|
309
|
+
repo: repoField("the repo whose .env.secrets gets it, org/repo; default is your own").optional(),
|
|
310
|
+
slot: external_exports.boolean().describe("true to add it to your own slot's .env.secrets instead, for this track's work only").optional(),
|
|
311
|
+
about: issueField("the issue it is for, org/repo#slug").optional()
|
|
312
|
+
});
|
|
313
|
+
var RepoForgetBody = external_exports.strictObject({ repo: repoField("the repo to stop keeping, org/repo") });
|
|
314
|
+
var partKind = EditableKind.describe("profile (what agents get, kept in a Repo) or attachment (a folder of skills)");
|
|
315
|
+
var ProfileSaveBody = external_exports.strictObject({
|
|
316
|
+
kind: partKind,
|
|
317
|
+
name: PartName.describe("its name, lowercase words joined by hyphens; a new name creates it"),
|
|
318
|
+
repo: repoField("for a new profile, the kept repo to keep it in, org/repo").optional(),
|
|
319
|
+
seen: external_exports.string().describe("the profile's hash as you read it, so a change over a newer version is refused").optional(),
|
|
320
|
+
change: external_exports.record(external_exports.string(), external_exports.unknown()).describe('the fields to set: for a profile description, skills (per skill group, "all" or a list of its skill names), on_for (org/repo, org/*, or *), handlers (each {name, event, text, every?}), and actions (each {name, label, view: repo, slot, or issue, task, description?}); for an attachment description and path. ' + WRITING_RULE)
|
|
321
|
+
});
|
|
322
|
+
var ProfileDeleteBody = external_exports.strictObject({
|
|
323
|
+
kind: partKind,
|
|
324
|
+
name: PartName.describe("its name")
|
|
325
|
+
});
|
|
326
|
+
var ProfilesMoveBody = external_exports.strictObject({ repo: repoField("the kept repo to keep them in, org/repo") });
|
|
327
|
+
var ProfilesBody = external_exports.strictObject({});
|
|
328
|
+
var FoldersBody = external_exports.strictObject({ path: external_exports.string().trim().min(1).describe("a folder under ~, written from ~, such as ~/Development") });
|
|
329
|
+
var LoginSetBody = external_exports.strictObject({
|
|
330
|
+
login: GitHubName.describe("the GitHub login, one gh is signed in as"),
|
|
331
|
+
ssh_key: SshKey.describe("its private SSH key, ~/.ssh/...; none or null to make a new one").optional(),
|
|
332
|
+
name: CommitName.describe("the name its commits carry"),
|
|
333
|
+
email: CommitEmail.describe("the email its commits carry"),
|
|
334
|
+
orgs: external_exports.array(GitHubName).describe("the orgs whose kept repos commit and push as it; an org on another login moves here").optional()
|
|
335
|
+
});
|
|
336
|
+
var LoginRemoveBody = external_exports.strictObject({ login: GitHubName.describe("the login to stop keeping") });
|
|
337
|
+
var OrgLoginBody = external_exports.strictObject({
|
|
338
|
+
org: GitHubName.describe("the org"),
|
|
339
|
+
login: GitHubName.describe("a login the bus keeps, for its repos")
|
|
340
|
+
});
|
|
341
|
+
var GitHubSignInBody = external_exports.strictObject({ action: external_exports.enum(["start", "cancel"]).describe("start gh's web sign-in, or cancel it") });
|
|
342
|
+
var HistoryBody = external_exports.strictObject({
|
|
343
|
+
with: Recipient.describe("only Messages to or from this slot, or user").optional(),
|
|
344
|
+
about: issueField("only Messages about this issue, org/repo#slug").optional(),
|
|
345
|
+
unread: external_exports.boolean().describe("only Messages not yet read").optional(),
|
|
346
|
+
limit: external_exports.number().int().min(1).max(100).default(20).describe("how many, the latest; default 20")
|
|
347
|
+
});
|
|
348
|
+
var StatusBody = external_exports.strictObject({
|
|
349
|
+
stage: StageName.describe("a registered stage, from the catalog or stages; never a gated one"),
|
|
350
|
+
text: oneLine("A status", 160).describe("what you are doing now, in a few words (one line, at most 160 characters): the stage's description on the user's page").optional()
|
|
351
|
+
});
|
|
352
|
+
var StagesBody = external_exports.strictObject({});
|
|
353
|
+
var ServerBody = external_exports.strictObject({});
|
|
354
|
+
var StageAddBody = external_exports.strictObject({
|
|
355
|
+
name: StageName.describe("the new stage: lowercase snake_case, one to three words, at most 24 characters, not a Herdr state"),
|
|
356
|
+
usage: text$1("when to use it, in a sentence, so other agents choose it rightly")
|
|
357
|
+
});
|
|
358
|
+
var ThrottleBody = external_exports.strictObject({});
|
|
359
|
+
var StartNowBody = external_exports.strictObject({ held: external_exports.number().int().min(1).describe("the held work's id, as throttle lists it") });
|
|
360
|
+
var PausedBody = external_exports.strictObject({ note: text$1("where you stopped, if it helps you pick up again").optional() });
|
|
361
|
+
var ReadBody = external_exports.strictObject({});
|
|
362
|
+
var WaitingBody = external_exports.strictObject({});
|
|
363
|
+
var t = (name, description, body) => ({
|
|
364
|
+
name,
|
|
365
|
+
description,
|
|
366
|
+
body
|
|
367
|
+
});
|
|
368
|
+
var TYPES = Object.fromEntries([
|
|
369
|
+
t("message", "Send a message to a slot, org/repo@track, or to user. Use it to ask, answer, report, or hand off work; name the issue it concerns in about. A message to a slot with no agent running is held, and the bus brings the slot back up; while resources are short, the throttle brings it up once they recover.", SendBody),
|
|
370
|
+
t("start", "Start an agent of one of the Agent Types in the catalog with a task, on a track, in its own slot in the repo. The reply gives its id; it reports back to you by message. Agents in several repos go down one track together by naming the same track, but a repo has one slot on a track. While resources are short, the throttle holds it: the reply says held, and you are told by message once it starts.", StartBody),
|
|
371
|
+
t("stop", "End an agent's Session when its work is done or it is no longer needed.", StopBody),
|
|
372
|
+
t("resume", "Bring a slot whose agent ended back up, in its own worktree, resuming its conversation where it can.", ResumeBody),
|
|
373
|
+
t("adopt", "Make a worktree that already exists at its slot's place a slot the bus knows, with no agent running; a message to it later brings it up with a fresh agent there.", AdoptBody),
|
|
374
|
+
t("throttle", "See what the throttle sees and is doing: its level, what it says, the agent it asked to pause, and the work it holds until resources recover, oldest first.", ThrottleBody),
|
|
375
|
+
t("start_now", "The user's alone, as their page's Start now: run one piece of work the throttle holds at once, whatever resources say.", StartNowBody),
|
|
376
|
+
t("paused", "Tell the bus you stopped at a safe point after the throttle asked you to pause, because resources ran out; the bus closes you, and brings you back in this conversation once memory recovers.", PausedBody),
|
|
377
|
+
t("ask", "Tell the bus you are about to ask the user, then ask them with your AskUserQuestion tool in your own session: your plan before building, your finished work before landing, a pr before you send it, or a decision. The user is told you wait; your next send shows you carried on.", AskBody),
|
|
378
|
+
t("land", "Land your slot's branch, the only way your work reaches the default branch: the bus checks it is committed and on the latest origin default branch, then lands the commit it checked as the repo's Landing Method says (pushed to the default branch, or pushed as your branch with a PR opened or updated). It closes the issue in about once the work is on the default branch, and ends you once you rest, when end is set; without it you keep working; a refusal says why, and nothing is pushed. With no_code, work with nothing to push finishes the same way. A lead whose followers have not all landed stays up, its issue held, until they have.", LandBody),
|
|
379
|
+
t("push", "Push your slot's own branch to origin under its own name, to back up work, run CI, or share it; it lands nothing.", PushBody),
|
|
380
|
+
t("pr", "Open a PR that is itself part of your work, such as a preview environment for your branch, or one that bootstraps a system you are deploying: the bus pushes head and opens the PR as the org's account, and records it as your Work PR. It is never a landing: it never changes your stage, closes an issue, or ends you, and the bus does not watch it; follow it yourself with gh pr view and gh pr checks. Never use it to land your work: that is land, which is refused while a Work PR from your branch into the default branch is open, so close it first. Sending it again for the same head and base pushes and keeps that PR.", PrBody),
|
|
381
|
+
t("pr_close", "Close a Work PR you opened with pr, when it has done its job or before you land the work it was opened from; any other PR is refused.", PrCloseBody),
|
|
382
|
+
t("github", "Read what the bus allows from GitHub for your repo, with the right account: pr, your PR's state, checks, mergeability, reviews, and comments. Anything else is refused.", GitHubBody),
|
|
383
|
+
t("landed", "Report work that needs no land: done with nothing to push (an answer, a review), with a note, or already on the repo's default branch, with the commit it landed as, which the bus links. It closes the issue in about. Work with commits to land lands with land, which reports landed itself; landed is refused while your branch has commits to land.", LandedBody),
|
|
384
|
+
t("leash", "The user's alone: set a slot's leash, gated or free, and whether its agent stays open after landing; the slot is told.", LeashBody),
|
|
385
|
+
t("lead", "The user's alone: give a slot a lead, another slot whose bus messages and approvals it then takes as the user's, or clear its lead by leaving lead out; the bus tells both in their own sessions, as the user.", LeadBody),
|
|
386
|
+
t("follower", "Bring a repo's slot on a lead's track up as the lead's follower: a new agent there with the lead set, told to introduce itself to the lead, or with existing, the slot or worktree already there, led. Every rule is checked first, so a refusal changes nothing. From user it runs at once; from a slot, only for its own slot as lead, held as a follower request until the user approves it.", FollowerBody),
|
|
387
|
+
t("follower_answer", "The user's alone: approve or decline a lead's follower request; approving runs it, checked again.", FollowerAnswerBody),
|
|
388
|
+
t("status", "Name the stage your work is in, from the stages below, and say in a few words what you are doing; both show on the user's Web Page beside Herdr's state. Send it at each change of work. The bus alone sets the gated stages, as you pass their gates, and refuses status once your work has landed.", StatusBody),
|
|
389
|
+
t("server", "What this coordinator is: its version, its folder ($COORDINATOR_ROOT), its development folder, and the user's name and their address on the bus. Ask whenever you need one of them; a path under the folder is $COORDINATOR_ROOT/...", ServerBody),
|
|
390
|
+
t("stages", "List every stage with its usage: the fixed ones, and those agents registered. Check it before adding one.", StagesBody),
|
|
391
|
+
t("stage_add", "Register a stage, with when to use it, only when none in stages fits your work; every agent can name it after.", StageAddBody),
|
|
392
|
+
t("issue_open", "Open an issue in any repo (your own by default); its slug must be new in that repo. Set holder to give it to a slot of that repo at once: your own, as a note of work to come back to, or one you work with. Set blocked_by to the issues it waits on.", IssueOpenBody),
|
|
393
|
+
t("issue_assign", "Give an issue to a slot of its repo, while no slot holds it or its holder has no agent running; refused while it is blocked.", IssueAssignBody),
|
|
394
|
+
t("issue_take", "Hold an issue of your own repo, while no slot holds it or its holder has no agent running; name none to take the first free one in your repo's order. Blocked issues are skipped, and refused when named.", IssueTakeBody),
|
|
395
|
+
t("issue_block", "Make an issue wait on another, in any repo: it is blocked, never handed out, until that one lands. Refused for itself, an unknown issue, one closed without landing, or one that already waits on it.", IssueBlockBody),
|
|
396
|
+
t("issue_unblock", "Stop an issue waiting on another; once it waits on nothing unlanded, its holder and user are told it is ready.", IssueUnblockBody),
|
|
397
|
+
t("issue_move", "Move an open issue, one no slot holds, to the top of its repo's order, or one place up or down; the first is the next taken. Held and closed issues are not ordered.", IssueMoveBody),
|
|
398
|
+
t("issue_ask", "Ask the slot holding an issue of your own repo, whose agent is running, to hand it to you.", IssueAskBody),
|
|
399
|
+
t("issue_hand_over", "Hand an issue you hold to the slot that asked for it.", IssueHandOverBody),
|
|
400
|
+
t("issue_keep", "Keep an issue you hold that a slot asked for, saying why.", IssueKeepBody),
|
|
401
|
+
t("issue_release", "Stop holding an issue, leaving it open, last in its repo's order, for any slot of its repo to take.", IssueReleaseBody),
|
|
402
|
+
t("issue_comment", "Add a comment to an issue.", IssueCommentBody),
|
|
403
|
+
t("issue_link", "Add a link to an issue's work outside the bus, such as its ticket or a page, shown on its page; once per url. With remove, take the link with that url away.", IssueLinkBody),
|
|
404
|
+
t("issue_plan", "Record one of an issue's plans on it as soon as it is published: its page's link, a name for its part of the work, and approved once the user approves it; by the issue's holder or user. A new link adds a plan, so an issue keeps as many as the work needs, a known link with a name renames that plan, and replaces moves a plan to a new link in place; the bus is the record of approval, and a cleared or new session finds the plans here.", IssuePlanBody),
|
|
405
|
+
t("issue_plan_delete", "Delete one of an issue's plans, by anyone at any time, closed issues included: it only removes the link from the issue's plans, and a document it links to stays.", IssuePlanDeleteBody),
|
|
406
|
+
t("doc_publish", "Publish an HTML page as one of an issue's documents, kept for good and served by the coordinator, the better home for a plan or any page you show the user than a Claude artifact: the bus copies the file or folder at path in place of the document's newest version, or as its next once the issue's work has landed since, and answers with its link, the same view on the Web Page and in a tab of its own, under a live header of its issue and slot. Give a plan's link to issue_plan. Pages may load /docs/doc.js for that context and to ask to act as the user.", DocPublishBody),
|
|
407
|
+
t("issue_followers", "The user's alone: set an issue's follower repos, kept repos other than its own; when it is started or passed to a slot, each one's slot on that track comes up as the holder's follower.", IssueFollowersBody),
|
|
408
|
+
t("issue_close", "Close an issue, saying what was done; only an explicit close ends an issue.", IssueCloseBody),
|
|
409
|
+
t("issues", "List issues, by repo, state (open, held, or closed), or holding slot: open ones in each repo's order, then held and closed ones, newest first.", IssuesBody),
|
|
410
|
+
t("slot", "One slot's whole picture: its agent and stage, its Landing (state, method, commit, PR number and link), the issues it holds, and its properties and badges.", SlotBody),
|
|
411
|
+
t("slot_property", "Set one of a slot's properties, a name and value shown on its page, with an optional link its value opens; the same name again replaces it, and no value clears it. Kept for the next agent on the slot.", SlotPropertyBody),
|
|
412
|
+
t("slot_badge", "Set one of a slot's badges, a short label in a tone shown beside its stage, by a name that keys it, so changing state keeps one badge; no label clears it. Kept for the next agent on the slot.", SlotBadgeBody),
|
|
413
|
+
t("slots", "List the slots the bus knows, each with its agent's Agent Type, state, task, and latest status; by track, repo, or only those with an agent running.", SlotsBody),
|
|
414
|
+
t("repos", "List the repos the bus keeps, each with its checkout, default branch, agents running, slots, and open or held issues; name one for its local branches and worktrees from git, each branch with the slot on it, its agent's state and stage, and the issues it holds, then worktrees outside the layout, which the bus never adopts.", ReposBody),
|
|
415
|
+
t("changes", "Read a repo's Change Summaries, its history of landings: 20 at a time, newest first, each with its title, one-line summary, what was built, the challenges, and its PR or commit link; more says older ones remain, read with before.", ChangesBody),
|
|
416
|
+
t("repo_add", "Keep a repo, named by org/repo or a GitHub URL: the clone already at its place under repos, or cloned there from GitHub first; its default branch is read from git. Agents start only in repos the bus keeps.", RepoAddBody),
|
|
417
|
+
t("secret_key", "When your work needs a new secret, add its empty name with this: the bus appends NAME= to the repo's .env.secrets only when no line names it, and tells the user, who fills in the value from the repo's Settings. Your slot's worktree starts with a copy of the repo's file, made when your agent starts; with slot, the name goes in your slot's own file instead, for a secret only this track needs, gone when the track is cleaned up. The reply says added or already there, never anything about a value; you never read, set, or overwrite one.", SecretKeyBody),
|
|
418
|
+
t("repo_settings", "The user's alone: change some of a repo's settings, such as landing (how its agents' work lands: push or pr), pre_land, during_land, and post_land (its Landing Scripts, .mjs files in the repo the server runs before each landing, while its PR is open, and after), during_every (how often During landing runs), order (the order its agents get the Profiles on for it, after base), and defaults (on or off: whether its agents get the built-in defaults Profile).", RepoSettingsBody),
|
|
419
|
+
t("repo_forget", "The user's alone: stop keeping a repo, leaving its files; refused while it has agents running or open or held issues.", RepoForgetBody),
|
|
420
|
+
t("login_set", "The user's alone: add or change a GitHub login the bus keeps: its SSH key (made and uploaded when none is named), the name and email its commits carry, and its orgs; the bus writes it into every kept repo of those orgs.", LoginSetBody),
|
|
421
|
+
t("login_remove", "The user's alone: stop keeping a GitHub login; its key, gh's sign-in, and repos' config stay.", LoginRemoveBody),
|
|
422
|
+
t("org_login", "The user's alone: point an org's kept repos at a GitHub login the bus keeps.", OrgLoginBody),
|
|
423
|
+
t("github_sign_in", "The user's alone: start gh's web sign-in, which shows a one-time code on the page, or cancel it.", GitHubSignInBody),
|
|
424
|
+
t("profiles", "List the Profiles (base first, which every agent gets, then defaults, the Default Skills, on unless a repo turns it off), each with the repo it is kept in, the repos it is on for, and its own event handlers and actions; and the skills by source (shipped base and extra, each attached folder, each npx skills source, and each marketplace plugin). A profile chooses from each source all of it or some skills.", ProfilesBody),
|
|
425
|
+
t("profile_save", "The user's alone: create or change a Profile, saved in the repo it is kept in (at once where that repo's git ignores .coord_repo/, else landed there the repo's way), or an attached folder (a folder of skills under ~, used In Place, its path in change); base and defaults are never changed.", ProfileSaveBody),
|
|
426
|
+
t("profile_delete", "The user's alone: delete a Profile from its repo, or detach a folder no profile takes from.", ProfileDeleteBody),
|
|
427
|
+
t("profiles_move", "The user's alone: move the Profiles from before they were kept in repos into the kept repo named, as one change landed there.", ProfilesMoveBody),
|
|
428
|
+
t("folders", "The user's alone: the folders inside a folder under ~, for choosing one to attach.", FoldersBody),
|
|
429
|
+
t("history", "Look over recent Messages, oldest first: to or from a slot (or user), about an issue, or not yet read. It marks nothing read.", HistoryBody),
|
|
430
|
+
t("read", "Read your unread Messages, and the catalog if it changed. Use it whenever the bus tells you Messages are waiting.", ReadBody),
|
|
431
|
+
t("waiting", "Whether Messages wait for you: the newest unread one's id, or null. The agents' plugin asks it after each step to tell you; you need not send it yourself.", WaitingBody)
|
|
432
|
+
].map((kind) => [kind.name, kind]));
|
|
433
|
+
external_exports.strictObject({
|
|
434
|
+
name: external_exports.string(),
|
|
435
|
+
description: external_exports.string().min(1),
|
|
436
|
+
prompt: external_exports.string().default(""),
|
|
437
|
+
model: external_exports.string().nullable().default(null),
|
|
438
|
+
permission_mode: external_exports.enum([
|
|
439
|
+
"default",
|
|
440
|
+
"acceptEdits",
|
|
441
|
+
"plan",
|
|
442
|
+
"auto",
|
|
443
|
+
"dontAsk",
|
|
444
|
+
"bypassPermissions"
|
|
445
|
+
]).nullable().default(null),
|
|
446
|
+
effort: external_exports.enum([
|
|
447
|
+
"low",
|
|
448
|
+
"medium",
|
|
449
|
+
"high",
|
|
450
|
+
"xhigh",
|
|
451
|
+
"max"
|
|
452
|
+
]).nullable().default(null),
|
|
453
|
+
settings: external_exports.record(external_exports.string(), external_exports.any()).default({}),
|
|
454
|
+
mcp: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.any())).default({}),
|
|
455
|
+
files: external_exports.array(external_exports.string()).default([]),
|
|
456
|
+
/** The built-in tools it has, as claude's --tools names them; all of them when unset, none when empty. */
|
|
457
|
+
tools: external_exports.array(external_exports.string()).nullable().default(null),
|
|
458
|
+
/** Plugin folders it loads from the coordinator's own package; the Agent plugins setting adds the user's to a slot's agent. */
|
|
459
|
+
plugins: external_exports.array(external_exports.string()).default([]),
|
|
460
|
+
/** The Message Types its Port may send; all of them when unset. */
|
|
461
|
+
messages: external_exports.array(external_exports.string().refine((m) => m in TYPES, { error: (i) => `no Message Type ${String(i.input)}` })).nullable().default(null),
|
|
462
|
+
sandbox: external_exports.boolean().default(false)
|
|
463
|
+
});
|
|
464
|
+
function startable(t2) {
|
|
465
|
+
return t2.name !== CONSOLE;
|
|
466
|
+
}
|
|
467
|
+
get("waker");
|
|
468
|
+
var AT_REST = /* @__PURE__ */ new Set(["idle", "done"]);
|
|
469
|
+
function restMinutes(s, messages, at = Date.now()) {
|
|
470
|
+
const slot = slotOf(s);
|
|
471
|
+
if (!(isLive(s) && slot && AT_REST.has(s.state) && s.idle_since) || s.keep_open || s.landed_at || s.stage === "pr_open" || s.lead || s.finishing) return null;
|
|
472
|
+
if (openAsk(messages, slot) || messages.some((m) => m.to === slot && !m.delivered)) return null;
|
|
473
|
+
return (at - Date.parse(s.idle_since)) / 6e4;
|
|
474
|
+
}
|
|
475
|
+
function quiet(s, messages, settings, at = Date.now()) {
|
|
476
|
+
const rest = restMinutes(s, messages, at);
|
|
477
|
+
return rest !== null && rest >= settings.idle_warning_minutes;
|
|
478
|
+
}
|
|
479
|
+
function trackTree(sessions) {
|
|
480
|
+
const root = {
|
|
481
|
+
name: "",
|
|
482
|
+
path: "",
|
|
483
|
+
sessions: [],
|
|
484
|
+
children: /* @__PURE__ */ new Map()
|
|
485
|
+
};
|
|
486
|
+
const sorted = [...sessions].sort((a, b) => cmp(a.track.toLowerCase(), b.track.toLowerCase()) || cmp(a.repo ?? "", b.repo ?? "") || cmp(a.started, b.started));
|
|
487
|
+
for (const s of sorted) {
|
|
488
|
+
let node = root;
|
|
489
|
+
const parts = s.track.split("/");
|
|
490
|
+
parts.forEach((part, depth) => {
|
|
491
|
+
if (!node.children.has(part)) node.children.set(part, {
|
|
492
|
+
name: part,
|
|
493
|
+
path: parts.slice(0, depth + 1).join("/"),
|
|
494
|
+
sessions: [],
|
|
495
|
+
children: /* @__PURE__ */ new Map()
|
|
496
|
+
});
|
|
497
|
+
node = node.children.get(part);
|
|
498
|
+
});
|
|
499
|
+
node.sessions.push(s.id);
|
|
500
|
+
}
|
|
501
|
+
const byId = new Map(sessions.map((s) => [s.id, s]));
|
|
502
|
+
const leadFirst = (ids) => {
|
|
503
|
+
const leads = new Set(ids.map((id) => byId.get(id).lead));
|
|
504
|
+
const rank = (id) => Number(!leads.has(slotOf(byId.get(id))));
|
|
505
|
+
return [...ids].sort((a, b) => rank(a) - rank(b));
|
|
506
|
+
};
|
|
507
|
+
const view = (n) => ({
|
|
508
|
+
name: n.name,
|
|
509
|
+
path: n.path,
|
|
510
|
+
sessions: leadFirst(n.sessions),
|
|
511
|
+
children: [...n.children.values()].sort((a, b) => cmp(a.name.toLowerCase(), b.name.toLowerCase())).map(view)
|
|
512
|
+
});
|
|
513
|
+
return view(root).children;
|
|
514
|
+
}
|
|
515
|
+
function textOf(m) {
|
|
516
|
+
const body = m.body;
|
|
517
|
+
if (m.type === "message" || m.type === "status") return body.text ?? "";
|
|
518
|
+
if (m.type === "start") return `start ${body.type} at ${m.started ?? "?"}: ${body.task ?? ""}`;
|
|
519
|
+
if (m.type === "stop" || m.type === "resume") return `${m.type} ${body.to ?? ""}`;
|
|
520
|
+
if (m.type === "issue") return `${body.issue} ${body.event}` + (body.text ? `: ${body.text}` : "");
|
|
521
|
+
if (m.type === "event") {
|
|
522
|
+
const n = (body.handlers ?? []).length;
|
|
523
|
+
return `${body.name} fired` + (n ? `: ${n} handler${n === 1 ? "" : "s"} from its profile given` : "");
|
|
524
|
+
}
|
|
525
|
+
if (m.type === "catalog") return "the catalog of Agent Types and Message Types changed";
|
|
526
|
+
if (m.type === "ask") return `asks you (${body.kind}): ${body.text}`;
|
|
527
|
+
if (m.type === "landed") return `landed: ${body.link ?? "nothing to push"}` + (body.note ? `. ${body.note}` : "") + (body.waiting ? `; waits on ${body.waiting.join(", ")} before closing` : "");
|
|
528
|
+
return pythonish(body);
|
|
529
|
+
}
|
|
530
|
+
function pythonish(value) {
|
|
531
|
+
if (value === null || value === void 0) return "None";
|
|
532
|
+
if (typeof value === "string") return `'${value}'`;
|
|
533
|
+
if (typeof value === "boolean") return value ? "True" : "False";
|
|
534
|
+
if (Array.isArray(value)) return `[${value.map(pythonish).join(", ")}]`;
|
|
535
|
+
if (typeof value === "object") return `{${Object.entries(value).map(([k, v]) => `'${k}': ${pythonish(v)}`).join(", ")}}`;
|
|
536
|
+
return String(value);
|
|
537
|
+
}
|
|
538
|
+
function sessionView(s, sessions, messages, settings, landings = {}, workPrs = [], requests = []) {
|
|
539
|
+
const slot = slotOf(s);
|
|
540
|
+
const started = sessions.filter((o) => slot && o.parent === slot && isLive(o)).sort((a, b) => cmp(a.started, b.started));
|
|
541
|
+
const { token: _, ...shown2 } = s;
|
|
542
|
+
const asked = slot && isLive(s) ? openAsk(messages, slot) : null;
|
|
543
|
+
const ask = asked ? {
|
|
544
|
+
id: asked.id,
|
|
545
|
+
at: asked.at,
|
|
546
|
+
kind: asked.body.kind,
|
|
547
|
+
text: asked.body.text,
|
|
548
|
+
about: asked.body.about ?? null
|
|
549
|
+
} : null;
|
|
550
|
+
const followers = slot ? followersOf(sessions, slot) : [];
|
|
551
|
+
const l = slot ? landings[slot] : void 0;
|
|
552
|
+
const landing = l ? {
|
|
553
|
+
state: l.state,
|
|
554
|
+
method: l.method,
|
|
555
|
+
title: l.title,
|
|
556
|
+
reason: l.reason,
|
|
557
|
+
link: l.link,
|
|
558
|
+
pr: l.pr,
|
|
559
|
+
commits: l.commits,
|
|
560
|
+
summary: l.summary,
|
|
561
|
+
revised: l.revised,
|
|
562
|
+
change: l.change,
|
|
563
|
+
repo: l.repo,
|
|
564
|
+
during: l.during,
|
|
565
|
+
updated_at: l.updated_at
|
|
566
|
+
} : null;
|
|
567
|
+
const work_prs = workPrs.filter((w) => w.slot === slot).reverse().map((w) => ({
|
|
568
|
+
repo: w.repo,
|
|
569
|
+
head: w.head,
|
|
570
|
+
base: w.base,
|
|
571
|
+
title: w.title,
|
|
572
|
+
about: w.about,
|
|
573
|
+
number: w.number,
|
|
574
|
+
link: w.link,
|
|
575
|
+
state: w.state,
|
|
576
|
+
reason: w.reason,
|
|
577
|
+
at: w.at
|
|
578
|
+
}));
|
|
579
|
+
const follower_requests = requests.filter((r) => r.lead === slot && r.state === "pending").map((r) => ({
|
|
580
|
+
id: r.id,
|
|
581
|
+
repo: r.repo,
|
|
582
|
+
type: r.type,
|
|
583
|
+
task: r.task,
|
|
584
|
+
existing: r.existing,
|
|
585
|
+
at: r.at
|
|
586
|
+
}));
|
|
587
|
+
const waits_on = slot && s.finishing ? unfinishedFollowers(sessions, slot) : [];
|
|
588
|
+
return {
|
|
589
|
+
...shown2,
|
|
590
|
+
slot,
|
|
591
|
+
started_ids: started.map((o) => o.id),
|
|
592
|
+
followers,
|
|
593
|
+
ask,
|
|
594
|
+
quiet: quiet(s, messages, settings),
|
|
595
|
+
landing,
|
|
596
|
+
work_prs,
|
|
597
|
+
follower_requests,
|
|
598
|
+
waits_on
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
function issueView(i, all, docs) {
|
|
602
|
+
const address = addressOfIssue(i);
|
|
603
|
+
return {
|
|
604
|
+
...i,
|
|
605
|
+
address,
|
|
606
|
+
blocked: waitingOn(i, (a) => all[a]).length > 0,
|
|
607
|
+
docs: docs.of(address).map((d) => docView(d, docs))
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function docView(d, docs) {
|
|
611
|
+
return {
|
|
612
|
+
address: docAddress(d),
|
|
613
|
+
name: d.name,
|
|
614
|
+
title: d.title,
|
|
615
|
+
by: d.by,
|
|
616
|
+
version: latest(d),
|
|
617
|
+
versions: d.versions.map((v) => v.n),
|
|
618
|
+
created_at: d.created_at,
|
|
619
|
+
updated_at: updatedAt(d),
|
|
620
|
+
path: docPath(d),
|
|
621
|
+
link: docs.link(d),
|
|
622
|
+
frame: docs.frame(d)
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function shown(sessions) {
|
|
626
|
+
return latestPerSlot(Object.values(sessions));
|
|
627
|
+
}
|
|
628
|
+
function consoleView(system, all) {
|
|
629
|
+
const latest2 = system.console.latest();
|
|
630
|
+
return latest2 && system.config.current().console ? sessionView(latest2, all, system.bus.messages(), system.config.current()) : null;
|
|
631
|
+
}
|
|
632
|
+
async function model(system) {
|
|
633
|
+
const state = system.bus.snapshot();
|
|
634
|
+
const all = Object.values(state.sessions);
|
|
635
|
+
const live = shown(state.sessions).filter((s) => !system.cleanup.cleaning(s.id));
|
|
636
|
+
const msgs = state.messages.slice(-300).map((m) => ({
|
|
637
|
+
id: m.id,
|
|
638
|
+
at: m.at,
|
|
639
|
+
from: m.from,
|
|
640
|
+
to: m.to,
|
|
641
|
+
type: m.type,
|
|
642
|
+
text: textOf(m),
|
|
643
|
+
about: m.body.about || m.body.issue || null,
|
|
644
|
+
delivered: m.delivered
|
|
645
|
+
}));
|
|
646
|
+
return {
|
|
647
|
+
tree: trackTree(live),
|
|
648
|
+
sessions: Object.fromEntries(live.map((s) => [s.id, sessionView(s, all, state.messages, system.config.current(), state.landings, state.work_prs, state.follower_requests)])),
|
|
649
|
+
slots: Object.fromEntries(live.map((s) => [slotOf(s), s.id])),
|
|
650
|
+
messages: msgs,
|
|
651
|
+
inbox: msgs.filter((m) => m.to === USER),
|
|
652
|
+
bus: "bus",
|
|
653
|
+
issues: Object.values(state.issues).sort(issueOrder).map((i) => issueView(i, state.issues, system.docs)),
|
|
654
|
+
groupings: Object.fromEntries(Object.entries(state.groupings).map(([repo, g]) => {
|
|
655
|
+
const address = (slug) => `${repo}#${slug}`;
|
|
656
|
+
return [repo, {
|
|
657
|
+
at: g.at,
|
|
658
|
+
weighed: g.weighed.map(address),
|
|
659
|
+
groups: g.groups.map((x) => ({
|
|
660
|
+
issues: x.issues.map(address),
|
|
661
|
+
why: x.why
|
|
662
|
+
}))
|
|
663
|
+
}];
|
|
664
|
+
})),
|
|
665
|
+
types: Object.values(system.types).filter(startable).map((t2) => ({
|
|
666
|
+
name: t2.name,
|
|
667
|
+
description: t2.description
|
|
668
|
+
})),
|
|
669
|
+
repos: await system.repos.summaries(),
|
|
670
|
+
...system.logins.view(),
|
|
671
|
+
profiles: system.skills.view(),
|
|
672
|
+
settings: describe(system.config.current()),
|
|
673
|
+
console: consoleView(system, all)
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
var GET = async ({ locals }) => json({
|
|
677
|
+
...await model(locals.served.system),
|
|
678
|
+
resources: locals.served.resources.latest,
|
|
679
|
+
throttle: locals.served.system.throttle.view()
|
|
680
|
+
});
|
|
681
|
+
export {
|
|
682
|
+
GET
|
|
683
|
+
};
|