@sjawhar/opencode-legion-envoy 1.51.0 → 1.53.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/README.md +2 -1
- package/dist/src/server.js +3313 -3204
- package/package.json +1 -1
- package/skills/dispatch/SKILL.md +60 -4
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -154,10 +154,51 @@ 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
|
|
|
161
|
+
## Claim the issue before you work it
|
|
162
|
+
|
|
163
|
+
Two sessions once spent a night implementing the same issue, because nothing on it said who was
|
|
164
|
+
on it (Sami, 2026-09-24, verbatim: "It seems like we need a better way of tracking what's already
|
|
165
|
+
in progress"). So before you start implementing an issue, claim it:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
dispatch_claim({ issue: "LEGION-234" }) // I am implementing this
|
|
169
|
+
dispatch_claim({ issue: "LEGION-234", release: true }) // I have stopped; it is free
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
A claim records **your** session — the one making the call, never another — and shows on every
|
|
173
|
+
read of the issue: the dashboard header, the issue list and board, `dispatch_read` (a
|
|
174
|
+
`Claimed by:` line) and `dispatch_issues` (a claim on the row). `dispatch_issues` plus the
|
|
175
|
+
dashboard's **Unclaimed** filter is how you find work nobody is on.
|
|
176
|
+
|
|
177
|
+
- **`409 ISSUE_CLAIMED` means someone else holds this issue.** When it is another session, the
|
|
178
|
+
refusal names it and says it is still running: do not work the issue in parallel — message
|
|
179
|
+
that session (its id is in the message; `envoy_send` reaches it) or pick up something else,
|
|
180
|
+
and tell the human if you believe the work should be yours. When a **human** holds it, the
|
|
181
|
+
refusal names the person and says nothing about a session running, because there is none to
|
|
182
|
+
message: ask them on the issue (`dispatch_message`) instead, and never assume their claim has
|
|
183
|
+
lapsed — only a human releases or forces a human's claim.
|
|
184
|
+
- **`409 CLAIM_CONTENDED` means the issue changed hands twice while your call ran**, so nothing
|
|
185
|
+
was applied and nobody's liveness was checked. Read the issue and decide again; it is not a
|
|
186
|
+
refusal by a live holder.
|
|
187
|
+
- **A claim whose session has ended is yours to take.** If the Envoy listener no longer lists
|
|
188
|
+
the holder, your claim simply succeeds; the takeover is recorded on the issue and the session
|
|
189
|
+
that lost it is told.
|
|
190
|
+
- **Release it when you stop** — finished, handing over, or moving to something else. A claim is
|
|
191
|
+
released by its holder or any human — and by any agent once the holder's session is no longer
|
|
192
|
+
running, the same rule that lets you take it. Closing the issue releases it for you.
|
|
193
|
+
- A claim is intent to implement, not contact: reading the issue, commenting, asking, or gating
|
|
194
|
+
its pull request claims nothing, so a coordinator never collides with an implementer.
|
|
195
|
+
|
|
196
|
+
**Claiming and moving the status are two separate actions, and you do both.** A claim says which
|
|
197
|
+
session is on the work; the status says where the work has got to, and humans use it to track
|
|
198
|
+
that too (Sami, 2026-09-24, verbatim: "Keep them separate — Separate because humans might be
|
|
199
|
+
using them to keep track of work"). So when you start: `dispatch_claim({ issue })` **and**
|
|
200
|
+
`dispatch_issue_update({ issue, status: "in_progress" })`.
|
|
201
|
+
|
|
161
202
|
## Issue status is yours to move
|
|
162
203
|
|
|
163
204
|
The issue's status is how a human sees delivery without asking a session. Outside Legion (where
|
|
@@ -167,16 +208,19 @@ production-like surface, `needs_review` when its pull request is open and waitin
|
|
|
167
208
|
queue, `done` when the change has been driven in production (a merge is not `done`). Move child
|
|
168
209
|
issues you own as well as the root. An issue left at `triage` while work is underway is a defect:
|
|
169
210
|
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.
|
|
211
|
+
status is." Waiting for the deploy lane is not a status and is never announced.
|
|
172
212
|
|
|
173
213
|
```ts
|
|
174
|
-
// PATCH /api/v1/issues/{key} — status, title, labels, external_links (merged by URL), route, parent
|
|
214
|
+
// PATCH /api/v1/issues/{key} — status, title, labels, priority, external_links (merged by URL), route, parent
|
|
175
215
|
dispatch_issue_update({ issue: "AGENTC-175", status: "testing" })
|
|
216
|
+
dispatch_issue_update({ issue: "AGENTC-175", priority: 1 }) // 0–3; see Priority is yours to set
|
|
176
217
|
dispatch_issue_update({ issue: "AGENTC-175", external_links: ["https://github.com/owner/repo/pull/7"] })
|
|
177
218
|
dispatch_issue_update({ issue: "AGENTC-175", parent: "AGENTC-170" }) // same-project key; "" clears the parent
|
|
178
219
|
```
|
|
179
220
|
|
|
221
|
+
The two clears differ: `priority` clears with `null`, while `parent` and `route` clear with `""`.
|
|
222
|
+
Guessing the other one is a refusal either way.
|
|
223
|
+
|
|
180
224
|
Link the pull request that delivers the issue in `external_links` when you open it; the issue page
|
|
181
225
|
renders its state and checks from that link. The call is authenticated with the same bearer as every
|
|
182
226
|
other `dispatch_*` tool: a Legion pane reads it from the `DISPATCH_TOKEN_FILE` path the daemon sets on
|
|
@@ -185,6 +229,18 @@ the pane; an OMP session outside Legion reads `dispatch.token` from `~/.config/o
|
|
|
185
229
|
A write to an issue still in `triage` answers once with `… is still in triage …`; move the status
|
|
186
230
|
when work has started.
|
|
187
231
|
|
|
232
|
+
## Priority is yours to set
|
|
233
|
+
|
|
234
|
+
Priority is the coarse bucket a backlog is read by: `0` is P0, the highest, through `3`, P3, the
|
|
235
|
+
lowest, and `null` clears it. Sami ruled on 2026-09-24, answering "may agents set issue priority
|
|
236
|
+
(P0–P3), or only propose it for you?" on `dispatch://LEGION/artifact/issue-status-conventions-md`:
|
|
237
|
+
**"Agents may set"**. So set it — on creation, and on a grooming pass over issues that have none —
|
|
238
|
+
and say what you set and why; he overrides anything he disagrees with from the dashboard. A closed
|
|
239
|
+
issue takes only `rank`, `components`, and a reopening `status` (any status but `done`);
|
|
240
|
+
everything else, `priority` included, waits for the reopen (`409 ISSUE_CLOSED`). So reopen it
|
|
241
|
+
first, then set the priority — the two cannot go in one call. `rank` itself is not a tool field:
|
|
242
|
+
reorder it the way [Issue reads](#your-owner) describes, through `PATCH /api/v1/issues/{key}`.
|
|
243
|
+
|
|
188
244
|
## Search first
|
|
189
245
|
|
|
190
246
|
Before you create an issue or start a design document, search:
|