@sjawhar/pi-legion-envoy 0.26.0 → 0.28.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 -2
- package/dist/envoy.js +48 -3
- package/dist/legion.js +48 -3
- package/dist/skills/dispatch/SKILL.md +14 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,8 +79,8 @@ extension files it does not contain.
|
|
|
79
79
|
|
|
80
80
|
## Native Dispatch tools
|
|
81
81
|
|
|
82
|
-
The extension registers `dispatch_issue`, `dispatch_ask`, `
|
|
83
|
-
`dispatch_suggest`, `dispatch_message`, `dispatch_doc_edit`,
|
|
82
|
+
The extension registers `dispatch_issue`, `dispatch_ask`, `dispatch_resolve_ask`,
|
|
83
|
+
`dispatch_comment`, `dispatch_suggest`, `dispatch_message`, `dispatch_doc_edit`,
|
|
84
84
|
`dispatch_doc_read`, `dispatch_artifact`, and `dispatch_read` when Dispatch
|
|
85
85
|
configuration resolves both a base URL and bearer token.
|
|
86
86
|
|
package/dist/envoy.js
CHANGED
|
@@ -29671,7 +29671,13 @@ var ArtifactVersionEventPayloadSchema = object({
|
|
|
29671
29671
|
var AskEventPayloadSchema = object({
|
|
29672
29672
|
question: string2().optional(),
|
|
29673
29673
|
options: array(object({ label: string2().optional() })).nullish(),
|
|
29674
|
-
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish()
|
|
29674
|
+
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish(),
|
|
29675
|
+
resolution: object({
|
|
29676
|
+
kind: _enum2(["retracted", "resolved"]).optional(),
|
|
29677
|
+
reason: string2().optional(),
|
|
29678
|
+
actor: object({ kind: string2().optional(), id: string2().optional() }).passthrough().optional(),
|
|
29679
|
+
at: string2().optional()
|
|
29680
|
+
}).nullish()
|
|
29675
29681
|
});
|
|
29676
29682
|
var CommentEventPayloadSchema = object({
|
|
29677
29683
|
artifact_name: string2().optional(),
|
|
@@ -29727,6 +29733,15 @@ var dispatchToolSpecs = [
|
|
|
29727
29733
|
}).describe("Optional document location for the question.").optional()
|
|
29728
29734
|
})
|
|
29729
29735
|
},
|
|
29736
|
+
{
|
|
29737
|
+
name: "dispatch_resolve_ask",
|
|
29738
|
+
description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
|
|
29739
|
+
arguments: (z) => ({
|
|
29740
|
+
ask: z.string().describe("Ask id to close."),
|
|
29741
|
+
kind: z.enum(["retracted", "resolved"]).describe("Whether the ask is retracted or self-resolved."),
|
|
29742
|
+
reason: z.string({ min: 1 }).describe("Why the open ask no longer needs a human answer.")
|
|
29743
|
+
})
|
|
29744
|
+
},
|
|
29730
29745
|
{
|
|
29731
29746
|
name: "dispatch_comment",
|
|
29732
29747
|
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}`,
|
|
@@ -30798,6 +30813,7 @@ var DISPATCH_PAYLOAD_SCHEMAS = {
|
|
|
30798
30813
|
"artifact.version": ArtifactVersionEventPayloadSchema,
|
|
30799
30814
|
"ask.opened": AskEventPayloadSchema,
|
|
30800
30815
|
"ask.answered": AskEventPayloadSchema,
|
|
30816
|
+
"ask.resolved": AskEventPayloadSchema,
|
|
30801
30817
|
"comment.created": CommentEventPayloadSchema,
|
|
30802
30818
|
"comment.resolved": CommentEventPayloadSchema,
|
|
30803
30819
|
"suggestion.accepted": CommentEventPayloadSchema,
|
|
@@ -31180,6 +31196,9 @@ class DispatchClient {
|
|
|
31180
31196
|
async ask(issue, input) {
|
|
31181
31197
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "asks"], input);
|
|
31182
31198
|
}
|
|
31199
|
+
async resolveAsk(id, input) {
|
|
31200
|
+
return this.#json("POST", ["api", "v1", "asks", id, "resolve"], input);
|
|
31201
|
+
}
|
|
31183
31202
|
async comment(issue, input) {
|
|
31184
31203
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "comments"], input);
|
|
31185
31204
|
}
|
|
@@ -31398,7 +31417,7 @@ function toolSchema(tool) {
|
|
|
31398
31417
|
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
31399
31418
|
}
|
|
31400
31419
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
31401
|
-
if (tool === "dispatch_issue")
|
|
31420
|
+
if (tool === "dispatch_issue" || tool === "dispatch_resolve_ask")
|
|
31402
31421
|
return { args, ref: null };
|
|
31403
31422
|
const refArgument = args.ref;
|
|
31404
31423
|
const ref = typeof refArgument === "string" ? parseDispatchRef(refArgument) ?? (() => {
|
|
@@ -31505,6 +31524,12 @@ function askSummary({ ask, replies }) {
|
|
|
31505
31524
|
`- Selected: ${answer.selected.length === 0 ? "none" : answer.selected.join(", ")}`,
|
|
31506
31525
|
...answer.text === null ? [] : [`- Text: ${answer.text}`]
|
|
31507
31526
|
],
|
|
31527
|
+
...ask.resolution === undefined ? [] : [
|
|
31528
|
+
"Resolution:",
|
|
31529
|
+
`- By: ${ask.resolution.actor.id}`,
|
|
31530
|
+
`- Kind: ${ask.resolution.kind}`,
|
|
31531
|
+
`- Reason: ${ask.resolution.reason}`
|
|
31532
|
+
],
|
|
31508
31533
|
"Replies:",
|
|
31509
31534
|
...chain.length === 0 ? ["- none"] : chain
|
|
31510
31535
|
].join(`
|
|
@@ -31549,7 +31574,7 @@ async function executeDispatchTool(input) {
|
|
|
31549
31574
|
const args = toolSchema(input.tool).parse(issueArguments.args);
|
|
31550
31575
|
const actor = toolActor(await resolveOrigin(env, exec, input.cwd), input);
|
|
31551
31576
|
const client = new DispatchClient(input.config.url, input.config.token, input.fetchImpl);
|
|
31552
|
-
const issueKey = input.tool === "dispatch_issue" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
31577
|
+
const issueKey = input.tool === "dispatch_issue" || input.tool === "dispatch_resolve_ask" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
31553
31578
|
const issue = () => {
|
|
31554
31579
|
if (issueKey === null)
|
|
31555
31580
|
throw new Error("issue is required");
|
|
@@ -31573,6 +31598,26 @@ async function executeDispatchTool(input) {
|
|
|
31573
31598
|
details: { issue: created.key, topic: dispatchIssueSubject(created.key, ">") }
|
|
31574
31599
|
};
|
|
31575
31600
|
}
|
|
31601
|
+
case "dispatch_resolve_ask": {
|
|
31602
|
+
const kind = stringArg(args, "kind");
|
|
31603
|
+
if (kind !== "retracted" && kind !== "resolved")
|
|
31604
|
+
throw new Error("kind must be retracted or resolved");
|
|
31605
|
+
const ask = await client.resolveAsk(stringArg(args, "ask"), {
|
|
31606
|
+
kind,
|
|
31607
|
+
reason: stringArg(args, "reason"),
|
|
31608
|
+
actor
|
|
31609
|
+
});
|
|
31610
|
+
if (ask.resolution === undefined)
|
|
31611
|
+
throw new Error("resolved ask is missing its resolution");
|
|
31612
|
+
return {
|
|
31613
|
+
text: `${kind === "retracted" ? "Retracted" : "Resolved"} ask ${ask.id}: ${ask.resolution.reason}`,
|
|
31614
|
+
details: {
|
|
31615
|
+
issue: ask.issue_key,
|
|
31616
|
+
topic: dispatchIssueSubject(ask.issue_key, ">"),
|
|
31617
|
+
ask: ask.id
|
|
31618
|
+
}
|
|
31619
|
+
};
|
|
31620
|
+
}
|
|
31576
31621
|
case "dispatch_ask": {
|
|
31577
31622
|
const anchorArgs = asObject(args.anchor);
|
|
31578
31623
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
package/dist/legion.js
CHANGED
|
@@ -29669,7 +29669,13 @@ var ArtifactVersionEventPayloadSchema = object({
|
|
|
29669
29669
|
var AskEventPayloadSchema = object({
|
|
29670
29670
|
question: string2().optional(),
|
|
29671
29671
|
options: array(object({ label: string2().optional() })).nullish(),
|
|
29672
|
-
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish()
|
|
29672
|
+
answer: object({ selected: array(string2()).nullish(), text: string2().nullish() }).nullish(),
|
|
29673
|
+
resolution: object({
|
|
29674
|
+
kind: _enum2(["retracted", "resolved"]).optional(),
|
|
29675
|
+
reason: string2().optional(),
|
|
29676
|
+
actor: object({ kind: string2().optional(), id: string2().optional() }).passthrough().optional(),
|
|
29677
|
+
at: string2().optional()
|
|
29678
|
+
}).nullish()
|
|
29673
29679
|
});
|
|
29674
29680
|
var CommentEventPayloadSchema = object({
|
|
29675
29681
|
artifact_name: string2().optional(),
|
|
@@ -29725,6 +29731,15 @@ var dispatchToolSpecs = [
|
|
|
29725
29731
|
}).describe("Optional document location for the question.").optional()
|
|
29726
29732
|
})
|
|
29727
29733
|
},
|
|
29734
|
+
{
|
|
29735
|
+
name: "dispatch_resolve_ask",
|
|
29736
|
+
description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
|
|
29737
|
+
arguments: (z) => ({
|
|
29738
|
+
ask: z.string().describe("Ask id to close."),
|
|
29739
|
+
kind: z.enum(["retracted", "resolved"]).describe("Whether the ask is retracted or self-resolved."),
|
|
29740
|
+
reason: z.string({ min: 1 }).describe("Why the open ask no longer needs a human answer.")
|
|
29741
|
+
})
|
|
29742
|
+
},
|
|
29728
29743
|
{
|
|
29729
29744
|
name: "dispatch_comment",
|
|
29730
29745
|
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}`,
|
|
@@ -31290,6 +31305,7 @@ var DISPATCH_PAYLOAD_SCHEMAS = {
|
|
|
31290
31305
|
"artifact.version": ArtifactVersionEventPayloadSchema,
|
|
31291
31306
|
"ask.opened": AskEventPayloadSchema,
|
|
31292
31307
|
"ask.answered": AskEventPayloadSchema,
|
|
31308
|
+
"ask.resolved": AskEventPayloadSchema,
|
|
31293
31309
|
"comment.created": CommentEventPayloadSchema,
|
|
31294
31310
|
"comment.resolved": CommentEventPayloadSchema,
|
|
31295
31311
|
"suggestion.accepted": CommentEventPayloadSchema,
|
|
@@ -31665,6 +31681,9 @@ class DispatchClient {
|
|
|
31665
31681
|
async ask(issue, input) {
|
|
31666
31682
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "asks"], input);
|
|
31667
31683
|
}
|
|
31684
|
+
async resolveAsk(id, input) {
|
|
31685
|
+
return this.#json("POST", ["api", "v1", "asks", id, "resolve"], input);
|
|
31686
|
+
}
|
|
31668
31687
|
async comment(issue, input) {
|
|
31669
31688
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "comments"], input);
|
|
31670
31689
|
}
|
|
@@ -31883,7 +31902,7 @@ function toolSchema(tool) {
|
|
|
31883
31902
|
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
31884
31903
|
}
|
|
31885
31904
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
31886
|
-
if (tool === "dispatch_issue")
|
|
31905
|
+
if (tool === "dispatch_issue" || tool === "dispatch_resolve_ask")
|
|
31887
31906
|
return { args, ref: null };
|
|
31888
31907
|
const refArgument = args.ref;
|
|
31889
31908
|
const ref = typeof refArgument === "string" ? parseDispatchRef(refArgument) ?? (() => {
|
|
@@ -31990,6 +32009,12 @@ function askSummary({ ask, replies }) {
|
|
|
31990
32009
|
`- Selected: ${answer.selected.length === 0 ? "none" : answer.selected.join(", ")}`,
|
|
31991
32010
|
...answer.text === null ? [] : [`- Text: ${answer.text}`]
|
|
31992
32011
|
],
|
|
32012
|
+
...ask.resolution === undefined ? [] : [
|
|
32013
|
+
"Resolution:",
|
|
32014
|
+
`- By: ${ask.resolution.actor.id}`,
|
|
32015
|
+
`- Kind: ${ask.resolution.kind}`,
|
|
32016
|
+
`- Reason: ${ask.resolution.reason}`
|
|
32017
|
+
],
|
|
31993
32018
|
"Replies:",
|
|
31994
32019
|
...chain.length === 0 ? ["- none"] : chain
|
|
31995
32020
|
].join(`
|
|
@@ -32034,7 +32059,7 @@ async function executeDispatchTool(input) {
|
|
|
32034
32059
|
const args = toolSchema(input.tool).parse(issueArguments.args);
|
|
32035
32060
|
const actor = toolActor(await resolveOrigin(env, exec, input.cwd), input);
|
|
32036
32061
|
const client = new DispatchClient(input.config.url, input.config.token, input.fetchImpl);
|
|
32037
|
-
const issueKey = input.tool === "dispatch_issue" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
32062
|
+
const issueKey = input.tool === "dispatch_issue" || input.tool === "dispatch_resolve_ask" ? null : await ensureIssue(client, stringArg(args, "issue"), actor);
|
|
32038
32063
|
const issue = () => {
|
|
32039
32064
|
if (issueKey === null)
|
|
32040
32065
|
throw new Error("issue is required");
|
|
@@ -32058,6 +32083,26 @@ async function executeDispatchTool(input) {
|
|
|
32058
32083
|
details: { issue: created.key, topic: dispatchIssueSubject(created.key, ">") }
|
|
32059
32084
|
};
|
|
32060
32085
|
}
|
|
32086
|
+
case "dispatch_resolve_ask": {
|
|
32087
|
+
const kind = stringArg(args, "kind");
|
|
32088
|
+
if (kind !== "retracted" && kind !== "resolved")
|
|
32089
|
+
throw new Error("kind must be retracted or resolved");
|
|
32090
|
+
const ask = await client.resolveAsk(stringArg(args, "ask"), {
|
|
32091
|
+
kind,
|
|
32092
|
+
reason: stringArg(args, "reason"),
|
|
32093
|
+
actor
|
|
32094
|
+
});
|
|
32095
|
+
if (ask.resolution === undefined)
|
|
32096
|
+
throw new Error("resolved ask is missing its resolution");
|
|
32097
|
+
return {
|
|
32098
|
+
text: `${kind === "retracted" ? "Retracted" : "Resolved"} ask ${ask.id}: ${ask.resolution.reason}`,
|
|
32099
|
+
details: {
|
|
32100
|
+
issue: ask.issue_key,
|
|
32101
|
+
topic: dispatchIssueSubject(ask.issue_key, ">"),
|
|
32102
|
+
ask: ask.id
|
|
32103
|
+
}
|
|
32104
|
+
};
|
|
32105
|
+
}
|
|
32061
32106
|
case "dispatch_ask": {
|
|
32062
32107
|
const anchorArgs = asObject(args.anchor);
|
|
32063
32108
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
|
@@ -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
|