@sjawhar/opencode-legion-envoy 1.50.0 → 1.52.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.
@@ -13931,12 +13931,13 @@ var dispatchToolSpecs = [
13931
13931
  {
13932
13932
  name: "dispatch_issue_update",
13933
13933
  example: { issue: "DSP-1", status: "in_progress" },
13934
- description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, 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 and is allowed on a " + "closed issue. Priority is the human's and is not settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
13934
+ 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}`,
13935
13935
  arguments: (z) => ({
13936
13936
  issue: z.string().describe(ISSUE_REFERENCE),
13937
13937
  status: z.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
13938
13938
  title: z.string({ min: 1 }).describe("Replacement title.").optional(),
13939
13939
  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(),
13940
+ 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."),
13940
13941
  external_links: z.array(z.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
13941
13942
  route: z.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
13942
13943
  parent: z.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
@@ -13945,9 +13946,9 @@ var dispatchToolSpecs = [
13945
13946
  validation: {
13946
13947
  check: (value) => {
13947
13948
  const input = value;
13948
- 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;
13949
+ 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;
13949
13950
  },
13950
- message: "Issue update requires at least one field besides issue: status, title, labels, external_links, route, parent, or components."
13951
+ message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, or components."
13951
13952
  },
13952
13953
  strict: true
13953
13954
  },
@@ -15577,6 +15578,12 @@ function optionalNumber(args, name) {
15577
15578
  const value = args[name];
15578
15579
  return typeof value === "number" ? value : undefined;
15579
15580
  }
15581
+ function optionalPriority(args, name) {
15582
+ const value = args[name];
15583
+ if (value === null)
15584
+ return null;
15585
+ return typeof value === "number" ? value : undefined;
15586
+ }
15580
15587
  function optionalComponents(args, name) {
15581
15588
  const value = args[name];
15582
15589
  if (typeof value !== "object" || value === null)
@@ -16421,7 +16428,7 @@ async function executeDispatchTool(input) {
16421
16428
  const external = optionalString(args, "external");
16422
16429
  const force = optionalBoolean(args, "force");
16423
16430
  const spec = optionalString(args, "spec");
16424
- const priority = optionalNumber(args, "priority");
16431
+ const priority = optionalPriority(args, "priority");
16425
16432
  const assignee = optionalString(args, "assignee");
16426
16433
  const components = optionalComponents(args, "components");
16427
16434
  const labels = args.labels;
@@ -16483,6 +16490,7 @@ async function executeDispatchTool(input) {
16483
16490
  const route = optionalString(args, "route");
16484
16491
  const parent = optionalString(args, "parent");
16485
16492
  const components = optionalComponents(args, "components");
16493
+ const priority = optionalPriority(args, "priority");
16486
16494
  const labels = Array.isArray(args.labels) ? args.labels : undefined;
16487
16495
  const requestedLinks = Array.isArray(args.external_links) ? [...new Set(args.external_links)] : undefined;
16488
16496
  let newLinks = [];
@@ -16494,6 +16502,7 @@ async function executeDispatchTool(input) {
16494
16502
  ...status === undefined ? {} : { status },
16495
16503
  ...title === undefined ? {} : { title },
16496
16504
  ...labels === undefined ? {} : { labels },
16505
+ ...priority === undefined ? {} : { priority },
16497
16506
  ...route === undefined ? {} : { route },
16498
16507
  ...parent === undefined ? {} : { parent: parent === "" ? null : parent },
16499
16508
  ...components === undefined ? {} : { components },
@@ -16505,6 +16514,7 @@ async function executeDispatchTool(input) {
16505
16514
  ...status === undefined ? [] : [`status ${before.status} -> ${after.status}`],
16506
16515
  ...title === undefined ? [] : [`title "${after.title}"`],
16507
16516
  ...labels === undefined ? [] : [after.labels.length === 0 ? "labels cleared" : `labels ${after.labels.join(", ")}`],
16517
+ ...priority === undefined ? [] : [after.priority === null ? "priority cleared" : `priority -> P${after.priority}`],
16508
16518
  ...requestedLinks === undefined ? [] : [
16509
16519
  newLinks.length === 0 ? `already linked ${requestedLinks.join(", ")} ${linkCount}` : `linked ${newLinks.join(", ")} ${linkCount}`
16510
16520
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/opencode-legion-envoy",
3
- "version": "1.50.0",
3
+ "version": "1.52.0",
4
4
  "type": "module",
5
5
  "main": "dist/src/server.js",
6
6
  "exports": {
@@ -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. Set `priority` on creation only when the human's intent makes the bucket clear; otherwise priority remains the human's decision. 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
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. Priority stays the
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: