@sjawhar/opencode-legion-envoy 3.8.2 → 3.9.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/src/server.js +12 -2
- package/package.json +1 -1
- package/skills/dispatch/SKILL.md +40 -2
package/dist/src/server.js
CHANGED
|
@@ -14255,13 +14255,14 @@ var dispatchToolSpecs = [
|
|
|
14255
14255
|
},
|
|
14256
14256
|
{
|
|
14257
14257
|
name: "dispatch_issues",
|
|
14258
|
-
example: { project: "AGENTC" },
|
|
14259
|
-
description: "List a project's issues for a roadmap or backlog pass: every issue in one project, each carrying " + "its status, priority, parent, labels, and open-ask count, so you can see backlog shape without " + "opening every issue. Optionally filter by status, parent, label, or how recently it changed
|
|
14258
|
+
example: { project: "AGENTC", priority: [0, 1] },
|
|
14259
|
+
description: "List a project's issues for a roadmap or backlog pass: every issue in one project, each carrying " + "its status, priority, parent, labels, and open-ask count, so you can see backlog shape without " + "opening every issue. Optionally filter by status, parent, label, priority, or how recently it " + "changed; priority takes one or more of 0-3 (P0-P3) and null for an issue with no priority, so " + "an owner's P0/P1 audit is priority [0, 1]. Do not use it to search by keyword or phrase; " + "dispatch_search remains the keyword surface. Rows are capped at limit (default 50, max 250), " + "applied to the response here, not by the server.",
|
|
14260
14260
|
arguments: (z2) => ({
|
|
14261
14261
|
project: z2.string().describe("Project key to list issues from."),
|
|
14262
14262
|
status: z2.enum(ISSUE_STATUSES).describe("Optional lifecycle status filter.").optional(),
|
|
14263
14263
|
parent: z2.string().describe("Optional parent issue key filter.").optional(),
|
|
14264
14264
|
label: z2.string().describe("Optional label filter.").optional(),
|
|
14265
|
+
priority: z2.array(z2.number({ int: true, min: 0, max: 3 }).nullable(), { min: 1, max: 5 }).describe("Optional priority filter: one or more of 0 (P0, highest) through 3 (P3, lowest), and null " + "for an issue with no priority; an issue matching any listed value is returned.").optional(),
|
|
14265
14266
|
updated_since: z2.string().describe("Optional RFC3339 timestamp; only issues updated at or after it.").optional(),
|
|
14266
14267
|
limit: z2.number({ int: true, min: 1, max: 250 }).describe("Maximum rows, 1-250; default 50.").optional()
|
|
14267
14268
|
})
|
|
@@ -15323,6 +15324,9 @@ class DispatchClient {
|
|
|
15323
15324
|
for (const [name, value] of Object.entries(query)) {
|
|
15324
15325
|
if (typeof value === "string" || typeof value === "number") {
|
|
15325
15326
|
url2.searchParams.set(name, String(value));
|
|
15327
|
+
} else if (Array.isArray(value)) {
|
|
15328
|
+
for (const item of value)
|
|
15329
|
+
url2.searchParams.append(name, String(item));
|
|
15326
15330
|
}
|
|
15327
15331
|
}
|
|
15328
15332
|
}
|
|
@@ -15623,6 +15627,10 @@ function optionalPriority(args, name) {
|
|
|
15623
15627
|
return null;
|
|
15624
15628
|
return typeof value === "number" ? value : undefined;
|
|
15625
15629
|
}
|
|
15630
|
+
function optionalPriorityFilter(args, name) {
|
|
15631
|
+
const value = args[name];
|
|
15632
|
+
return Array.isArray(value) ? value.map((item) => item ?? "none") : undefined;
|
|
15633
|
+
}
|
|
15626
15634
|
function optionalComponents(args, name) {
|
|
15627
15635
|
const value = args[name];
|
|
15628
15636
|
if (typeof value !== "object" || value === null)
|
|
@@ -16688,6 +16696,7 @@ async function executeDispatchTool(input) {
|
|
|
16688
16696
|
const status = optionalString(args, "status");
|
|
16689
16697
|
const parent = optionalString(args, "parent");
|
|
16690
16698
|
const label = optionalString(args, "label");
|
|
16699
|
+
const priority = optionalPriorityFilter(args, "priority");
|
|
16691
16700
|
const updatedSince = optionalString(args, "updated_since");
|
|
16692
16701
|
const limit = Math.min(Math.max(optionalNumber(args, "limit") ?? 50, 1), 250);
|
|
16693
16702
|
const issues = await client.listIssues({
|
|
@@ -16695,6 +16704,7 @@ async function executeDispatchTool(input) {
|
|
|
16695
16704
|
...status === undefined ? {} : { status },
|
|
16696
16705
|
...parent === undefined ? {} : { parent },
|
|
16697
16706
|
...label === undefined ? {} : { label },
|
|
16707
|
+
...priority === undefined ? {} : { priority },
|
|
16698
16708
|
...updatedSince === undefined ? {} : { updated_since: updatedSince }
|
|
16699
16709
|
});
|
|
16700
16710
|
const rows = issues.slice(0, limit).map((row) => ({
|
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -286,16 +286,54 @@ distinction from the named issue, citing it (`dispatch://KEY`), for whoever read
|
|
|
286
286
|
|
|
287
287
|
To see the shape of a project rather than find a phrase, list its issues:
|
|
288
288
|
```ts
|
|
289
|
-
dispatch_issues({ project, status?, parent?, label?, updated_since?, limit? })
|
|
289
|
+
dispatch_issues({ project, status?, parent?, label?, priority?, updated_since?, limit? })
|
|
290
290
|
```
|
|
291
291
|
Each row carries the issue key, title, status, priority, parent, labels, its open-ask count, and
|
|
292
292
|
when it last changed — a roadmap or backlog pass without opening every issue. Filter with `status`
|
|
293
|
-
(a lifecycle status), `parent` (one issue's children), `label`,
|
|
293
|
+
(a lifecycle status), `parent` (one issue's children), `label`, `priority` (a list of `0`–`3`, with
|
|
294
|
+
`null` for an issue with no priority: `[0, 1]` is every P0 and P1), or `updated_since` (an RFC3339
|
|
294
295
|
timestamp, for "what moved this week"). `limit` caps the rows at 50 by default and 250 at most.
|
|
295
296
|
|
|
296
297
|
This is not search: it matches no text. Use `dispatch_search` for a keyword or phrase, and
|
|
297
298
|
`dispatch_issues` when you want every issue in a project and its current state.
|
|
298
299
|
|
|
300
|
+
### The owner audit
|
|
301
|
+
|
|
302
|
+
As the owner of a surface, list your area's P0 and P1 issues and staff or close each one nobody
|
|
303
|
+
has started:
|
|
304
|
+
```ts
|
|
305
|
+
dispatch_issues({ project, priority: [0, 1], limit: 250 })
|
|
306
|
+
```
|
|
307
|
+
Every unclaimed row in `triage`, `icebox`, `backlog` or `todo` is a decision: someone takes it and
|
|
308
|
+
builds it, or it closes. A row in `in_progress`, `testing`, `needs_review` or `retro`, or one that
|
|
309
|
+
carries a claim, is work under way ([Issue status is yours to move](#issue-status-is-yours-to-move))
|
|
310
|
+
and is not re-staffed. A todo with a finished spec reads as queued work that nobody is doing
|
|
311
|
+
(LEGION-173 sat in todo for two weeks with a complete spec; AGENTC-1010's v4 plan sat in backlog
|
|
312
|
+
with nobody building it).
|
|
313
|
+
|
|
314
|
+
The audit finds three shapes:
|
|
315
|
+
|
|
316
|
+
- **Unstaffed work.** A plan or measurement exists, and no one is building it.
|
|
317
|
+
- **Unrecorded delivery.** An issue not yet in `testing` or `done`, claimed or not, has a merged PR
|
|
318
|
+
naming it. Check the change live, then move the issue (AGENTC-1033 sat at `triage` after its fix,
|
|
319
|
+
agent-c #20367, merged).
|
|
320
|
+
- **Unrecorded practice.** Someone does the issue's work by hand, more than once, while the issue
|
|
321
|
+
sits in backlog (OPS-132, done by hand on every migration merge). It leaves no plan and no PR to
|
|
322
|
+
find; the tell is your own messages. Doing something by hand more than once means an issue is
|
|
323
|
+
wearing the wrong status.
|
|
324
|
+
|
|
325
|
+
Run the audit as a step of a coordinator's loop, at each checkpoint, not as a habit: these shapes
|
|
326
|
+
are found by running the check, not by noticing them.
|
|
327
|
+
|
|
328
|
+
### Symptom versus cause
|
|
329
|
+
|
|
330
|
+
When a symptom and its cause sit on different issues, the work accrues to the cause's issue, and
|
|
331
|
+
the symptom's issue carries a pointer to it. Before posting a measurement or finding, search
|
|
332
|
+
Dispatch for the failing identity's or component's name, and post on the issue whose title names
|
|
333
|
+
the fix, not the one naming the symptom. A symptom issue gathering messages with no human response
|
|
334
|
+
is the tell. (The production freeze was iterated on AGENTC-546, the failing gate, while its cause
|
|
335
|
+
and answer sat on AGENTC-1010.)
|
|
336
|
+
|
|
299
337
|
## Asking
|
|
300
338
|
|
|
301
339
|
### Before you ask
|