@sjawhar/opencode-legion-envoy 0.20.2 → 0.22.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 +4 -0
- package/dist/src/server.js +42 -11
- package/package.json +1 -1
- package/skills/dispatch/SKILL.md +11 -6
package/README.md
CHANGED
|
@@ -29,6 +29,10 @@ envoy.json (`~/.config/opencode/envoy.json`, merged with `<repo>/.opencode/envoy
|
|
|
29
29
|
the session working directory, stamps it with the OpenCode session id and title, and stores
|
|
30
30
|
`details.topic` as tool metadata so a successful mutation subscribes to that exact Dispatch topic.
|
|
31
31
|
|
|
32
|
+
`dispatch_artifact` accepts exactly one upload source: a local `path`, or inline `content`.
|
|
33
|
+
An architect can post a primary specification directly with
|
|
34
|
+
`{ issue, name: "spec.md", content: "# Design", primary: true }`.
|
|
35
|
+
|
|
32
36
|
It also maintains the live session registry metadata needed for Envoy to discover OpenCode sessions and their API ports.
|
|
33
37
|
|
|
34
38
|
Slack topic examples must use the real Slack `team_id`, for example:
|
package/dist/src/server.js
CHANGED
|
@@ -13590,6 +13590,10 @@ var ChildStatusEventPayloadSchema = object({
|
|
|
13590
13590
|
to: string2().optional()
|
|
13591
13591
|
});
|
|
13592
13592
|
// ../contracts/src/dispatch-tools.ts
|
|
13593
|
+
function dispatchToolSchema(spec, z, opts) {
|
|
13594
|
+
const shape = spec.arguments(z);
|
|
13595
|
+
return spec.validation === undefined ? z.object(shape, opts) : z.refineObject(shape, spec.validation.check, spec.validation.message, opts);
|
|
13596
|
+
}
|
|
13593
13597
|
var ISSUE_REFERENCE = "An issue is a native KEY or external owner/repo#n reference; an external reference creates its native issue on first use in the repository's mapped project (DISPATCH_REPO_PROJECTS) or, failing that, the default project (DISPATCH_DEFAULT_PROJECT).";
|
|
13594
13598
|
var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
13595
13599
|
var DOC_EDIT_OPS = ["replace", "delete", "insert"];
|
|
@@ -13616,7 +13620,6 @@ var dispatchToolSpecs = [
|
|
|
13616
13620
|
description: z.string().describe("Optional option context.").optional()
|
|
13617
13621
|
}), { max: 8 }).describe("Optional choices, at most 8.").optional(),
|
|
13618
13622
|
multiple: z.boolean().describe("Whether multiple choices may be selected.").optional(),
|
|
13619
|
-
custom: z.boolean().describe("Whether a free-text answer is allowed.").optional(),
|
|
13620
13623
|
urgency: z.enum(ASK_URGENCIES).describe("Optional decision urgency.").optional(),
|
|
13621
13624
|
anchor: z.object({
|
|
13622
13625
|
artifact: z.string().describe("Artifact slug or id containing the quoted text."),
|
|
@@ -13687,14 +13690,22 @@ var dispatchToolSpecs = [
|
|
|
13687
13690
|
},
|
|
13688
13691
|
{
|
|
13689
13692
|
name: "dispatch_artifact",
|
|
13690
|
-
description: "
|
|
13693
|
+
description: "Attach a local file or inline text as an issue artifact. Do not use it to edit a live document; use " + `dispatch_doc_edit instead. Exactly one of path or content is required; artifacts are limited to 25 MiB. ${ISSUE_REFERENCE}`,
|
|
13691
13694
|
arguments: (z) => ({
|
|
13692
13695
|
issue: z.string().describe(ISSUE_REFERENCE),
|
|
13693
13696
|
name: z.string().describe("Artifact filename shown in Dispatch."),
|
|
13694
|
-
path: z.string().describe("Local path to the file to upload."),
|
|
13697
|
+
path: z.string().describe("Local path to the file to upload.").optional(),
|
|
13698
|
+
content: z.string().describe("Inline text to store as a Markdown document.").optional(),
|
|
13695
13699
|
primary: z.boolean().describe("Make this document the issue primary artifact.").optional(),
|
|
13696
13700
|
summary: z.string().describe("Optional version summary.").optional()
|
|
13697
|
-
})
|
|
13701
|
+
}),
|
|
13702
|
+
validation: {
|
|
13703
|
+
check: (value) => {
|
|
13704
|
+
const input = value;
|
|
13705
|
+
return typeof input.path === "string" !== (typeof input.content === "string");
|
|
13706
|
+
},
|
|
13707
|
+
message: "Exactly one of path or content is required."
|
|
13708
|
+
}
|
|
13698
13709
|
},
|
|
13699
13710
|
{
|
|
13700
13711
|
name: "dispatch_read",
|
|
@@ -14082,7 +14093,18 @@ function zodSchemaApi(zod) {
|
|
|
14082
14093
|
schema = schema.max(opts.max);
|
|
14083
14094
|
return schema;
|
|
14084
14095
|
},
|
|
14085
|
-
object: (shape) =>
|
|
14096
|
+
object: (shape, opts = {}) => {
|
|
14097
|
+
let schema = api.object(shape);
|
|
14098
|
+
if (opts.strict)
|
|
14099
|
+
schema = schema.strict();
|
|
14100
|
+
return schema;
|
|
14101
|
+
},
|
|
14102
|
+
refineObject: (shape, check, message, opts = {}) => {
|
|
14103
|
+
let schema = api.object(shape);
|
|
14104
|
+
if (opts.strict)
|
|
14105
|
+
schema = schema.strict();
|
|
14106
|
+
return schema.refine(check, message);
|
|
14107
|
+
}
|
|
14086
14108
|
};
|
|
14087
14109
|
}
|
|
14088
14110
|
// ../envoy-client/src/defaults.ts
|
|
@@ -14351,6 +14373,9 @@ class DispatchClient {
|
|
|
14351
14373
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "messages"], input);
|
|
14352
14374
|
}
|
|
14353
14375
|
async artifact(issue, input) {
|
|
14376
|
+
const artifactPath = ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"];
|
|
14377
|
+
if ("content" in input)
|
|
14378
|
+
return this.#json("POST", artifactPath, input);
|
|
14354
14379
|
const form = new FormData;
|
|
14355
14380
|
form.set("name", input.name);
|
|
14356
14381
|
if (input.primary !== undefined)
|
|
@@ -14360,7 +14385,7 @@ class DispatchClient {
|
|
|
14360
14385
|
if (input.actor !== undefined)
|
|
14361
14386
|
form.set("actor", JSON.stringify(input.actor));
|
|
14362
14387
|
form.set("file", input.file, input.name);
|
|
14363
|
-
return this.#form("POST",
|
|
14388
|
+
return this.#form("POST", artifactPath, form);
|
|
14364
14389
|
}
|
|
14365
14390
|
async getArtifact(id) {
|
|
14366
14391
|
return this.#json("GET", ["api", "v1", "artifacts", id]);
|
|
@@ -14545,7 +14570,7 @@ function toolSchema(tool) {
|
|
|
14545
14570
|
const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
|
|
14546
14571
|
if (!spec)
|
|
14547
14572
|
throw new Error(`Unknown Dispatch tool: ${tool}`);
|
|
14548
|
-
return
|
|
14573
|
+
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
14549
14574
|
}
|
|
14550
14575
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
14551
14576
|
if (tool === "dispatch_issue")
|
|
@@ -14722,14 +14747,12 @@ async function executeDispatchTool(input) {
|
|
|
14722
14747
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
|
14723
14748
|
const options = args.options;
|
|
14724
14749
|
const multiple = optionalBoolean(args, "multiple");
|
|
14725
|
-
const custom = optionalBoolean(args, "custom");
|
|
14726
14750
|
const urgency = askUrgency(args);
|
|
14727
14751
|
const anchored = anchorArgs && resolved ? anchor(resolved.artifact, anchorArgs) : undefined;
|
|
14728
14752
|
const ask = await client.ask(issue(), {
|
|
14729
14753
|
question: stringArg(args, "question"),
|
|
14730
14754
|
...Array.isArray(options) ? { options } : {},
|
|
14731
14755
|
...multiple === undefined ? {} : { multiple },
|
|
14732
|
-
...custom === undefined ? {} : { custom },
|
|
14733
14756
|
...urgency === undefined ? {} : { urgency },
|
|
14734
14757
|
...anchored === undefined ? {} : { anchor: anchored },
|
|
14735
14758
|
actor
|
|
@@ -14829,12 +14852,20 @@ Open anchored asks/comments: ${marks.join(", ")}`,
|
|
|
14829
14852
|
case "dispatch_artifact": {
|
|
14830
14853
|
const primary = optionalBoolean(args, "primary");
|
|
14831
14854
|
const summary = optionalString(args, "summary");
|
|
14832
|
-
const
|
|
14833
|
-
|
|
14855
|
+
const name = stringArg(args, "name");
|
|
14856
|
+
const content = optionalString(args, "content");
|
|
14857
|
+
const result = await client.artifact(issue(), content === undefined ? {
|
|
14858
|
+
name,
|
|
14834
14859
|
file: Bun.file(resolvePath(input.cwd, stringArg(args, "path"))),
|
|
14835
14860
|
...primary === undefined ? {} : { primary },
|
|
14836
14861
|
...summary === undefined ? {} : { summary },
|
|
14837
14862
|
actor
|
|
14863
|
+
} : {
|
|
14864
|
+
name,
|
|
14865
|
+
content,
|
|
14866
|
+
...primary === undefined ? {} : { primary },
|
|
14867
|
+
...summary === undefined ? {} : { summary },
|
|
14868
|
+
actor
|
|
14838
14869
|
});
|
|
14839
14870
|
return {
|
|
14840
14871
|
text: `Uploaded ${result.artifact.name} as version ${result.version.number}`,
|
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -36,7 +36,6 @@ dispatch_ask({
|
|
|
36
36
|
question,
|
|
37
37
|
options?: { label, description? }[],
|
|
38
38
|
multiple?,
|
|
39
|
-
custom?,
|
|
40
39
|
urgency?,
|
|
41
40
|
anchor?: { artifact, quote, occurrence? },
|
|
42
41
|
})
|
|
@@ -106,15 +105,22 @@ invalid actor, route, or primary artifact.
|
|
|
106
105
|
|
|
107
106
|
## Artifacts
|
|
108
107
|
|
|
109
|
-
Attach an image, diagram, or file with:
|
|
108
|
+
Attach an image, diagram, or local file with:
|
|
110
109
|
|
|
111
110
|
```ts
|
|
112
111
|
dispatch_artifact({ issue, name, path, primary?, summary? })
|
|
113
112
|
```
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
Or, when the text is already in the call, post a Markdown document directly:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
dispatch_artifact({ issue, name: "spec.md", content: "# Design\n...", primary: true })
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Exactly one of `path` and `content` is required. The inline form sends JSON with
|
|
121
|
+
`Content-Type: application/json`. It returns `details` `{ issue, topic, artifact, version }`.
|
|
122
|
+
Uploading the same `name` creates its next version. Use `content` for an architect's primary spec;
|
|
123
|
+
set `primary: true` only for Markdown documents.
|
|
118
124
|
|
|
119
125
|
## Messages
|
|
120
126
|
|
|
@@ -191,7 +197,6 @@ dispatch_ask({
|
|
|
191
197
|
description: "Narrows the release but requires another deployment test.",
|
|
192
198
|
},
|
|
193
199
|
],
|
|
194
|
-
custom: false,
|
|
195
200
|
urgency: "high",
|
|
196
201
|
anchor: {
|
|
197
202
|
artifact: "spec",
|