@sjawhar/pi-envoy 9.1.2 → 9.2.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/dist/dispatch.js
CHANGED
|
@@ -13557,6 +13557,7 @@ function serviceSubjectLabel(subject) {
|
|
|
13557
13557
|
}
|
|
13558
13558
|
return subject;
|
|
13559
13559
|
}
|
|
13560
|
+
var MAX_ISSUE_BLOCKERS = 20;
|
|
13560
13561
|
var ISSUE_TITLE_MAX = 1000;
|
|
13561
13562
|
var MAX_ISSUE_PAGE_LIMIT = 250;
|
|
13562
13563
|
var DEFAULT_ISSUE_PAGE_LIMIT = 50;
|
|
@@ -14023,6 +14024,7 @@ var dispatchToolSpecs = [
|
|
|
14023
14024
|
project: z2.string().describe("Project key for the new issue."),
|
|
14024
14025
|
title: z2.string({ max: ISSUE_TITLE_MAX }).describe("Concise issue title, at most 1,000 characters."),
|
|
14025
14026
|
parent: z2.string().describe("Optional parent issue.").optional(),
|
|
14027
|
+
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Issue keys in the same project this issue waits on. Dispatch refuses a dependency cycle.").optional(),
|
|
14026
14028
|
external: z2.string().describe("Optional external issue reference.").optional(),
|
|
14027
14029
|
force: z2.boolean().describe("Create even though POSSIBLE_DUPLICATE listed similar issues; pass it only after reading them.").optional(),
|
|
14028
14030
|
spec: z2.string().describe(`Optional initial primary-document markdown. ${SPEC_WRITING_POINTER}`).optional(),
|
|
@@ -14039,7 +14041,7 @@ var dispatchToolSpecs = [
|
|
|
14039
14041
|
status: "done",
|
|
14040
14042
|
reason: "Shipped in owner/repo#7; verified on the production dashboard."
|
|
14041
14043
|
},
|
|
14042
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, or attach it to architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "and a reopening status (any status but done); everything else, priority included, waits " + "for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
14044
|
+
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, or attach it to " + "architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "and a reopening status (any status but done); everything else, priority included, waits " + "for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
14043
14045
|
arguments: (z2) => ({
|
|
14044
14046
|
issue: z2.string().describe(ISSUE_REFERENCE),
|
|
14045
14047
|
status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
@@ -14050,15 +14052,16 @@ var dispatchToolSpecs = [
|
|
|
14050
14052
|
external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
|
|
14051
14053
|
route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
14052
14054
|
parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
14055
|
+
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
|
|
14053
14056
|
components: componentsArgument(z2).optional()
|
|
14054
14057
|
}),
|
|
14055
14058
|
validation: {
|
|
14056
14059
|
check: (value) => {
|
|
14057
14060
|
const input = value;
|
|
14058
14061
|
const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
|
|
14059
|
-
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || typeof input.components === "object" && input.components !== null);
|
|
14062
|
+
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
|
|
14060
14063
|
},
|
|
14061
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
14064
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
14062
14065
|
},
|
|
14063
14066
|
strict: true
|
|
14064
14067
|
},
|
|
@@ -17496,11 +17499,13 @@ async function executeDispatchTool(input) {
|
|
|
17496
17499
|
const assignee = optionalString(args, "assignee");
|
|
17497
17500
|
const components = optionalComponents(args, "components");
|
|
17498
17501
|
const labels = args.labels;
|
|
17502
|
+
const blockedBy = args.blocked_by;
|
|
17499
17503
|
try {
|
|
17500
17504
|
const created = await client.issue({
|
|
17501
17505
|
project,
|
|
17502
17506
|
title,
|
|
17503
17507
|
...parent === undefined ? {} : { parent },
|
|
17508
|
+
...Array.isArray(blockedBy) ? { blocked_by: blockedBy } : {},
|
|
17504
17509
|
...external2 === undefined ? {} : { external: external2 },
|
|
17505
17510
|
...force === undefined ? {} : { force },
|
|
17506
17511
|
...spec === undefined ? {} : { spec },
|
|
@@ -17558,6 +17563,7 @@ async function executeDispatchTool(input) {
|
|
|
17558
17563
|
const components = optionalComponents(args, "components");
|
|
17559
17564
|
const priority = optionalPriority(args, "priority");
|
|
17560
17565
|
const labels = Array.isArray(args.labels) ? args.labels : undefined;
|
|
17566
|
+
const blockedBy = Array.isArray(args.blocked_by) ? args.blocked_by : undefined;
|
|
17561
17567
|
const requestedLinks = Array.isArray(args.external_links) ? [...new Set(args.external_links)] : undefined;
|
|
17562
17568
|
let before;
|
|
17563
17569
|
try {
|
|
@@ -17591,6 +17597,7 @@ async function executeDispatchTool(input) {
|
|
|
17591
17597
|
...priority === undefined ? {} : { priority },
|
|
17592
17598
|
...route === undefined ? {} : { route },
|
|
17593
17599
|
...parent === undefined ? {} : { parent: parent === "" ? null : parent },
|
|
17600
|
+
...blockedBy === undefined ? {} : { blocked_by: blockedBy },
|
|
17594
17601
|
...components === undefined ? {} : { components },
|
|
17595
17602
|
...requestedLinks === undefined ? {} : { external_links: [...before.external_links, ...newLinks.map((url2) => ({ url: url2 }))] },
|
|
17596
17603
|
actor
|
|
@@ -17618,6 +17625,9 @@ async function executeDispatchTool(input) {
|
|
|
17618
17625
|
],
|
|
17619
17626
|
...route === undefined ? [] : [after.route === null ? "route cleared" : `route ${after.route}`],
|
|
17620
17627
|
...parent === undefined ? [] : [after.parent === null ? "parent cleared" : `parent -> ${after.parent}`],
|
|
17628
|
+
...blockedBy === undefined ? [] : [
|
|
17629
|
+
after.blocked_by.length === 0 ? "blocked_by cleared" : `blocked by ${after.blocked_by.join(", ")}`
|
|
17630
|
+
],
|
|
17621
17631
|
...components === undefined ? [] : [componentsChange(components, after.components)]
|
|
17622
17632
|
];
|
|
17623
17633
|
const adviceLines = renderAdvice(input.tool, after.key, after.advice, {
|
package/dist/envoy.js
CHANGED
|
@@ -29647,6 +29647,7 @@ function date4(params) {
|
|
|
29647
29647
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
29648
29648
|
config(en_default());
|
|
29649
29649
|
// ../contracts/src/dispatch-api.ts
|
|
29650
|
+
var MAX_ISSUE_BLOCKERS = 20;
|
|
29650
29651
|
var ISSUE_TITLE_MAX = 1000;
|
|
29651
29652
|
var MAX_ISSUE_PAGE_LIMIT = 250;
|
|
29652
29653
|
var DEFAULT_ISSUE_PAGE_LIMIT = 50;
|
|
@@ -30010,6 +30011,7 @@ var dispatchToolSpecs = [
|
|
|
30010
30011
|
project: z2.string().describe("Project key for the new issue."),
|
|
30011
30012
|
title: z2.string({ max: ISSUE_TITLE_MAX }).describe("Concise issue title, at most 1,000 characters."),
|
|
30012
30013
|
parent: z2.string().describe("Optional parent issue.").optional(),
|
|
30014
|
+
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Issue keys in the same project this issue waits on. Dispatch refuses a dependency cycle.").optional(),
|
|
30013
30015
|
external: z2.string().describe("Optional external issue reference.").optional(),
|
|
30014
30016
|
force: z2.boolean().describe("Create even though POSSIBLE_DUPLICATE listed similar issues; pass it only after reading them.").optional(),
|
|
30015
30017
|
spec: z2.string().describe(`Optional initial primary-document markdown. ${SPEC_WRITING_POINTER}`).optional(),
|
|
@@ -30026,7 +30028,7 @@ var dispatchToolSpecs = [
|
|
|
30026
30028
|
status: "done",
|
|
30027
30029
|
reason: "Shipped in owner/repo#7; verified on the production dashboard."
|
|
30028
30030
|
},
|
|
30029
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, or attach it to architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "and a reopening status (any status but done); everything else, priority included, waits " + "for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
30031
|
+
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, or attach it to " + "architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "and a reopening status (any status but done); everything else, priority included, waits " + "for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
30030
30032
|
arguments: (z2) => ({
|
|
30031
30033
|
issue: z2.string().describe(ISSUE_REFERENCE),
|
|
30032
30034
|
status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
@@ -30037,15 +30039,16 @@ var dispatchToolSpecs = [
|
|
|
30037
30039
|
external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
|
|
30038
30040
|
route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
30039
30041
|
parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
30042
|
+
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
|
|
30040
30043
|
components: componentsArgument(z2).optional()
|
|
30041
30044
|
}),
|
|
30042
30045
|
validation: {
|
|
30043
30046
|
check: (value) => {
|
|
30044
30047
|
const input = value;
|
|
30045
30048
|
const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
|
|
30046
|
-
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || typeof input.components === "object" && input.components !== null);
|
|
30049
|
+
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
|
|
30047
30050
|
},
|
|
30048
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
30051
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
30049
30052
|
},
|
|
30050
30053
|
strict: true
|
|
30051
30054
|
},
|
|
@@ -85,7 +85,7 @@ issues you own as well as the root. An issue left at `triage` while work is unde
|
|
|
85
85
|
Waiting for the deploy lane is not a status and is never announced.
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
# PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL), route, parent
|
|
88
|
+
# PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL), route, parent, blocked_by
|
|
89
89
|
dispatch issue-update --issue PROJ-175 --status testing
|
|
90
90
|
dispatch issue-update --issue PROJ-175 --status done --reason 'Shipped in owner/repo#7; verified on the production dashboard.'
|
|
91
91
|
dispatch issue-update --issue PROJ-175 --priority 1 # 0–3; see Priority is yours to set
|