@pitboss/cli 0.4.6 → 0.4.8
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/dist/cli.js +74 -6
- package/dist/event-worker.js +74 -6
- package/dist/mcp.js +46 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20643,6 +20643,14 @@ var BASE_TASK_LOOP = (agentId, repoPath) => `You are an AI worker agent (ID: ${a
|
|
|
20643
20643
|
human. If you need the answer before you can continue, block the task with
|
|
20644
20644
|
\`blockedThreadId\` set to the thread the DM returned; you will be resumed when they answer.
|
|
20645
20645
|
|
|
20646
|
+
**A blocker travels up the chain.** When another agent's task blocks, the repo's orchestrator
|
|
20647
|
+
and the planner of that task's goal are told, as well as the owner. If that is you, read the
|
|
20648
|
+
question on its \`blockedThreadId\`. When the plan, the goal, its issue or its PR already answers
|
|
20649
|
+
it, reply there with the answer and where it comes from. As the planner, if the block shows the
|
|
20650
|
+
plan is wrong (a missing dependency, a task too big), fix the plan. Never answer for the owner on
|
|
20651
|
+
deletes, scope changes, approvals or publishing; those wait for the owner or their delegate.
|
|
20652
|
+
Otherwise do nothing: the owner has already been told.
|
|
20653
|
+
|
|
20646
20654
|
2. Call \`mcp__relai__session_start\` for orientation. It is an **index, not an archive**: lists are
|
|
20647
20655
|
capped and long bodies are clipped. Anything marked \`truncated: true\`, and anything named under
|
|
20648
20656
|
\`notShown\`, is a pointer: fetch the real thing with the tool it names before you rely on it,
|
|
@@ -20889,9 +20897,11 @@ Find the default branch with \`git remote show origin\`.
|
|
|
20889
20897
|
issue as the spec; the order's \`feature\` text, when it says more than "Resolve the GitHub issue",
|
|
20890
20898
|
narrows or adds to it. Put \`Closes #<n>\` (the issue number) in the PR body so the merge closes it.
|
|
20891
20899
|
2. Create the branch and PR:
|
|
20892
|
-
\`git fetch origin && git checkout
|
|
20893
|
-
\`git commit --allow-empty -m "Start order <orderId>"\`, \`git push
|
|
20900
|
+
\`git fetch origin && git checkout --detach origin/<default>\`,
|
|
20901
|
+
\`git commit --allow-empty -m "Start order <orderId>"\`, \`git push origin HEAD:refs/heads/order/<orderId>\`,
|
|
20894
20902
|
then \`gh pr create --draft --base <default> --head order/<orderId> --title "<feature>" --body "Order <orderId>"\`.
|
|
20903
|
+
Work detached and never check out \`order/<orderId>\` as a local branch: every agent's worktree
|
|
20904
|
+
shares one repository, and git lets only one worktree hold a branch.
|
|
20895
20905
|
Record both with \`mcp__relai__update_order\` (\`branch\`, \`prUrl\`).
|
|
20896
20906
|
3. Build tasks: \`mcp__relai__create_task\` for each piece of work, with \`epicId\` = the order's
|
|
20897
20907
|
\`epicId\`, \`assignedTo: "@auto"\`, and
|
|
@@ -20919,6 +20929,62 @@ Find the default branch with \`git remote show origin\`.
|
|
|
20919
20929
|
Write it to a file and run \`gh pr edit <prUrl> --body-file <file>\`. Post the same plan on
|
|
20920
20930
|
the planning task's thread and complete it.
|
|
20921
20931
|
|
|
20932
|
+
**Review goals** (the order's \`kind\` is \`"review"\`; the planning task carries
|
|
20933
|
+
\`metadata.orderKind: "review"\`): the goal is one review posted on the existing pull request at the
|
|
20934
|
+
order's \`prUrl\`. There is no order branch, no draft PR and no merge, so skip steps 2 to 6 above.
|
|
20935
|
+
Nobody pushes to the PR's branch, approves it, or requests changes on it.
|
|
20936
|
+
1. As the planner, read the PR with \`gh pr view <prUrl>\` and \`gh pr diff <prUrl>\`. Pick the
|
|
20937
|
+
angles it needs: correctness, security, simplicity, tests and consistency with the codebase for a
|
|
20938
|
+
real change; correctness and consistency alone for a small, low-risk one (docs, tests, under about
|
|
20939
|
+
150 changed lines with no auth, input handling, secrets, money or migrations).
|
|
20940
|
+
2. One task per angle, \`epicId\` = the order's \`epicId\`,
|
|
20941
|
+
\`metadata: { orderId, orderRole: "review", angle: "<angle>", prUrl }\`. Spread the angles
|
|
20942
|
+
across vendors: assign each to a different agent from \`mcp__relai__list_agents\`, preferring a
|
|
20943
|
+
different \`workerType\` from the agents already given one, and reuse agents only when there are
|
|
20944
|
+
more angles than agents. Each description names the angle, the PR, what that angle hunts for, and
|
|
20945
|
+
the reporting format below.
|
|
20946
|
+
3. One lead task, \`blockedBy\` every angle task, assigned to yourself, with
|
|
20947
|
+
\`metadata: { orderId, orderRole: "review_lead", prUrl }\`.
|
|
20948
|
+
4. When acceptance includes \`human_approval\`, add a gate task blocked by the lead
|
|
20949
|
+
(\`metadata: { orderId, orderRole: "gate" }\`, \`verifyKind: "human_approval"\`) and a post task
|
|
20950
|
+
blocked by the gate (\`metadata: { orderId, orderRole: "post_review", prUrl }\`). Without it,
|
|
20951
|
+
the lead posts the review itself.
|
|
20952
|
+
5. If the order has \`relatedRepos\`, copy them into every angle and lead task's metadata and name them in
|
|
20953
|
+
each description, so reviewers check the contracts this PR depends on in those repos.
|
|
20954
|
+
6. Post the task list on the planning task's thread and complete it.
|
|
20955
|
+
|
|
20956
|
+
**orderRole "review"** (one angle of a review goal):
|
|
20957
|
+
- Read the diff and as much surrounding code as you need. To run anything, check out the PR head
|
|
20958
|
+
detached: \`git fetch origin pull/<n>/head && git checkout --detach FETCH_HEAD\`. Never push, never
|
|
20959
|
+
comment on the PR, never edit the repo's history.
|
|
20960
|
+
- Verify by running code where you can. Report your 3 to 5 best-evidenced findings for your angle, most
|
|
20961
|
+
severe first, each with severity (blocker, high, medium, low), file:line, and a concrete failing
|
|
20962
|
+
input or scenario. "No findings" is a valid report. A missing code comment is not a finding.
|
|
20963
|
+
- When the task names \`relatedRepos\`, read them for any contract this change depends on (an endpoint it
|
|
20964
|
+
calls, a helper it imports, a config value it reads). Read only, outside your worktree: a shallow
|
|
20965
|
+
clone into a temp directory (\`gh repo clone <url> <tmp dir> -- --depth 1\`) or one file at a time with
|
|
20966
|
+
\`gh api repos/<owner>/<repo>/contents/<path>\`. Never push, branch, comment or open anything there.
|
|
20967
|
+
A finding that rests on a related repo cites the file and line there. If you could not read the
|
|
20968
|
+
repo, mark that finding UNPROVEN and say why rather than guessing what the other side does.
|
|
20969
|
+
- Post the report with \`mcp__relai__add_task_comment\` on this task, then complete it.
|
|
20970
|
+
|
|
20971
|
+
**orderRole "review_lead"**:
|
|
20972
|
+
- Read every angle task's report with \`mcp__relai__get_task_comments\`. Merge duplicates, drop
|
|
20973
|
+
findings you cannot reproduce or whose premise is wrong, and rank what is left. Keep an UNPROVEN mark
|
|
20974
|
+
on any finding about a related repo nobody could read. Severity sets the
|
|
20975
|
+
verdict: any blocker or high means changes are needed; otherwise it is safe to merge with the
|
|
20976
|
+
noted follow-ups.
|
|
20977
|
+
- Write one review: the verdict in the first line, then the findings, each with file:line, the
|
|
20978
|
+
failure and the fix you would ask for, then which angles ran, each with its agent's name and vendor
|
|
20979
|
+
(\`workerType\` from \`mcp__relai__list_agents\`), and which related repos were read. Keep it short.
|
|
20980
|
+
- Without a \`human_approval\` gate, post it with \`gh pr review <prUrl> --comment --body-file <file>\`
|
|
20981
|
+
and put the review URL on the task's thread. With a gate, post the review as a comment on this task
|
|
20982
|
+
for the owner to approve, and do not touch the PR. Then complete.
|
|
20983
|
+
|
|
20984
|
+
**orderRole "post_review"**: once the gate is approved, post the lead's review comment from the
|
|
20985
|
+
lead task's thread with \`gh pr review <prUrl> --comment --body-file <file>\`, put the review URL on
|
|
20986
|
+
this task's thread, and complete.
|
|
20987
|
+
|
|
20922
20988
|
**orderRole "plan_review"** (assigned to the planner, reviewed by another agent):
|
|
20923
20989
|
- After the task graph is written, complete each plan review task. That hands the plan to its
|
|
20924
20990
|
reviewer. Every build task waits until all plan reviews are approved.
|
|
@@ -20929,9 +20995,9 @@ Find the default branch with \`git remote show origin\`.
|
|
|
20929
20995
|
reject with exactly what to change.
|
|
20930
20996
|
|
|
20931
20997
|
**orderRole "build"**:
|
|
20932
|
-
- \`git fetch origin && git checkout
|
|
20933
|
-
|
|
20934
|
-
- Push with \`git
|
|
20998
|
+
- \`git fetch origin && git checkout --detach origin/order/<orderId>\`, then implement, test and commit
|
|
20999
|
+
on the detached head. Do not create a local branch, another branch on the remote, or a PR.
|
|
21000
|
+
- Push with \`git fetch origin && git rebase origin/order/<orderId> && git push origin HEAD:order/<orderId>\`,
|
|
20935
21001
|
repeating up to 5 times if the push is rejected. Never force-push.
|
|
20936
21002
|
- If you drop or change any part of what the goal asked for, even for a good reason, record each one
|
|
20937
21003
|
with \`mcp__relai__update_task_status\` metadata \`deviations: [{ "item": "<what the goal asked>",
|
|
@@ -20948,7 +21014,9 @@ Find the default branch with \`git remote show origin\`.
|
|
|
20948
21014
|
on deviations in the approval gate.
|
|
20949
21015
|
|
|
20950
21016
|
**orderRole "merge"**:
|
|
20951
|
-
1. \`gh pr ready <prUrl>\`, then \`gh pr checks <prUrl> --watch --fail-fast\`.
|
|
21017
|
+
1. \`gh pr ready <prUrl>\`, then \`gh pr checks <prUrl> --watch --fail-fast\`. If the PR has no checks
|
|
21018
|
+
(the repo has no CI), check out the PR head and run the repo's own lint, typecheck and test scripts
|
|
21019
|
+
from its package manifest instead, and treat a failure there as a failed check.
|
|
20952
21020
|
Before merging, replace the PR body with a run report built from
|
|
20953
21021
|
\`mcp__relai__list_all_tasks\` filtered to the order's Epic: the feature, the workflow
|
|
20954
21022
|
(planning, build, gates, merge), each task with its assignee, status, and created and
|
package/dist/event-worker.js
CHANGED
|
@@ -35,6 +35,14 @@ var BASE_TASK_LOOP = (agentId, repoPath) => `You are an AI worker agent (ID: ${a
|
|
|
35
35
|
human. If you need the answer before you can continue, block the task with
|
|
36
36
|
\`blockedThreadId\` set to the thread the DM returned; you will be resumed when they answer.
|
|
37
37
|
|
|
38
|
+
**A blocker travels up the chain.** When another agent's task blocks, the repo's orchestrator
|
|
39
|
+
and the planner of that task's goal are told, as well as the owner. If that is you, read the
|
|
40
|
+
question on its \`blockedThreadId\`. When the plan, the goal, its issue or its PR already answers
|
|
41
|
+
it, reply there with the answer and where it comes from. As the planner, if the block shows the
|
|
42
|
+
plan is wrong (a missing dependency, a task too big), fix the plan. Never answer for the owner on
|
|
43
|
+
deletes, scope changes, approvals or publishing; those wait for the owner or their delegate.
|
|
44
|
+
Otherwise do nothing: the owner has already been told.
|
|
45
|
+
|
|
38
46
|
2. Call \`mcp__relai__session_start\` for orientation. It is an **index, not an archive**: lists are
|
|
39
47
|
capped and long bodies are clipped. Anything marked \`truncated: true\`, and anything named under
|
|
40
48
|
\`notShown\`, is a pointer: fetch the real thing with the tool it names before you rely on it,
|
|
@@ -281,9 +289,11 @@ Find the default branch with \`git remote show origin\`.
|
|
|
281
289
|
issue as the spec; the order's \`feature\` text, when it says more than "Resolve the GitHub issue",
|
|
282
290
|
narrows or adds to it. Put \`Closes #<n>\` (the issue number) in the PR body so the merge closes it.
|
|
283
291
|
2. Create the branch and PR:
|
|
284
|
-
\`git fetch origin && git checkout
|
|
285
|
-
\`git commit --allow-empty -m "Start order <orderId>"\`, \`git push
|
|
292
|
+
\`git fetch origin && git checkout --detach origin/<default>\`,
|
|
293
|
+
\`git commit --allow-empty -m "Start order <orderId>"\`, \`git push origin HEAD:refs/heads/order/<orderId>\`,
|
|
286
294
|
then \`gh pr create --draft --base <default> --head order/<orderId> --title "<feature>" --body "Order <orderId>"\`.
|
|
295
|
+
Work detached and never check out \`order/<orderId>\` as a local branch: every agent's worktree
|
|
296
|
+
shares one repository, and git lets only one worktree hold a branch.
|
|
287
297
|
Record both with \`mcp__relai__update_order\` (\`branch\`, \`prUrl\`).
|
|
288
298
|
3. Build tasks: \`mcp__relai__create_task\` for each piece of work, with \`epicId\` = the order's
|
|
289
299
|
\`epicId\`, \`assignedTo: "@auto"\`, and
|
|
@@ -311,6 +321,62 @@ Find the default branch with \`git remote show origin\`.
|
|
|
311
321
|
Write it to a file and run \`gh pr edit <prUrl> --body-file <file>\`. Post the same plan on
|
|
312
322
|
the planning task's thread and complete it.
|
|
313
323
|
|
|
324
|
+
**Review goals** (the order's \`kind\` is \`"review"\`; the planning task carries
|
|
325
|
+
\`metadata.orderKind: "review"\`): the goal is one review posted on the existing pull request at the
|
|
326
|
+
order's \`prUrl\`. There is no order branch, no draft PR and no merge, so skip steps 2 to 6 above.
|
|
327
|
+
Nobody pushes to the PR's branch, approves it, or requests changes on it.
|
|
328
|
+
1. As the planner, read the PR with \`gh pr view <prUrl>\` and \`gh pr diff <prUrl>\`. Pick the
|
|
329
|
+
angles it needs: correctness, security, simplicity, tests and consistency with the codebase for a
|
|
330
|
+
real change; correctness and consistency alone for a small, low-risk one (docs, tests, under about
|
|
331
|
+
150 changed lines with no auth, input handling, secrets, money or migrations).
|
|
332
|
+
2. One task per angle, \`epicId\` = the order's \`epicId\`,
|
|
333
|
+
\`metadata: { orderId, orderRole: "review", angle: "<angle>", prUrl }\`. Spread the angles
|
|
334
|
+
across vendors: assign each to a different agent from \`mcp__relai__list_agents\`, preferring a
|
|
335
|
+
different \`workerType\` from the agents already given one, and reuse agents only when there are
|
|
336
|
+
more angles than agents. Each description names the angle, the PR, what that angle hunts for, and
|
|
337
|
+
the reporting format below.
|
|
338
|
+
3. One lead task, \`blockedBy\` every angle task, assigned to yourself, with
|
|
339
|
+
\`metadata: { orderId, orderRole: "review_lead", prUrl }\`.
|
|
340
|
+
4. When acceptance includes \`human_approval\`, add a gate task blocked by the lead
|
|
341
|
+
(\`metadata: { orderId, orderRole: "gate" }\`, \`verifyKind: "human_approval"\`) and a post task
|
|
342
|
+
blocked by the gate (\`metadata: { orderId, orderRole: "post_review", prUrl }\`). Without it,
|
|
343
|
+
the lead posts the review itself.
|
|
344
|
+
5. If the order has \`relatedRepos\`, copy them into every angle and lead task's metadata and name them in
|
|
345
|
+
each description, so reviewers check the contracts this PR depends on in those repos.
|
|
346
|
+
6. Post the task list on the planning task's thread and complete it.
|
|
347
|
+
|
|
348
|
+
**orderRole "review"** (one angle of a review goal):
|
|
349
|
+
- Read the diff and as much surrounding code as you need. To run anything, check out the PR head
|
|
350
|
+
detached: \`git fetch origin pull/<n>/head && git checkout --detach FETCH_HEAD\`. Never push, never
|
|
351
|
+
comment on the PR, never edit the repo's history.
|
|
352
|
+
- Verify by running code where you can. Report your 3 to 5 best-evidenced findings for your angle, most
|
|
353
|
+
severe first, each with severity (blocker, high, medium, low), file:line, and a concrete failing
|
|
354
|
+
input or scenario. "No findings" is a valid report. A missing code comment is not a finding.
|
|
355
|
+
- When the task names \`relatedRepos\`, read them for any contract this change depends on (an endpoint it
|
|
356
|
+
calls, a helper it imports, a config value it reads). Read only, outside your worktree: a shallow
|
|
357
|
+
clone into a temp directory (\`gh repo clone <url> <tmp dir> -- --depth 1\`) or one file at a time with
|
|
358
|
+
\`gh api repos/<owner>/<repo>/contents/<path>\`. Never push, branch, comment or open anything there.
|
|
359
|
+
A finding that rests on a related repo cites the file and line there. If you could not read the
|
|
360
|
+
repo, mark that finding UNPROVEN and say why rather than guessing what the other side does.
|
|
361
|
+
- Post the report with \`mcp__relai__add_task_comment\` on this task, then complete it.
|
|
362
|
+
|
|
363
|
+
**orderRole "review_lead"**:
|
|
364
|
+
- Read every angle task's report with \`mcp__relai__get_task_comments\`. Merge duplicates, drop
|
|
365
|
+
findings you cannot reproduce or whose premise is wrong, and rank what is left. Keep an UNPROVEN mark
|
|
366
|
+
on any finding about a related repo nobody could read. Severity sets the
|
|
367
|
+
verdict: any blocker or high means changes are needed; otherwise it is safe to merge with the
|
|
368
|
+
noted follow-ups.
|
|
369
|
+
- Write one review: the verdict in the first line, then the findings, each with file:line, the
|
|
370
|
+
failure and the fix you would ask for, then which angles ran, each with its agent's name and vendor
|
|
371
|
+
(\`workerType\` from \`mcp__relai__list_agents\`), and which related repos were read. Keep it short.
|
|
372
|
+
- Without a \`human_approval\` gate, post it with \`gh pr review <prUrl> --comment --body-file <file>\`
|
|
373
|
+
and put the review URL on the task's thread. With a gate, post the review as a comment on this task
|
|
374
|
+
for the owner to approve, and do not touch the PR. Then complete.
|
|
375
|
+
|
|
376
|
+
**orderRole "post_review"**: once the gate is approved, post the lead's review comment from the
|
|
377
|
+
lead task's thread with \`gh pr review <prUrl> --comment --body-file <file>\`, put the review URL on
|
|
378
|
+
this task's thread, and complete.
|
|
379
|
+
|
|
314
380
|
**orderRole "plan_review"** (assigned to the planner, reviewed by another agent):
|
|
315
381
|
- After the task graph is written, complete each plan review task. That hands the plan to its
|
|
316
382
|
reviewer. Every build task waits until all plan reviews are approved.
|
|
@@ -321,9 +387,9 @@ Find the default branch with \`git remote show origin\`.
|
|
|
321
387
|
reject with exactly what to change.
|
|
322
388
|
|
|
323
389
|
**orderRole "build"**:
|
|
324
|
-
- \`git fetch origin && git checkout
|
|
325
|
-
|
|
326
|
-
- Push with \`git
|
|
390
|
+
- \`git fetch origin && git checkout --detach origin/order/<orderId>\`, then implement, test and commit
|
|
391
|
+
on the detached head. Do not create a local branch, another branch on the remote, or a PR.
|
|
392
|
+
- Push with \`git fetch origin && git rebase origin/order/<orderId> && git push origin HEAD:order/<orderId>\`,
|
|
327
393
|
repeating up to 5 times if the push is rejected. Never force-push.
|
|
328
394
|
- If you drop or change any part of what the goal asked for, even for a good reason, record each one
|
|
329
395
|
with \`mcp__relai__update_task_status\` metadata \`deviations: [{ "item": "<what the goal asked>",
|
|
@@ -340,7 +406,9 @@ Find the default branch with \`git remote show origin\`.
|
|
|
340
406
|
on deviations in the approval gate.
|
|
341
407
|
|
|
342
408
|
**orderRole "merge"**:
|
|
343
|
-
1. \`gh pr ready <prUrl>\`, then \`gh pr checks <prUrl> --watch --fail-fast\`.
|
|
409
|
+
1. \`gh pr ready <prUrl>\`, then \`gh pr checks <prUrl> --watch --fail-fast\`. If the PR has no checks
|
|
410
|
+
(the repo has no CI), check out the PR head and run the repo's own lint, typecheck and test scripts
|
|
411
|
+
from its package manifest instead, and treat a failure there as a failed check.
|
|
344
412
|
Before merging, replace the PR body with a run report built from
|
|
345
413
|
\`mcp__relai__list_all_tasks\` filtered to the order's Epic: the feature, the workflow
|
|
346
414
|
(planning, build, gates, merge), each task with its assignee, status, and created and
|
package/dist/mcp.js
CHANGED
|
@@ -12538,19 +12538,23 @@ function buildCreateOrderTool(client, repoId, opts) {
|
|
|
12538
12538
|
repoId: external_exports.string().optional().describe(opts.ownerScoped ? "Repo to file the order in: any repo your owner owns. Defaults to your home repo." : "Repo to file the order in. Defaults to this agent's home repo."),
|
|
12539
12539
|
feature: external_exports.string().min(1).optional().describe("What to build, in the requester's words. Optional when issueUrl is given."),
|
|
12540
12540
|
issueUrl: external_exports.string().optional().describe("A GitHub issue in this repo to build from (https://github.com/<owner>/<repo>/issues/<n>). The planner reads it, and the merge closes it."),
|
|
12541
|
+
reviewPrUrl: external_exports.string().optional().describe('Review this pull request in the repo instead of building something (https://github.com/<owner>/<repo>/pull/<n>). Agents on different vendors each review one angle, a lead merges their findings, and one review is posted on the PR. No gate by default; pass acceptance ["human_approval"] to approve the review before it is posted. feature, when given, narrows what to look at.'),
|
|
12542
|
+
relatedRepos: external_exports.array(external_exports.string()).max(5).optional().describe("Review goals only: ids of other repos you own (see list_repos) whose contracts this PR depends on. Reviewers read them, never write to them, and mark findings about one they could not read as unproven."),
|
|
12541
12543
|
planReviewers: external_exports.number().int().min(0).max(3).optional().describe("How many other agents must approve the plan before building starts (0 to 3). Reviewers are picked by the API, preferring reviewer agents on another vendor."),
|
|
12542
12544
|
pairBuilds: external_exports.boolean().optional().describe("Pair every build task with a reviewer on a different vendor: each build carries its own review gate, and the builder is never on the reviewer's vendor."),
|
|
12543
12545
|
title: external_exports.string().min(1).max(120).optional().describe("A short name for the goal. The planner writes one when omitted."),
|
|
12544
|
-
acceptance: external_exports.array(external_exports.enum(["ci_passed", "human_approval", "reviewer_agent"])).optional().describe("Gates that must all pass. Defaults to human_approval."),
|
|
12546
|
+
acceptance: external_exports.array(external_exports.enum(["ci_passed", "human_approval", "reviewer_agent"])).optional().describe("Gates that must all pass. Defaults to human_approval, or none for a review."),
|
|
12545
12547
|
budget: external_exports.record(external_exports.unknown()).optional().describe("Optional ceilings. Stored only; not enforced.")
|
|
12546
12548
|
}),
|
|
12547
12549
|
handler: async (input) => {
|
|
12548
|
-
if (!input.feature && !input.issueUrl) return mcpFail("create_order needs feature or
|
|
12550
|
+
if (!input.feature && !input.issueUrl && !input.reviewPrUrl) return mcpFail("create_order needs feature, issueUrl or reviewPrUrl");
|
|
12549
12551
|
try {
|
|
12550
12552
|
const created = await client.createOrder({
|
|
12551
12553
|
repoId: targetRepo(input),
|
|
12552
12554
|
...input.feature ? { feature: input.feature } : {},
|
|
12553
12555
|
...input.issueUrl ? { issueUrl: input.issueUrl } : {},
|
|
12556
|
+
...input.reviewPrUrl ? { kind: "review", prUrl: input.reviewPrUrl } : {},
|
|
12557
|
+
...input.relatedRepos?.length ? { relatedRepos: input.relatedRepos } : {},
|
|
12554
12558
|
...input.planReviewers ? { planReviewers: input.planReviewers } : {},
|
|
12555
12559
|
...input.pairBuilds ? { pairBuilds: true } : {},
|
|
12556
12560
|
...input.title ? { title: input.title } : {},
|
|
@@ -13238,21 +13242,42 @@ ${version.body}`
|
|
|
13238
13242
|
] : []
|
|
13239
13243
|
];
|
|
13240
13244
|
}
|
|
13245
|
+
var ATTENTION_STATUSES = "blocked,pending_verification,proposed";
|
|
13246
|
+
function attentionMaxAgeDays() {
|
|
13247
|
+
const n = Number(process.env.ATTENTION_MAX_AGE_DAYS);
|
|
13248
|
+
return Number.isFinite(n) && n > 0 ? n : 7;
|
|
13249
|
+
}
|
|
13250
|
+
var attentionWindowSchema = {
|
|
13251
|
+
includeStale: external_exports.boolean().optional().describe("Include items untouched for longer than maxAgeDays. Off by default so new asks lead."),
|
|
13252
|
+
maxAgeDays: external_exports.number().positive().optional().describe("Hide items untouched for longer than this many days (default 7).")
|
|
13253
|
+
};
|
|
13254
|
+
function attentionCutoff(input) {
|
|
13255
|
+
if (input.includeStale) return void 0;
|
|
13256
|
+
return new Date(Date.now() - (input.maxAgeDays ?? attentionMaxAgeDays()) * 864e5).toISOString();
|
|
13257
|
+
}
|
|
13258
|
+
async function staleAttentionCount(client, cutoff) {
|
|
13259
|
+
if (!cutoff) return 0;
|
|
13260
|
+
const { meta } = await client.getTasksPage({ status: ATTENTION_STATUSES, updatedBefore: cutoff, limit: 1, clip: true });
|
|
13261
|
+
return meta?.total ?? 0;
|
|
13262
|
+
}
|
|
13241
13263
|
function buildGodCoordinationTools(client) {
|
|
13242
13264
|
return [
|
|
13243
13265
|
{
|
|
13244
13266
|
name: "list_attention",
|
|
13245
|
-
description: "List what needs attention across ALL your owner's repos: tasks that are 'blocked' (a worker is waiting), 'pending_verification' (awaiting a review decision), or 'proposed' (a worker's task awaiting commit), plus idle workers that cannot take the ready work that is sitting there (idle_unroutable \u2014 derived now, not from the event log). Each task carries its repoId. A blocked task with metadata.blockedThreadId resumes when you answer with send_message on that thread, as if the owner had.
|
|
13246
|
-
inputSchema: external_exports.object(
|
|
13247
|
-
handler: async () => {
|
|
13267
|
+
description: "List what needs attention across ALL your owner's repos: tasks that are 'blocked' (a worker is waiting), 'pending_verification' (awaiting a review decision), or 'proposed' (a worker's task awaiting commit), plus idle workers that cannot take the ready work that is sitting there (idle_unroutable \u2014 derived now, not from the event log). Each task carries its repoId. A blocked task with metadata.blockedThreadId resumes when you answer with send_message (type decision) on that thread, as if the owner had, when the owner has given you a decide delegation for that repo; the task records clearedBy. Answer only reversible, branch-level confirmations yourself (editing, pushing or deleting files on an order branch, choosing between plan options). Merges into a default branch, deploys, deletes outside an order branch, and anything touching credentials or money go to the owner. A blocked task without blockedThreadId (stalled or overflowed work) resumes the same way when you post add_task_comment (type decision) on it; say whether to split, retry or reassign. Your own blocked task never resumes on your answer. An idle_unroutable item names the agent and why each task is ineligible (domain, specialization, review_gate, for-human, product-decision, pinned, blockedBy). Capped and clipped, newest first; read one in full with get_task.",
|
|
13268
|
+
inputSchema: external_exports.object(attentionWindowSchema),
|
|
13269
|
+
handler: async (input) => {
|
|
13270
|
+
const cutoff = attentionCutoff(input);
|
|
13248
13271
|
const [{ data, meta }, idleUnroutable] = await Promise.all([
|
|
13249
13272
|
client.getTasksPage({
|
|
13250
|
-
status:
|
|
13273
|
+
status: ATTENTION_STATUSES,
|
|
13251
13274
|
limit: listTasksLimit(),
|
|
13252
|
-
clip: true
|
|
13275
|
+
clip: true,
|
|
13276
|
+
...cutoff ? { updatedAfter: cutoff } : {}
|
|
13253
13277
|
}),
|
|
13254
13278
|
client.getIdleUnroutable()
|
|
13255
13279
|
]);
|
|
13280
|
+
const staleCount = await staleAttentionCount(client, cutoff);
|
|
13256
13281
|
const tasks = data ?? [];
|
|
13257
13282
|
const idle = idleUnroutable ?? [];
|
|
13258
13283
|
const total = meta?.total ?? tasks.length;
|
|
@@ -13260,11 +13285,12 @@ function buildGodCoordinationTools(client) {
|
|
|
13260
13285
|
return {
|
|
13261
13286
|
content: [{
|
|
13262
13287
|
type: "text",
|
|
13263
|
-
text: tasks.length === 0 && idle.length === 0 ? "Nothing needs attention across your repos right now." : JSON.stringify({
|
|
13288
|
+
text: tasks.length === 0 && idle.length === 0 && staleCount === 0 ? "Nothing needs attention across your repos right now." : JSON.stringify({
|
|
13264
13289
|
tasks,
|
|
13265
13290
|
taskCount: total,
|
|
13266
13291
|
...idle.length > 0 ? { idleUnroutable: idle } : {},
|
|
13267
13292
|
...notShown ? { notShown } : {},
|
|
13293
|
+
...staleCount > 0 ? { staleCount, stale: `${staleCount} older items hidden; pass includeStale: true to see them, and cancel or archive what is dead.` } : {},
|
|
13268
13294
|
peerBoundary: PEER_BOUNDARY
|
|
13269
13295
|
}, null, 2)
|
|
13270
13296
|
}]
|
|
@@ -13536,19 +13562,22 @@ function buildOperatorTools(client, ownerId) {
|
|
|
13536
13562
|
{
|
|
13537
13563
|
name: "list_attention",
|
|
13538
13564
|
description: "List everything across ALL your projects that needs you right now: tasks that are 'blocked' (a worker is waiting on your input), 'pending_verification' (awaiting a review decision), or 'proposed' (a worker's task awaiting your commit), plus idle workers that cannot take the ready work sitting there (idle_unroutable). Call this first to see what to act on. Each task carries its repoId and, for blocked tasks, metadata.blockedThreadId \u2014 the thread to post a reply on (via reply_human) to resume the worker. An idle_unroutable item names the agent and why each task is ineligible.",
|
|
13539
|
-
inputSchema: external_exports.object(
|
|
13540
|
-
handler: async () => {
|
|
13541
|
-
const
|
|
13542
|
-
|
|
13543
|
-
client.
|
|
13565
|
+
inputSchema: external_exports.object(attentionWindowSchema),
|
|
13566
|
+
handler: async (input) => {
|
|
13567
|
+
const cutoff = attentionCutoff(input);
|
|
13568
|
+
const [tasks, idleUnroutable, staleCount] = await Promise.all([
|
|
13569
|
+
client.getTasks({ status: ATTENTION_STATUSES, ...cutoff ? { updatedAfter: cutoff } : {} }),
|
|
13570
|
+
client.getIdleUnroutable(),
|
|
13571
|
+
staleAttentionCount(client, cutoff)
|
|
13544
13572
|
]);
|
|
13545
13573
|
const idle = idleUnroutable ?? [];
|
|
13546
13574
|
return {
|
|
13547
13575
|
content: [{
|
|
13548
13576
|
type: "text",
|
|
13549
|
-
text: tasks.length === 0 && idle.length === 0 ? "Nothing needs your attention across your projects right now." : JSON.stringify({
|
|
13577
|
+
text: tasks.length === 0 && idle.length === 0 && staleCount === 0 ? "Nothing needs your attention across your projects right now." : JSON.stringify({
|
|
13550
13578
|
tasks,
|
|
13551
|
-
...idle.length > 0 ? { idleUnroutable: idle } : {}
|
|
13579
|
+
...idle.length > 0 ? { idleUnroutable: idle } : {},
|
|
13580
|
+
...staleCount > 0 ? { staleCount, stale: `${staleCount} older items hidden; pass includeStale: true to see them, and cancel or archive what is dead.` } : {}
|
|
13552
13581
|
}, null, 2)
|
|
13553
13582
|
}]
|
|
13554
13583
|
};
|
|
@@ -13820,7 +13849,8 @@ function attentionStateOf(task) {
|
|
|
13820
13849
|
function describe(task, state) {
|
|
13821
13850
|
const title = (task.title ?? task.id).slice(0, 80);
|
|
13822
13851
|
const where = task.repoId ? ` [${task.repoId}]` : "";
|
|
13823
|
-
const
|
|
13852
|
+
const replyOn = typeof task.metadata?.blockedThreadId === "string" ? task.metadata.blockedThreadId : task.threadId;
|
|
13853
|
+
const thread = state !== "blocked" ? "" : replyOn ? ` Reply on thread ${replyOn} to unblock it.` : ` Answer with add_task_comment on ${task.id} to unblock it.`;
|
|
13824
13854
|
const next = state === "proposed" ? " Use commit_proposal." : state === "pending_verification" ? " Use review_task." : state === "stalled" ? " Nobody is coming; reassign or cancel it." : "";
|
|
13825
13855
|
return `relai: "${title}" is ${LABEL[state]}${where} (${task.id}).${thread}${next}`;
|
|
13826
13856
|
}
|