@sjawhar/pi-envoy 10.2.3 → 10.2.4

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
@@ -14043,7 +14043,7 @@ var dispatchToolSpecs = [
14043
14043
  status: "done",
14044
14044
  reason: "Shipped in owner/repo#7; verified on the production dashboard."
14045
14045
  },
14046
- 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}`,
14046
+ 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. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. 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, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); 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}`,
14047
14047
  arguments: (z2) => ({
14048
14048
  issue: z2.string().describe(ISSUE_REFERENCE),
14049
14049
  status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
@@ -14051,7 +14051,7 @@ var dispatchToolSpecs = [
14051
14051
  title: z2.string({ min: 1, max: ISSUE_TITLE_MAX }).describe("Replacement title, at most 1,000 characters.").optional(),
14052
14052
  labels: z2.array(z2.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(),
14053
14053
  priority: z2.number({ int: true, min: 0, max: 3 }).nullable().optional().describe("Coarse priority: 0 is P0 (highest) through 3 is P3 (lowest); null clears it."),
14054
- external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
14054
+ external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; a non-empty list merges into the issue's existing external links by URL, an empty list removes every link instead.").optional(),
14055
14055
  route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
14056
14056
  parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
14057
14057
  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(),
@@ -17515,6 +17515,7 @@ async function executeDispatchTool(input) {
17515
17515
  }
17516
17516
  const linked = before.external_links.map((link) => link.url);
17517
17517
  const newLinks = requestedLinks?.filter((url2) => !linked.includes(url2)) ?? [];
17518
+ const sentLinks = requestedLinks === undefined ? undefined : requestedLinks.length === 0 ? [] : [...before.external_links, ...newLinks.map((url2) => ({ url: url2 }))];
17518
17519
  let after;
17519
17520
  try {
17520
17521
  after = await client.updateIssue(issueKey, {
@@ -17526,7 +17527,7 @@ async function executeDispatchTool(input) {
17526
17527
  ...parent === undefined ? {} : { parent: parent === "" ? null : parent },
17527
17528
  ...blockedBy === undefined ? {} : { blocked_by: blockedBy },
17528
17529
  ...components === undefined ? {} : { components },
17529
- ...requestedLinks === undefined ? {} : { external_links: [...before.external_links, ...newLinks.map((url2) => ({ url: url2 }))] },
17530
+ ...sentLinks === undefined ? {} : { external_links: sentLinks },
17530
17531
  actor
17531
17532
  });
17532
17533
  } catch (error48) {
@@ -17548,7 +17549,7 @@ async function executeDispatchTool(input) {
17548
17549
  ...labels === undefined ? [] : [after.labels.length === 0 ? "labels cleared" : `labels ${after.labels.join(", ")}`],
17549
17550
  ...priority === undefined ? [] : [after.priority === null ? "priority cleared" : `priority -> P${after.priority}`],
17550
17551
  ...requestedLinks === undefined ? [] : [
17551
- newLinks.length === 0 ? `already linked ${requestedLinks.join(", ")} ${linkCount}` : `linked ${newLinks.join(", ")} ${linkCount}`
17552
+ requestedLinks.length === 0 ? "external links cleared" : newLinks.length === 0 ? `already linked ${requestedLinks.join(", ")} ${linkCount}` : `linked ${newLinks.join(", ")} ${linkCount}`
17552
17553
  ],
17553
17554
  ...route === undefined ? [] : [after.route === null ? "route cleared" : `route ${after.route}`],
17554
17555
  ...parent === undefined ? [] : [after.parent === null ? "parent cleared" : `parent -> ${after.parent}`],
package/dist/envoy.js CHANGED
@@ -30030,7 +30030,7 @@ var dispatchToolSpecs = [
30030
30030
  status: "done",
30031
30031
  reason: "Shipped in owner/repo#7; verified on the production dashboard."
30032
30032
  },
30033
- 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}`,
30033
+ 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. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. 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, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); 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}`,
30034
30034
  arguments: (z2) => ({
30035
30035
  issue: z2.string().describe(ISSUE_REFERENCE),
30036
30036
  status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
@@ -30038,7 +30038,7 @@ var dispatchToolSpecs = [
30038
30038
  title: z2.string({ min: 1, max: ISSUE_TITLE_MAX }).describe("Replacement title, at most 1,000 characters.").optional(),
30039
30039
  labels: z2.array(z2.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
30040
  priority: z2.number({ int: true, min: 0, max: 3 }).nullable().optional().describe("Coarse priority: 0 is P0 (highest) through 3 is P3 (lowest); null clears it."),
30041
- external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; merged into the issue's existing external links by URL.").optional(),
30041
+ external_links: z2.array(z2.string({ min: 1 })).describe("URLs to link; a non-empty list merges into the issue's existing external links by URL, an empty list removes every link instead.").optional(),
30042
30042
  route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
30043
30043
  parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
30044
30044
  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(),
@@ -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, blocked_by
88
+ # PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), 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
@@ -100,8 +100,9 @@ error names the posted message; after a timeout or a server error it also says t
100
100
  landed, so read the issue's status first. A retry points its reason at the posted message rather
101
101
  than repeating it.
102
102
 
103
- The two clears differ: `--clear-priority` sends null, while `--parent ''` and `--route ''` clear with an
104
- empty string. Guessing the other one is a refusal either way.
103
+ The three clears differ: `--clear-priority` sends null, `--parent ''` and `--route ''` clear with an
104
+ empty string, and `--clear-external-links` / `--clear-blocked-by` send an empty list. Guessing the
105
+ wrong shape is a refusal either way.
105
106
 
106
107
  Link the pull request that delivers the issue with `--external-link` when you open it; the issue page
107
108
  renders its state and checks from that link, and `dispatch read` lists it under `External links:`.
@@ -122,7 +123,8 @@ Priority is the coarse bucket a backlog is read by: `0` is P0, the highest, thro
122
123
  lowest, and `null` clears it. Agents set it (`dispatch://LEGION/artifact/issue-status-conventions-md`)
123
124
  — on creation, and on a grooming pass over issues that have none — and say what you set and why;
124
125
  the human overrides anything they disagree with from the dashboard. A closed
125
- issue takes only `rank`, `components`, and a reopening `status` (any status but `done`);
126
+ issue takes only `rank`, `components`, a reopening `status` (any status but `done`), and an
127
+ external-links write that adds no new link (so a link can move to the issue that replaced it);
126
128
  everything else, `priority` included, waits for the reopen (`409 ISSUE_CLOSED`). So reopen it
127
129
  first, then set the priority — the two cannot go in one command. `rank` itself is not a flag:
128
130
  reorder it the way [Issue reads](#board-rank-priority-and-assignee-on-a-read) describes, through `PATCH /api/v1/issues/{key}`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-envoy",
3
- "version": "10.2.3",
3
+ "version": "10.2.4",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "omp": {