@sjawhar/pi-legion-envoy 0.19.0 → 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"];
@@ -29783,14 +29787,22 @@ var dispatchToolSpecs = [
29783
29787
  },
29784
29788
  {
29785
29789
  name: "dispatch_artifact",
29786
- 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}`,
29787
29791
  arguments: (z) => ({
29788
29792
  issue: z.string().describe(ISSUE_REFERENCE),
29789
29793
  name: z.string().describe("Artifact filename shown in Dispatch."),
29790
- 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(),
29791
29796
  primary: z.boolean().describe("Make this document the issue primary artifact.").optional(),
29792
29797
  summary: z.string().describe("Optional version summary.").optional()
29793
- })
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
+ }
29794
29806
  },
29795
29807
  {
29796
29808
  name: "dispatch_read",
@@ -30198,7 +30210,18 @@ function zodSchemaApi(zod) {
30198
30210
  schema = schema.max(opts.max);
30199
30211
  return schema;
30200
30212
  },
30201
- 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
+ }
30202
30225
  };
30203
30226
  }
30204
30227
  // ../envoy-client/src/defaults.ts
@@ -31176,6 +31199,9 @@ class DispatchClient {
31176
31199
  return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "messages"], input);
31177
31200
  }
31178
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);
31179
31205
  const form = new FormData;
31180
31206
  form.set("name", input.name);
31181
31207
  if (input.primary !== undefined)
@@ -31185,7 +31211,7 @@ class DispatchClient {
31185
31211
  if (input.actor !== undefined)
31186
31212
  form.set("actor", JSON.stringify(input.actor));
31187
31213
  form.set("file", input.file, input.name);
31188
- return this.#form("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"], form);
31214
+ return this.#form("POST", artifactPath, form);
31189
31215
  }
31190
31216
  async getArtifact(id) {
31191
31217
  return this.#json("GET", ["api", "v1", "artifacts", id]);
@@ -31370,7 +31396,7 @@ function toolSchema(tool) {
31370
31396
  const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
31371
31397
  if (!spec)
31372
31398
  throw new Error(`Unknown Dispatch tool: ${tool}`);
31373
- return object(spec.arguments(zodSchemaApi(exports_external))).strict();
31399
+ return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
31374
31400
  }
31375
31401
  async function resolveIssueArguments(tool, args, cwd, env, exec) {
31376
31402
  if (tool === "dispatch_issue")
@@ -31652,12 +31678,20 @@ Open anchored asks/comments: ${marks.join(", ")}`,
31652
31678
  case "dispatch_artifact": {
31653
31679
  const primary = optionalBoolean(args, "primary");
31654
31680
  const summary = optionalString(args, "summary");
31655
- const result = await client.artifact(issue(), {
31656
- 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,
31657
31685
  file: Bun.file(resolvePath(input.cwd, stringArg(args, "path"))),
31658
31686
  ...primary === undefined ? {} : { primary },
31659
31687
  ...summary === undefined ? {} : { summary },
31660
31688
  actor
31689
+ } : {
31690
+ name,
31691
+ content,
31692
+ ...primary === undefined ? {} : { primary },
31693
+ ...summary === undefined ? {} : { summary },
31694
+ actor
31661
31695
  });
31662
31696
  return {
31663
31697
  text: `Uploaded ${result.artifact.name} as version ${result.version.number}`,
@@ -32570,7 +32604,7 @@ function envoyExtension(pi) {
32570
32604
  name: spec.name,
32571
32605
  label: spec.name,
32572
32606
  description: spec.description,
32573
- parameters: pi.zod.object(spec.arguments(zodSchemaApi(pi.zod))),
32607
+ parameters: dispatchToolSchema(spec, zodSchemaApi(pi.zod)),
32574
32608
  execute: async (_id, params, _signal, _onUpdate, context) => {
32575
32609
  try {
32576
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"];
@@ -29781,14 +29785,22 @@ var dispatchToolSpecs = [
29781
29785
  },
29782
29786
  {
29783
29787
  name: "dispatch_artifact",
29784
- 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}`,
29785
29789
  arguments: (z) => ({
29786
29790
  issue: z.string().describe(ISSUE_REFERENCE),
29787
29791
  name: z.string().describe("Artifact filename shown in Dispatch."),
29788
- 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(),
29789
29794
  primary: z.boolean().describe("Make this document the issue primary artifact.").optional(),
29790
29795
  summary: z.string().describe("Optional version summary.").optional()
29791
- })
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
+ }
29792
29804
  },
29793
29805
  {
29794
29806
  name: "dispatch_read",
@@ -30196,7 +30208,18 @@ function zodSchemaApi(zod) {
30196
30208
  schema = schema.max(opts.max);
30197
30209
  return schema;
30198
30210
  },
30199
- 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
+ }
30200
30223
  };
30201
30224
  }
30202
30225
  // ../envoy-client/src/defaults.ts
@@ -31661,6 +31684,9 @@ class DispatchClient {
31661
31684
  return this.#json("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "messages"], input);
31662
31685
  }
31663
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);
31664
31690
  const form = new FormData;
31665
31691
  form.set("name", input.name);
31666
31692
  if (input.primary !== undefined)
@@ -31670,7 +31696,7 @@ class DispatchClient {
31670
31696
  if (input.actor !== undefined)
31671
31697
  form.set("actor", JSON.stringify(input.actor));
31672
31698
  form.set("file", input.file, input.name);
31673
- return this.#form("POST", ["api", "v1", "issues", await this.#resolveIssue(issue), "artifacts"], form);
31699
+ return this.#form("POST", artifactPath, form);
31674
31700
  }
31675
31701
  async getArtifact(id) {
31676
31702
  return this.#json("GET", ["api", "v1", "artifacts", id]);
@@ -31855,7 +31881,7 @@ function toolSchema(tool) {
31855
31881
  const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
31856
31882
  if (!spec)
31857
31883
  throw new Error(`Unknown Dispatch tool: ${tool}`);
31858
- return object(spec.arguments(zodSchemaApi(exports_external))).strict();
31884
+ return dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
31859
31885
  }
31860
31886
  async function resolveIssueArguments(tool, args, cwd, env, exec) {
31861
31887
  if (tool === "dispatch_issue")
@@ -32137,12 +32163,20 @@ Open anchored asks/comments: ${marks.join(", ")}`,
32137
32163
  case "dispatch_artifact": {
32138
32164
  const primary = optionalBoolean(args, "primary");
32139
32165
  const summary = optionalString(args, "summary");
32140
- const result = await client.artifact(issue(), {
32141
- 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,
32142
32170
  file: Bun.file(resolvePath(input.cwd, stringArg(args, "path"))),
32143
32171
  ...primary === undefined ? {} : { primary },
32144
32172
  ...summary === undefined ? {} : { summary },
32145
32173
  actor
32174
+ } : {
32175
+ name,
32176
+ content,
32177
+ ...primary === undefined ? {} : { primary },
32178
+ ...summary === undefined ? {} : { summary },
32179
+ actor
32146
32180
  });
32147
32181
  return {
32148
32182
  text: `Uploaded ${result.artifact.name} as version ${result.version.number}`,
@@ -33047,7 +33081,7 @@ function envoyExtension(pi) {
33047
33081
  name: spec.name,
33048
33082
  label: spec.name,
33049
33083
  description: spec.description,
33050
- parameters: pi.zod.object(spec.arguments(zodSchemaApi(pi.zod))),
33084
+ parameters: dispatchToolSchema(spec, zodSchemaApi(pi.zod)),
33051
33085
  execute: async (_id, params, _signal, _onUpdate, context) => {
33052
33086
  try {
33053
33087
  const result = await executeDispatchTool({
@@ -105,15 +105,22 @@ invalid actor, route, or primary artifact.
105
105
 
106
106
  ## Artifacts
107
107
 
108
- Attach an image, diagram, or file with:
108
+ Attach an image, diagram, or local file with:
109
109
 
110
110
  ```ts
111
111
  dispatch_artifact({ issue, name, path, primary?, summary? })
112
112
  ```
113
113
 
114
- It returns `details` `{ issue, topic, artifact, version }`. `path` is the local file to upload.
115
- Uploading the same `name` creates its next version. Set `primary: true` only for a markdown file
116
- 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.
117
124
 
118
125
  ## Messages
119
126
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [