@sjawhar/pi-legion-envoy 0.18.3 → 0.20.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/envoy.js +43 -12
- package/dist/legion.js +43 -12
- package/dist/skills/dispatch/SKILL.md +11 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,6 +118,10 @@ The shared contract supplies the model-facing schemas and descriptions. The
|
|
|
118
118
|
`dispatch` skill describes when to use each operation for issues, asks, review
|
|
119
119
|
feedback, documents, artifacts, and status reads.
|
|
120
120
|
|
|
121
|
+
`dispatch_artifact` accepts exactly one upload source: a local `path`, or inline `content`.
|
|
122
|
+
For example, an architect can post its primary specification with
|
|
123
|
+
`{ issue, name: "spec.md", content: "# Design", primary: true }`.
|
|
124
|
+
|
|
121
125
|
Lifecycle and scope decisions between Legion roles go through `envoy_publish` to the owning
|
|
122
126
|
architect's role topic; Dispatch is for durable questions to the human and the shared
|
|
123
127
|
document, not for coordination between roles.
|
package/dist/envoy.js
CHANGED
|
@@ -29687,6 +29687,10 @@ var ChildStatusEventPayloadSchema = object({
|
|
|
29687
29687
|
to: string2().optional()
|
|
29688
29688
|
});
|
|
29689
29689
|
// ../contracts/src/dispatch-tools.ts
|
|
29690
|
+
function dispatchToolSchema(spec, z, opts) {
|
|
29691
|
+
const shape = spec.arguments(z);
|
|
29692
|
+
return spec.validation === undefined ? z.object(shape, opts) : z.refineObject(shape, spec.validation.check, spec.validation.message, opts);
|
|
29693
|
+
}
|
|
29690
29694
|
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).";
|
|
29691
29695
|
var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
29692
29696
|
var DOC_EDIT_OPS = ["replace", "delete", "insert"];
|
|
@@ -29713,7 +29717,6 @@ var dispatchToolSpecs = [
|
|
|
29713
29717
|
description: z.string().describe("Optional option context.").optional()
|
|
29714
29718
|
}), { max: 8 }).describe("Optional choices, at most 8.").optional(),
|
|
29715
29719
|
multiple: z.boolean().describe("Whether multiple choices may be selected.").optional(),
|
|
29716
|
-
custom: z.boolean().describe("Whether a free-text answer is allowed.").optional(),
|
|
29717
29720
|
urgency: z.enum(ASK_URGENCIES).describe("Optional decision urgency.").optional(),
|
|
29718
29721
|
anchor: z.object({
|
|
29719
29722
|
artifact: z.string().describe("Artifact slug or id containing the quoted text."),
|
|
@@ -29784,14 +29787,22 @@ var dispatchToolSpecs = [
|
|
|
29784
29787
|
},
|
|
29785
29788
|
{
|
|
29786
29789
|
name: "dispatch_artifact",
|
|
29787
|
-
description: "
|
|
29790
|
+
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}`,
|
|
29788
29791
|
arguments: (z) => ({
|
|
29789
29792
|
issue: z.string().describe(ISSUE_REFERENCE),
|
|
29790
29793
|
name: z.string().describe("Artifact filename shown in Dispatch."),
|
|
29791
|
-
path: z.string().describe("Local path to the file to upload."),
|
|
29794
|
+
path: z.string().describe("Local path to the file to upload.").optional(),
|
|
29795
|
+
content: z.string().describe("Inline text to store as a Markdown document.").optional(),
|
|
29792
29796
|
primary: z.boolean().describe("Make this document the issue primary artifact.").optional(),
|
|
29793
29797
|
summary: z.string().describe("Optional version summary.").optional()
|
|
29794
|
-
})
|
|
29798
|
+
}),
|
|
29799
|
+
validation: {
|
|
29800
|
+
check: (value) => {
|
|
29801
|
+
const input = value;
|
|
29802
|
+
return typeof input.path === "string" !== (typeof input.content === "string");
|
|
29803
|
+
},
|
|
29804
|
+
message: "Exactly one of path or content is required."
|
|
29805
|
+
}
|
|
29795
29806
|
},
|
|
29796
29807
|
{
|
|
29797
29808
|
name: "dispatch_read",
|
|
@@ -30199,7 +30210,18 @@ function zodSchemaApi(zod) {
|
|
|
30199
30210
|
schema = schema.max(opts.max);
|
|
30200
30211
|
return schema;
|
|
30201
30212
|
},
|
|
30202
|
-
object: (shape) =>
|
|
30213
|
+
object: (shape, opts = {}) => {
|
|
30214
|
+
let schema = api.object(shape);
|
|
30215
|
+
if (opts.strict)
|
|
30216
|
+
schema = schema.strict();
|
|
30217
|
+
return schema;
|
|
30218
|
+
},
|
|
30219
|
+
refineObject: (shape, check, message, opts = {}) => {
|
|
30220
|
+
let schema = api.object(shape);
|
|
30221
|
+
if (opts.strict)
|
|
30222
|
+
schema = schema.strict();
|
|
30223
|
+
return schema.refine(check, message);
|
|
30224
|
+
}
|
|
30203
30225
|
};
|
|
30204
30226
|
}
|
|
30205
30227
|
// ../envoy-client/src/defaults.ts
|
|
@@ -31177,6 +31199,9 @@ class DispatchClient {
|
|
|
31177
31199
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "messages"], input);
|
|
31178
31200
|
}
|
|
31179
31201
|
async artifact(issue, input) {
|
|
31202
|
+
const artifactPath = ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"];
|
|
31203
|
+
if ("content" in input)
|
|
31204
|
+
return this.#json("POST", artifactPath, input);
|
|
31180
31205
|
const form = new FormData;
|
|
31181
31206
|
form.set("name", input.name);
|
|
31182
31207
|
if (input.primary !== undefined)
|
|
@@ -31186,7 +31211,7 @@ class DispatchClient {
|
|
|
31186
31211
|
if (input.actor !== undefined)
|
|
31187
31212
|
form.set("actor", JSON.stringify(input.actor));
|
|
31188
31213
|
form.set("file", input.file, input.name);
|
|
31189
|
-
return this.#form("POST",
|
|
31214
|
+
return this.#form("POST", artifactPath, form);
|
|
31190
31215
|
}
|
|
31191
31216
|
async getArtifact(id) {
|
|
31192
31217
|
return this.#json("GET", ["api", "v1", "artifacts", id]);
|
|
@@ -31371,7 +31396,7 @@ function toolSchema(tool) {
|
|
|
31371
31396
|
const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
|
|
31372
31397
|
if (!spec)
|
|
31373
31398
|
throw new Error(`Unknown Dispatch tool: ${tool}`);
|
|
31374
|
-
return
|
|
31399
|
+
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
31375
31400
|
}
|
|
31376
31401
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
31377
31402
|
if (tool === "dispatch_issue")
|
|
@@ -31548,14 +31573,12 @@ async function executeDispatchTool(input) {
|
|
|
31548
31573
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
|
31549
31574
|
const options = args.options;
|
|
31550
31575
|
const multiple = optionalBoolean(args, "multiple");
|
|
31551
|
-
const custom = optionalBoolean(args, "custom");
|
|
31552
31576
|
const urgency = askUrgency(args);
|
|
31553
31577
|
const anchored = anchorArgs && resolved ? anchor(resolved.artifact, anchorArgs) : undefined;
|
|
31554
31578
|
const ask = await client.ask(issue(), {
|
|
31555
31579
|
question: stringArg(args, "question"),
|
|
31556
31580
|
...Array.isArray(options) ? { options } : {},
|
|
31557
31581
|
...multiple === undefined ? {} : { multiple },
|
|
31558
|
-
...custom === undefined ? {} : { custom },
|
|
31559
31582
|
...urgency === undefined ? {} : { urgency },
|
|
31560
31583
|
...anchored === undefined ? {} : { anchor: anchored },
|
|
31561
31584
|
actor
|
|
@@ -31655,12 +31678,20 @@ Open anchored asks/comments: ${marks.join(", ")}`,
|
|
|
31655
31678
|
case "dispatch_artifact": {
|
|
31656
31679
|
const primary = optionalBoolean(args, "primary");
|
|
31657
31680
|
const summary = optionalString(args, "summary");
|
|
31658
|
-
const
|
|
31659
|
-
|
|
31681
|
+
const name = stringArg(args, "name");
|
|
31682
|
+
const content = optionalString(args, "content");
|
|
31683
|
+
const result = await client.artifact(issue(), content === undefined ? {
|
|
31684
|
+
name,
|
|
31660
31685
|
file: Bun.file(resolvePath(input.cwd, stringArg(args, "path"))),
|
|
31661
31686
|
...primary === undefined ? {} : { primary },
|
|
31662
31687
|
...summary === undefined ? {} : { summary },
|
|
31663
31688
|
actor
|
|
31689
|
+
} : {
|
|
31690
|
+
name,
|
|
31691
|
+
content,
|
|
31692
|
+
...primary === undefined ? {} : { primary },
|
|
31693
|
+
...summary === undefined ? {} : { summary },
|
|
31694
|
+
actor
|
|
31664
31695
|
});
|
|
31665
31696
|
return {
|
|
31666
31697
|
text: `Uploaded ${result.artifact.name} as version ${result.version.number}`,
|
|
@@ -32573,7 +32604,7 @@ function envoyExtension(pi) {
|
|
|
32573
32604
|
name: spec.name,
|
|
32574
32605
|
label: spec.name,
|
|
32575
32606
|
description: spec.description,
|
|
32576
|
-
parameters:
|
|
32607
|
+
parameters: dispatchToolSchema(spec, zodSchemaApi(pi.zod)),
|
|
32577
32608
|
execute: async (_id, params, _signal, _onUpdate, context) => {
|
|
32578
32609
|
try {
|
|
32579
32610
|
const result = await executeDispatchTool({
|
package/dist/legion.js
CHANGED
|
@@ -29685,6 +29685,10 @@ var ChildStatusEventPayloadSchema = object({
|
|
|
29685
29685
|
to: string2().optional()
|
|
29686
29686
|
});
|
|
29687
29687
|
// ../contracts/src/dispatch-tools.ts
|
|
29688
|
+
function dispatchToolSchema(spec, z, opts) {
|
|
29689
|
+
const shape = spec.arguments(z);
|
|
29690
|
+
return spec.validation === undefined ? z.object(shape, opts) : z.refineObject(shape, spec.validation.check, spec.validation.message, opts);
|
|
29691
|
+
}
|
|
29688
29692
|
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).";
|
|
29689
29693
|
var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
29690
29694
|
var DOC_EDIT_OPS = ["replace", "delete", "insert"];
|
|
@@ -29711,7 +29715,6 @@ var dispatchToolSpecs = [
|
|
|
29711
29715
|
description: z.string().describe("Optional option context.").optional()
|
|
29712
29716
|
}), { max: 8 }).describe("Optional choices, at most 8.").optional(),
|
|
29713
29717
|
multiple: z.boolean().describe("Whether multiple choices may be selected.").optional(),
|
|
29714
|
-
custom: z.boolean().describe("Whether a free-text answer is allowed.").optional(),
|
|
29715
29718
|
urgency: z.enum(ASK_URGENCIES).describe("Optional decision urgency.").optional(),
|
|
29716
29719
|
anchor: z.object({
|
|
29717
29720
|
artifact: z.string().describe("Artifact slug or id containing the quoted text."),
|
|
@@ -29782,14 +29785,22 @@ var dispatchToolSpecs = [
|
|
|
29782
29785
|
},
|
|
29783
29786
|
{
|
|
29784
29787
|
name: "dispatch_artifact",
|
|
29785
|
-
description: "
|
|
29788
|
+
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}`,
|
|
29786
29789
|
arguments: (z) => ({
|
|
29787
29790
|
issue: z.string().describe(ISSUE_REFERENCE),
|
|
29788
29791
|
name: z.string().describe("Artifact filename shown in Dispatch."),
|
|
29789
|
-
path: z.string().describe("Local path to the file to upload."),
|
|
29792
|
+
path: z.string().describe("Local path to the file to upload.").optional(),
|
|
29793
|
+
content: z.string().describe("Inline text to store as a Markdown document.").optional(),
|
|
29790
29794
|
primary: z.boolean().describe("Make this document the issue primary artifact.").optional(),
|
|
29791
29795
|
summary: z.string().describe("Optional version summary.").optional()
|
|
29792
|
-
})
|
|
29796
|
+
}),
|
|
29797
|
+
validation: {
|
|
29798
|
+
check: (value) => {
|
|
29799
|
+
const input = value;
|
|
29800
|
+
return typeof input.path === "string" !== (typeof input.content === "string");
|
|
29801
|
+
},
|
|
29802
|
+
message: "Exactly one of path or content is required."
|
|
29803
|
+
}
|
|
29793
29804
|
},
|
|
29794
29805
|
{
|
|
29795
29806
|
name: "dispatch_read",
|
|
@@ -30197,7 +30208,18 @@ function zodSchemaApi(zod) {
|
|
|
30197
30208
|
schema = schema.max(opts.max);
|
|
30198
30209
|
return schema;
|
|
30199
30210
|
},
|
|
30200
|
-
object: (shape) =>
|
|
30211
|
+
object: (shape, opts = {}) => {
|
|
30212
|
+
let schema = api.object(shape);
|
|
30213
|
+
if (opts.strict)
|
|
30214
|
+
schema = schema.strict();
|
|
30215
|
+
return schema;
|
|
30216
|
+
},
|
|
30217
|
+
refineObject: (shape, check, message, opts = {}) => {
|
|
30218
|
+
let schema = api.object(shape);
|
|
30219
|
+
if (opts.strict)
|
|
30220
|
+
schema = schema.strict();
|
|
30221
|
+
return schema.refine(check, message);
|
|
30222
|
+
}
|
|
30201
30223
|
};
|
|
30202
30224
|
}
|
|
30203
30225
|
// ../envoy-client/src/defaults.ts
|
|
@@ -31662,6 +31684,9 @@ class DispatchClient {
|
|
|
31662
31684
|
return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "messages"], input);
|
|
31663
31685
|
}
|
|
31664
31686
|
async artifact(issue, input) {
|
|
31687
|
+
const artifactPath = ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"];
|
|
31688
|
+
if ("content" in input)
|
|
31689
|
+
return this.#json("POST", artifactPath, input);
|
|
31665
31690
|
const form = new FormData;
|
|
31666
31691
|
form.set("name", input.name);
|
|
31667
31692
|
if (input.primary !== undefined)
|
|
@@ -31671,7 +31696,7 @@ class DispatchClient {
|
|
|
31671
31696
|
if (input.actor !== undefined)
|
|
31672
31697
|
form.set("actor", JSON.stringify(input.actor));
|
|
31673
31698
|
form.set("file", input.file, input.name);
|
|
31674
|
-
return this.#form("POST",
|
|
31699
|
+
return this.#form("POST", artifactPath, form);
|
|
31675
31700
|
}
|
|
31676
31701
|
async getArtifact(id) {
|
|
31677
31702
|
return this.#json("GET", ["api", "v1", "artifacts", id]);
|
|
@@ -31856,7 +31881,7 @@ function toolSchema(tool) {
|
|
|
31856
31881
|
const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
|
|
31857
31882
|
if (!spec)
|
|
31858
31883
|
throw new Error(`Unknown Dispatch tool: ${tool}`);
|
|
31859
|
-
return
|
|
31884
|
+
return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
|
|
31860
31885
|
}
|
|
31861
31886
|
async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
31862
31887
|
if (tool === "dispatch_issue")
|
|
@@ -32033,14 +32058,12 @@ async function executeDispatchTool(input) {
|
|
|
32033
32058
|
const resolved = anchorArgs ? await resolveArtifact(client, issue(), stringArg(anchorArgs, "artifact")) : undefined;
|
|
32034
32059
|
const options = args.options;
|
|
32035
32060
|
const multiple = optionalBoolean(args, "multiple");
|
|
32036
|
-
const custom = optionalBoolean(args, "custom");
|
|
32037
32061
|
const urgency = askUrgency(args);
|
|
32038
32062
|
const anchored = anchorArgs && resolved ? anchor(resolved.artifact, anchorArgs) : undefined;
|
|
32039
32063
|
const ask = await client.ask(issue(), {
|
|
32040
32064
|
question: stringArg(args, "question"),
|
|
32041
32065
|
...Array.isArray(options) ? { options } : {},
|
|
32042
32066
|
...multiple === undefined ? {} : { multiple },
|
|
32043
|
-
...custom === undefined ? {} : { custom },
|
|
32044
32067
|
...urgency === undefined ? {} : { urgency },
|
|
32045
32068
|
...anchored === undefined ? {} : { anchor: anchored },
|
|
32046
32069
|
actor
|
|
@@ -32140,12 +32163,20 @@ Open anchored asks/comments: ${marks.join(", ")}`,
|
|
|
32140
32163
|
case "dispatch_artifact": {
|
|
32141
32164
|
const primary = optionalBoolean(args, "primary");
|
|
32142
32165
|
const summary = optionalString(args, "summary");
|
|
32143
|
-
const
|
|
32144
|
-
|
|
32166
|
+
const name = stringArg(args, "name");
|
|
32167
|
+
const content = optionalString(args, "content");
|
|
32168
|
+
const result = await client.artifact(issue(), content === undefined ? {
|
|
32169
|
+
name,
|
|
32145
32170
|
file: Bun.file(resolvePath(input.cwd, stringArg(args, "path"))),
|
|
32146
32171
|
...primary === undefined ? {} : { primary },
|
|
32147
32172
|
...summary === undefined ? {} : { summary },
|
|
32148
32173
|
actor
|
|
32174
|
+
} : {
|
|
32175
|
+
name,
|
|
32176
|
+
content,
|
|
32177
|
+
...primary === undefined ? {} : { primary },
|
|
32178
|
+
...summary === undefined ? {} : { summary },
|
|
32179
|
+
actor
|
|
32149
32180
|
});
|
|
32150
32181
|
return {
|
|
32151
32182
|
text: `Uploaded ${result.artifact.name} as version ${result.version.number}`,
|
|
@@ -33050,7 +33081,7 @@ function envoyExtension(pi) {
|
|
|
33050
33081
|
name: spec.name,
|
|
33051
33082
|
label: spec.name,
|
|
33052
33083
|
description: spec.description,
|
|
33053
|
-
parameters:
|
|
33084
|
+
parameters: dispatchToolSchema(spec, zodSchemaApi(pi.zod)),
|
|
33054
33085
|
execute: async (_id, params, _signal, _onUpdate, context) => {
|
|
33055
33086
|
try {
|
|
33056
33087
|
const result = await executeDispatchTool({
|
|
@@ -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",
|