@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 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: "Upload a local file as an issue artifact. Do not use it to edit a live document; use dispatch_doc_edit " + `instead. Files are limited to 25 MiB. ${ISSUE_REFERENCE}`,
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) => api.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", ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"], form);
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 object(spec.arguments(zodSchemaApi(exports_external))).strict();
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 result = await client.artifact(issue(), {
31659
- name: stringArg(args, "name"),
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: pi.zod.object(spec.arguments(zodSchemaApi(pi.zod))),
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: "Upload a local file as an issue artifact. Do not use it to edit a live document; use dispatch_doc_edit " + `instead. Files are limited to 25 MiB. ${ISSUE_REFERENCE}`,
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) => api.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", ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"], form);
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 object(spec.arguments(zodSchemaApi(exports_external))).strict();
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 result = await client.artifact(issue(), {
32144
- name: stringArg(args, "name"),
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: pi.zod.object(spec.arguments(zodSchemaApi(pi.zod))),
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
- It returns `details` `{ issue, topic, artifact, version }`. `path` is the local file to upload.
116
- Uploading the same `name` creates its next version. Set `primary: true` only for a markdown file
117
- to make it the issue's spec.
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "0.18.3",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [