@sjawhar/pi-legion-envoy 1.62.0 → 1.64.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/envoy.js +14 -4
- package/dist/legion.js +5 -4
- package/dist/skills/dispatch/SKILL.md +19 -4
- package/package.json +1 -1
package/dist/envoy.js
CHANGED
|
@@ -30031,12 +30031,13 @@ var dispatchToolSpecs = [
|
|
|
30031
30031
|
{
|
|
30032
30032
|
name: "dispatch_issue_update",
|
|
30033
30033
|
example: { issue: "DSP-1", status: "in_progress" },
|
|
30034
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, link a URL
|
|
30034
|
+
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. 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}`,
|
|
30035
30035
|
arguments: (z) => ({
|
|
30036
30036
|
issue: z.string().describe(ISSUE_REFERENCE),
|
|
30037
30037
|
status: z.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
30038
30038
|
title: z.string({ min: 1 }).describe("Replacement title.").optional(),
|
|
30039
30039
|
labels: z.array(z.string({ min: 1, max: 40 }), { max: 20 }).describe("Replacement label set, at most 20 labels of up to 40 characters; replaces every existing label.").optional(),
|
|
30040
|
+
priority: z.number({ int: true, min: 0, max: 3 }).nullable().optional().describe("Coarse priority: 0 is P0 (highest) through 3 is P3 (lowest); null clears it."),
|
|
30040
30041
|
external_links: z.array(z.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
|
|
30041
30042
|
route: z.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
30042
30043
|
parent: z.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
@@ -30045,9 +30046,9 @@ var dispatchToolSpecs = [
|
|
|
30045
30046
|
validation: {
|
|
30046
30047
|
check: (value) => {
|
|
30047
30048
|
const input = value;
|
|
30048
|
-
return typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || typeof input.components === "object" && input.components !== null;
|
|
30049
|
+
return 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
30050
|
},
|
|
30050
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, external_links, route, parent, or components."
|
|
30051
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, or components."
|
|
30051
30052
|
},
|
|
30052
30053
|
strict: true
|
|
30053
30054
|
},
|
|
@@ -32756,6 +32757,12 @@ function optionalNumber(args, name) {
|
|
|
32756
32757
|
const value = args[name];
|
|
32757
32758
|
return typeof value === "number" ? value : undefined;
|
|
32758
32759
|
}
|
|
32760
|
+
function optionalPriority(args, name) {
|
|
32761
|
+
const value = args[name];
|
|
32762
|
+
if (value === null)
|
|
32763
|
+
return null;
|
|
32764
|
+
return typeof value === "number" ? value : undefined;
|
|
32765
|
+
}
|
|
32759
32766
|
function optionalComponents(args, name) {
|
|
32760
32767
|
const value = args[name];
|
|
32761
32768
|
if (typeof value !== "object" || value === null)
|
|
@@ -33600,7 +33607,7 @@ async function executeDispatchTool(input) {
|
|
|
33600
33607
|
const external = optionalString(args, "external");
|
|
33601
33608
|
const force = optionalBoolean(args, "force");
|
|
33602
33609
|
const spec = optionalString(args, "spec");
|
|
33603
|
-
const priority =
|
|
33610
|
+
const priority = optionalPriority(args, "priority");
|
|
33604
33611
|
const assignee = optionalString(args, "assignee");
|
|
33605
33612
|
const components = optionalComponents(args, "components");
|
|
33606
33613
|
const labels = args.labels;
|
|
@@ -33662,6 +33669,7 @@ async function executeDispatchTool(input) {
|
|
|
33662
33669
|
const route = optionalString(args, "route");
|
|
33663
33670
|
const parent = optionalString(args, "parent");
|
|
33664
33671
|
const components = optionalComponents(args, "components");
|
|
33672
|
+
const priority = optionalPriority(args, "priority");
|
|
33665
33673
|
const labels = Array.isArray(args.labels) ? args.labels : undefined;
|
|
33666
33674
|
const requestedLinks = Array.isArray(args.external_links) ? [...new Set(args.external_links)] : undefined;
|
|
33667
33675
|
let newLinks = [];
|
|
@@ -33673,6 +33681,7 @@ async function executeDispatchTool(input) {
|
|
|
33673
33681
|
...status === undefined ? {} : { status },
|
|
33674
33682
|
...title === undefined ? {} : { title },
|
|
33675
33683
|
...labels === undefined ? {} : { labels },
|
|
33684
|
+
...priority === undefined ? {} : { priority },
|
|
33676
33685
|
...route === undefined ? {} : { route },
|
|
33677
33686
|
...parent === undefined ? {} : { parent: parent === "" ? null : parent },
|
|
33678
33687
|
...components === undefined ? {} : { components },
|
|
@@ -33684,6 +33693,7 @@ async function executeDispatchTool(input) {
|
|
|
33684
33693
|
...status === undefined ? [] : [`status ${before.status} -> ${after.status}`],
|
|
33685
33694
|
...title === undefined ? [] : [`title "${after.title}"`],
|
|
33686
33695
|
...labels === undefined ? [] : [after.labels.length === 0 ? "labels cleared" : `labels ${after.labels.join(", ")}`],
|
|
33696
|
+
...priority === undefined ? [] : [after.priority === null ? "priority cleared" : `priority -> P${after.priority}`],
|
|
33687
33697
|
...requestedLinks === undefined ? [] : [
|
|
33688
33698
|
newLinks.length === 0 ? `already linked ${requestedLinks.join(", ")} ${linkCount}` : `linked ${newLinks.join(", ")} ${linkCount}`
|
|
33689
33699
|
],
|
package/dist/legion.js
CHANGED
|
@@ -16144,7 +16144,7 @@ import { logger } from "@oh-my-pi/pi-utils";
|
|
|
16144
16144
|
// package.json
|
|
16145
16145
|
var package_default = {
|
|
16146
16146
|
name: "@sjawhar/pi-legion-envoy",
|
|
16147
|
-
version: "1.
|
|
16147
|
+
version: "1.64.0",
|
|
16148
16148
|
type: "module",
|
|
16149
16149
|
omp: {
|
|
16150
16150
|
extensions: [
|
|
@@ -30103,12 +30103,13 @@ var dispatchToolSpecs = [
|
|
|
30103
30103
|
{
|
|
30104
30104
|
name: "dispatch_issue_update",
|
|
30105
30105
|
example: { issue: "DSP-1", status: "in_progress" },
|
|
30106
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, link a URL
|
|
30106
|
+
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. 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}`,
|
|
30107
30107
|
arguments: (z) => ({
|
|
30108
30108
|
issue: z.string().describe(ISSUE_REFERENCE),
|
|
30109
30109
|
status: z.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
30110
30110
|
title: z.string({ min: 1 }).describe("Replacement title.").optional(),
|
|
30111
30111
|
labels: z.array(z.string({ min: 1, max: 40 }), { max: 20 }).describe("Replacement label set, at most 20 labels of up to 40 characters; replaces every existing label.").optional(),
|
|
30112
|
+
priority: z.number({ int: true, min: 0, max: 3 }).nullable().optional().describe("Coarse priority: 0 is P0 (highest) through 3 is P3 (lowest); null clears it."),
|
|
30112
30113
|
external_links: z.array(z.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
|
|
30113
30114
|
route: z.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
30114
30115
|
parent: z.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
@@ -30117,9 +30118,9 @@ var dispatchToolSpecs = [
|
|
|
30117
30118
|
validation: {
|
|
30118
30119
|
check: (value) => {
|
|
30119
30120
|
const input = value;
|
|
30120
|
-
return typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || typeof input.components === "object" && input.components !== null;
|
|
30121
|
+
return 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;
|
|
30121
30122
|
},
|
|
30122
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, external_links, route, parent, or components."
|
|
30123
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, or components."
|
|
30123
30124
|
},
|
|
30124
30125
|
strict: true
|
|
30125
30126
|
},
|
|
@@ -154,7 +154,7 @@ Architects create newly tracked child work with:
|
|
|
154
154
|
```ts
|
|
155
155
|
dispatch_issue({ project, title, parent?, external?, spec?, force?, labels?: string[], priority?: 0 | 1 | 2 | 3, assignee?: string })
|
|
156
156
|
```
|
|
157
|
-
`labels` are optional initial labels: Dispatch trims them, preserves their case, and removes case-insensitive duplicates.
|
|
157
|
+
`labels` are optional initial labels: Dispatch trims them, preserves their case, and removes case-insensitive duplicates. `priority` is yours on creation too — see [Priority is yours to set](#priority-is-yours-to-set). Set `assignee` (a GitHub login on the sign-in allowlist) only when the human said who owns the work; otherwise the default above applies, so a child inherits its parent's assignee. It returns
|
|
158
158
|
`details` `{ issue }`; creating an issue does not subscribe you to it (see [Following](#following)). Use `dispatch_issue` only to create an issue; never use it to park a question. When `spec` is supplied,
|
|
159
159
|
follow [Writing a spec](#writing-a-spec).
|
|
160
160
|
|
|
@@ -167,16 +167,19 @@ production-like surface, `needs_review` when its pull request is open and waitin
|
|
|
167
167
|
queue, `done` when the change has been driven in production (a merge is not `done`). Move child
|
|
168
168
|
issues you own as well as the root. An issue left at `triage` while work is underway is a defect:
|
|
169
169
|
Sami, 2026-09-15, on the roadmap he could not read — "I'm not even sure what their development
|
|
170
|
-
status is." Waiting for the deploy lane is not a status and is never announced.
|
|
171
|
-
human's: set it on creation only when their intent is clear, and change it only on their word.
|
|
170
|
+
status is." Waiting for the deploy lane is not a status and is never announced.
|
|
172
171
|
|
|
173
172
|
```ts
|
|
174
|
-
// PATCH /api/v1/issues/{key} — status, title, labels, external_links (merged by URL), route, parent
|
|
173
|
+
// PATCH /api/v1/issues/{key} — status, title, labels, priority, external_links (merged by URL), route, parent
|
|
175
174
|
dispatch_issue_update({ issue: "AGENTC-175", status: "testing" })
|
|
175
|
+
dispatch_issue_update({ issue: "AGENTC-175", priority: 1 }) // 0–3; see Priority is yours to set
|
|
176
176
|
dispatch_issue_update({ issue: "AGENTC-175", external_links: ["https://github.com/owner/repo/pull/7"] })
|
|
177
177
|
dispatch_issue_update({ issue: "AGENTC-175", parent: "AGENTC-170" }) // same-project key; "" clears the parent
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
+
The two clears differ: `priority` clears with `null`, while `parent` and `route` clear with `""`.
|
|
181
|
+
Guessing the other one is a refusal either way.
|
|
182
|
+
|
|
180
183
|
Link the pull request that delivers the issue in `external_links` when you open it; the issue page
|
|
181
184
|
renders its state and checks from that link. The call is authenticated with the same bearer as every
|
|
182
185
|
other `dispatch_*` tool: a Legion pane reads it from the `DISPATCH_TOKEN_FILE` path the daemon sets on
|
|
@@ -185,6 +188,18 @@ the pane; an OMP session outside Legion reads `dispatch.token` from `~/.config/o
|
|
|
185
188
|
A write to an issue still in `triage` answers once with `… is still in triage …`; move the status
|
|
186
189
|
when work has started.
|
|
187
190
|
|
|
191
|
+
## Priority is yours to set
|
|
192
|
+
|
|
193
|
+
Priority is the coarse bucket a backlog is read by: `0` is P0, the highest, through `3`, P3, the
|
|
194
|
+
lowest, and `null` clears it. Sami ruled on 2026-09-24, answering "may agents set issue priority
|
|
195
|
+
(P0–P3), or only propose it for you?" on `dispatch://LEGION/artifact/issue-status-conventions-md`:
|
|
196
|
+
**"Agents may set"**. So set it — on creation, and on a grooming pass over issues that have none —
|
|
197
|
+
and say what you set and why; he overrides anything he disagrees with from the dashboard. A closed
|
|
198
|
+
issue takes only `rank`, `components`, and a reopening `status` (any status but `done`);
|
|
199
|
+
everything else, `priority` included, waits for the reopen (`409 ISSUE_CLOSED`). So reopen it
|
|
200
|
+
first, then set the priority — the two cannot go in one call. `rank` itself is not a tool field:
|
|
201
|
+
reorder it the way [Issue reads](#your-owner) describes, through `PATCH /api/v1/issues/{key}`.
|
|
202
|
+
|
|
188
203
|
## Search first
|
|
189
204
|
|
|
190
205
|
Before you create an issue or start a design document, search:
|