@sjawhar/opencode-legion-envoy 0.28.0 → 0.29.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 +1 -0
- package/dist/src/server.js +47 -3
- package/package.json +1 -1
- package/skills/dispatch/SKILL.md +14 -2
package/README.md
CHANGED
package/dist/src/server.js
CHANGED
|
@@ -13574,7 +13574,13 @@ var ArtifactVersionEventPayloadSchema = object({
|
|
|
13574
13574
|
var AskEventPayloadSchema = object({
|
|
13575
13575
|
question: string2().optional(),
|
|
13576
13576
|
options: array(object({ label: string2().optional() })).nullish(),
|
|
13577
|
-
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish()
|
|
13577
|
+
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish(),
|
|
13578
|
+
resolution: object({
|
|
13579
|
+
kind: _enum2(["retracted", "resolved"]).optional(),
|
|
13580
|
+
reason: string2().optional(),
|
|
13581
|
+
actor: object({ kind: string2().optional(), id: string2().optional() }).passthrough().optional(),
|
|
13582
|
+
at: string2().optional()
|
|
13583
|
+
}).nullish()
|
|
13578
13584
|
});
|
|
13579
13585
|
var CommentEventPayloadSchema = object({
|
|
13580
13586
|
artifact_name: string2().optional(),
|
|
@@ -13630,6 +13636,15 @@ var dispatchToolSpecs = [
|
|
|
13630
13636
|
}).describe("Optional document location for the question.").optional()
|
|
13631
13637
|
})
|
|
13632
13638
|
},
|
|
13639
|
+
{
|
|
13640
|
+
name: "dispatch_resolve_ask",
|
|
13641
|
+
description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
|
|
13642
|
+
arguments: (z) => ({
|
|
13643
|
+
ask: z.string().describe("Ask id to close."),
|
|
13644
|
+
kind: z.enum(["retracted", "resolved"]).describe("Whether the ask is retracted or self-resolved."),
|
|
13645
|
+
reason: z.string({ min: 1 }).describe("Why the open ask no longer needs a human answer.")
|
|
13646
|
+
})
|
|
13647
|
+
},
|
|
13633
13648
|
{
|
|
13634
13649
|
name: "dispatch_comment",
|
|
13635
13650
|
description: "Add review feedback to an issue or document quote, or reply to a question asked with dispatch_ask. " + "Do not use it for an exact replacement; use " + `dispatch_suggest instead. Body is at most 2,000 characters. ${ISSUE_REFERENCE}`,
|
|
@@ -14340,6 +14355,9 @@ class DispatchClient {
|
|
|
14340
14355
|
async ask(issue, input) {
|
|
14341
14356
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "asks"], input);
|
|
14342
14357
|
}
|
|
14358
|
+
async resolveAsk(id, input) {
|
|
14359
|
+
return this.#json("POST", ["api", "v1", "asks", id, "resolve"], input);
|
|
14360
|
+
}
|
|
14343
14361
|
async comment(issue, input) {
|
|
14344
14362
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "comments"], input);
|
|
14345
14363
|
}
|
|
@@ -14558,7 +14576,7 @@ function toolSchema(tool) {
|
|
|
14558
14576
|
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
14559
14577
|
}
|
|
14560
14578
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
14561
|
-
if (tool === "dispatch_issue")
|
|
14579
|
+
if (tool === "dispatch_issue" || tool === "dispatch_resolve_ask")
|
|
14562
14580
|
return { args, ref: null };
|
|
14563
14581
|
const refArgument = args.ref;
|
|
14564
14582
|
const ref = typeof refArgument === "string" ? parseDispatchRef(refArgument) ?? (() => {
|
|
@@ -14665,6 +14683,12 @@ function askSummary({ ask, replies }) {
|
|
|
14665
14683
|
`- Selected: ${answer.selected.length === 0 ? "none" : answer.selected.join(", ")}`,
|
|
14666
14684
|
...answer.text === null ? [] : [`- Text: ${answer.text}`]
|
|
14667
14685
|
],
|
|
14686
|
+
...ask.resolution === undefined ? [] : [
|
|
14687
|
+
"Resolution:",
|
|
14688
|
+
`- By: ${ask.resolution.actor.id}`,
|
|
14689
|
+
`- Kind: ${ask.resolution.kind}`,
|
|
14690
|
+
`- Reason: ${ask.resolution.reason}`
|
|
14691
|
+
],
|
|
14668
14692
|
"Replies:",
|
|
14669
14693
|
...chain.length === 0 ? ["- none"] : chain
|
|
14670
14694
|
].join(`
|
|
@@ -14709,7 +14733,7 @@ async function executeDispatchTool(input) {
|
|
|
14709
14733
|
const args = toolSchema(input.tool).parse(issueArguments.args);
|
|
14710
14734
|
const actor = toolActor(await resolveOrigin(env, exec, input.cwd), input);
|
|
14711
14735
|
const client = new DispatchClient(input.config.url, input.config.token, input.fetchImpl);
|
|
14712
|
-
const issueKey = input.tool === "dispatch_issue" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
14736
|
+
const issueKey = input.tool === "dispatch_issue" || input.tool === "dispatch_resolve_ask" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
14713
14737
|
const issue = () => {
|
|
14714
14738
|
if (issueKey === null)
|
|
14715
14739
|
throw new Error("issue is required");
|
|
@@ -14733,6 +14757,26 @@ async function executeDispatchTool(input) {
|
|
|
14733
14757
|
details: { issue: created.key, topic: dispatchIssueSubject(created.key, ">") }
|
|
14734
14758
|
};
|
|
14735
14759
|
}
|
|
14760
|
+
case "dispatch_resolve_ask": {
|
|
14761
|
+
const kind = stringArg(args, "kind");
|
|
14762
|
+
if (kind !== "retracted" && kind !== "resolved")
|
|
14763
|
+
throw new Error("kind must be retracted or resolved");
|
|
14764
|
+
const ask = await client.resolveAsk(stringArg(args, "ask"), {
|
|
14765
|
+
kind,
|
|
14766
|
+
reason: stringArg(args, "reason"),
|
|
14767
|
+
actor
|
|
14768
|
+
});
|
|
14769
|
+
if (ask.resolution === undefined)
|
|
14770
|
+
throw new Error("resolved ask is missing its resolution");
|
|
14771
|
+
return {
|
|
14772
|
+
text: `${kind === "retracted" ? "Retracted" : "Resolved"} ask ${ask.id}: ${ask.resolution.reason}`,
|
|
14773
|
+
details: {
|
|
14774
|
+
issue: ask.issue_key,
|
|
14775
|
+
topic: dispatchIssueSubject(ask.issue_key, ">"),
|
|
14776
|
+
ask: ask.id
|
|
14777
|
+
}
|
|
14778
|
+
};
|
|
14779
|
+
}
|
|
14736
14780
|
case "dispatch_ask": {
|
|
14737
14781
|
const anchorArgs = asObject(args.anchor);
|
|
14738
14782
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -44,8 +44,20 @@ It returns `details` `{ issue, topic, ask }`. Options are buttons: never enumera
|
|
|
44
44
|
prose. Put the recommendation in `question`, and put each selectable choice in `options`.
|
|
45
45
|
Anchor a document question with `anchor: { artifact, quote, occurrence? }`; `occurrence` is
|
|
46
46
|
zero-based and selects a repeated quote. An anchor whose quote disappears becomes orphaned but
|
|
47
|
-
remains readable against its original document version.
|
|
48
|
-
|
|
47
|
+
remains readable against its original document version.
|
|
48
|
+
|
|
49
|
+
An ask stays open until a human answers, unless its question no longer needs that answer. Retract a
|
|
50
|
+
moot or superseded question, or self-resolve one after finding the answer:
|
|
51
|
+
```ts
|
|
52
|
+
dispatch_resolve_ask({
|
|
53
|
+
ask,
|
|
54
|
+
kind: "retracted",
|
|
55
|
+
reason: "A newer ask supersedes this question.",
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
Use `retracted` when the question is obsolete and `resolved` when you found the answer. Include the
|
|
59
|
+
reason because the question remains in its issue log and reply thread. Resolution is not an answer:
|
|
60
|
+
it never records a human decision, and an answered ask cannot be resolved.
|
|
49
61
|
|
|
50
62
|
An ask is a thread, not a dead end: a human can reply to it before or after answering, and you
|
|
51
63
|
(the asker) can reply too — e.g. acknowledging a clarifying question, or following up after the
|