@sjawhar/pi-legion-envoy 1.51.1 → 1.51.2

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/dist/envoy.js CHANGED
@@ -29908,6 +29908,7 @@ var DOC_EDIT_OPS = ["replace", "delete", "insert", "retype", "move"];
29908
29908
  var dispatchToolSpecs = [
29909
29909
  {
29910
29910
  name: "dispatch_issue",
29911
+ example: { project: "DSP", title: "Native workspace" },
29911
29912
  description: "Create a native Dispatch issue for newly tracked work. Search first with dispatch_search; if potentially duplicate issues exist, this returns 409 POSSIBLE_DUPLICATE unless force is true after reading them. " + `Do not use it when an existing issue already covers the work; read or update that issue instead. ${ISSUE_REFERENCE}`,
29912
29913
  arguments: (z) => ({
29913
29914
  project: z.string().describe("Project key for the new issue."),
@@ -29924,6 +29925,7 @@ var dispatchToolSpecs = [
29924
29925
  },
29925
29926
  {
29926
29927
  name: "dispatch_issue_update",
29928
+ example: { issue: "DSP-1", status: "in_progress" },
29927
29929
  description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, link a URL " + "(the pull request that delivers it, a run, a document), set its route, set or clear its parent, " + "or attach it to architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment and is allowed on a " + "closed issue. Priority is the human's and is not settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
29928
29930
  arguments: (z) => ({
29929
29931
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -29946,6 +29948,7 @@ var dispatchToolSpecs = [
29946
29948
  },
29947
29949
  {
29948
29950
  name: "dispatch_ask",
29951
+ example: { issue: "DSP-1", question: "Ship this?" },
29949
29952
  description: "Open a durable, answerable decision on an issue or project document. Do not use it for a status update or discussion; " + "use dispatch_message instead. A to-do a human must complete is a question phrased as that to-do, with the options you want (for example Done / Can't). " + "Anchor a document question, thread reply_to/reply_to_ask, or cite a dispatch:// " + `reference \u2014 it must be answerable from its own text and anchor alone, never "see above". A quote anchor is pinned to its block. Question is at most ${ASK_QUESTION_MAX} ` + `characters and has at most 8 options. ${OWNER_REFERENCE}`,
29950
29953
  arguments: (z) => ({
29951
29954
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29969,6 +29972,10 @@ var dispatchToolSpecs = [
29969
29972
  },
29970
29973
  {
29971
29974
  name: "dispatch_edit_ask",
29975
+ example: {
29976
+ ask: "01234567-0000-4000-8000-000000000001",
29977
+ question: "Ship the revised plan?"
29978
+ },
29972
29979
  description: "Edit an open question in place. Use it to correct or refine the same decision; retract the " + "old ask and open a new one when the decision itself changes. Previous text remains in the " + "event log. Only the asking session can edit it; answered or resolved asks cannot be edited.",
29973
29980
  arguments: (z) => ({
29974
29981
  ask: z.string().describe("Ask id to edit."),
@@ -29990,6 +29997,11 @@ var dispatchToolSpecs = [
29990
29997
  },
29991
29998
  {
29992
29999
  name: "dispatch_resolve_ask",
30000
+ example: {
30001
+ ask: "01234567-0000-4000-8000-000000000001",
30002
+ kind: "retracted",
30003
+ reason: "A newer question supersedes this one."
30004
+ },
29993
30005
  description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
29994
30006
  arguments: (z) => ({
29995
30007
  ask: z.string().describe("Ask id to close."),
@@ -29999,6 +30011,7 @@ var dispatchToolSpecs = [
29999
30011
  },
30000
30012
  {
30001
30013
  name: "dispatch_resolve_comment",
30014
+ example: { comment: "01234567-0000-4000-8000-000000000001" },
30002
30015
  description: "Resolve a review comment thread once it has been addressed - typically your own comment " + "after the document was fixed. Any session or human may resolve any open comment on an " + "open issue or project document; reopening a resolved comment is human-only (the dashboard). " + "Not for asks: use dispatch_resolve_ask.",
30003
30016
  arguments: (z) => ({
30004
30017
  comment: z.string().describe("Comment id (uuid), or a dispatch://KEY/comment/<id> or " + "dispatch://PROJECT/artifact/<slug>/comment/<id> reference; a reference accepts an " + "8+ character id prefix that is unique on its owner.")
@@ -30007,6 +30020,7 @@ var dispatchToolSpecs = [
30007
30020
  },
30008
30021
  {
30009
30022
  name: "dispatch_follow",
30023
+ example: { ask: "01234567-0000-4000-8000-000000000001", action: "follow" },
30010
30024
  description: "Follow or unfollow an ask. Every session that opens or replies to an ask follows it: its answer, " + "edits, resolution, and replies reach that session directly. Unfollow to stop; follow to rejoin or " + "to hear an ask you never wrote to. Whole-issue subscription is separate: envoy_subscribe " + "notifications.dispatch.issue.<KEY>.>",
30011
30025
  arguments: (z) => ({
30012
30026
  ask: z.string().describe("Full ask id (uuid)."),
@@ -30016,6 +30030,7 @@ var dispatchToolSpecs = [
30016
30030
  },
30017
30031
  {
30018
30032
  name: "dispatch_comment",
30033
+ example: { issue: "DSP-1", body: "Looks good." },
30019
30034
  description: "Add review feedback to an issue or project document quote, or reply to a question asked with dispatch_ask. " + "Do not use it for an exact replacement; use " + `dispatch_suggest instead. A quote anchor is pinned to its block. Body is at most 2,000 characters. ${OWNER_REFERENCE}`,
30020
30035
  arguments: (z) => ({
30021
30036
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30033,6 +30048,12 @@ var dispatchToolSpecs = [
30033
30048
  },
30034
30049
  {
30035
30050
  name: "dispatch_suggest",
30051
+ example: {
30052
+ issue: "DSP-1",
30053
+ artifact: "spec",
30054
+ quote: "old wording",
30055
+ replace_with: "new wording"
30056
+ },
30036
30057
  description: "Propose an exact replacement for quoted document text. Do not use it for general feedback; use " + `dispatch_comment instead. Optional explanation is at most 2,000 characters. ${OWNER_REFERENCE}`,
30037
30058
  arguments: (z) => ({
30038
30059
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30048,6 +30069,7 @@ var dispatchToolSpecs = [
30048
30069
  },
30049
30070
  {
30050
30071
  name: "dispatch_message",
30072
+ example: { issue: "DSP-1", body: "Implementation started." },
30051
30073
  description: "Post a note humans must read now: a reply to a human's message, a deliverable that landed, or a blocker only " + "they can clear. Never progress or status updates - Dispatch is a high-signal record, not a log. Not a decision " + `(dispatch_ask) or document feedback (dispatch_comment). Body is at most 2,000 characters. ${ISSUE_REFERENCE}`,
30052
30074
  arguments: (z) => ({
30053
30075
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -30057,6 +30079,11 @@ var dispatchToolSpecs = [
30057
30079
  },
30058
30080
  {
30059
30081
  name: "dispatch_doc_edit",
30082
+ example: {
30083
+ issue: "DSP-1",
30084
+ artifact: "spec",
30085
+ ops: [{ op: "replace", find: "old", with: "new" }]
30086
+ },
30060
30087
  description: "Apply deterministic document edits: replace or delete quoted text, insert markdown at an anchor, retype an identified paragraph or typed block into a schema-declared typed block, and delete or move a whole block by its id. " + "Do not use it for review feedback or for reading; use dispatch_comment, dispatch_suggest, or dispatch_doc_read instead. " + "For replace, delete, and quote anchors, find text as rendered: inline Markdown (**bold**, `code`) is tolerated; a leading '# ' matches a heading. replace is inline: with is the new text of the matched span, so a leading list or heading marker stays literal text. " + "A delete whose find is a block's entire text removes the block (a list emptied of its items goes too); delete with block removes any block by id, and move with block relocates one. " + 'Insert and move anchors also accept "start", "end", "heading:<exact heading text>", and "block:<id>"; block ids are the #id of a typed block or a row of GET /api/v1/artifacts/{id}/blocks. ' + `The spec (or any document) holds requirements, design, and decisions - never progress, status, or timestamps. ${OWNER_REFERENCE} ${SPEC_WRITING_GUIDANCE}`,
30061
30088
  arguments: (z) => ({
30062
30089
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30081,6 +30108,7 @@ var dispatchToolSpecs = [
30081
30108
  },
30082
30109
  {
30083
30110
  name: "dispatch_doc_read",
30111
+ example: { issue: "DSP-1" },
30084
30112
  description: "Read a live document or a named document version. Do not use it for issue status, asks, or events; " + "use dispatch_read instead. Supply ref, issue, or project plus artifact; issue plus an omitted artifact reads the primary document. " + OWNER_REFERENCE,
30085
30113
  arguments: (z) => ({
30086
30114
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30093,6 +30121,7 @@ var dispatchToolSpecs = [
30093
30121
  },
30094
30122
  {
30095
30123
  name: "dispatch_request_approval",
30124
+ example: { issue: "DSP-1" },
30096
30125
  description: "Ask a human to approve a document at its current version - the exception path for a spec " + "that departs from what was settled or proposes children, not a step for every issue. Opens an " + "approval ask (Approve / Request changes) in the human's Inbox; the answer pins a review to the " + "document version and arrives as artifact.approved or artifact.changes_requested. A later edit " + "makes an approval stale; request again for the new version. Idempotent while a request is open. " + OWNER_REFERENCE,
30097
30126
  arguments: (z) => ({
30098
30127
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30103,6 +30132,8 @@ var dispatchToolSpecs = [
30103
30132
  },
30104
30133
  {
30105
30134
  name: "dispatch_artifact",
30135
+ example: { issue: "DSP-1", name: "design.md", content: `# Design
30136
+ ` },
30106
30137
  description: "Attach a local file or inline text as an issue artifact or project document. 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. ${OWNER_REFERENCE}`,
30107
30138
  arguments: (z) => ({
30108
30139
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30122,6 +30153,7 @@ var dispatchToolSpecs = [
30122
30153
  },
30123
30154
  {
30124
30155
  name: "dispatch_read",
30156
+ example: { issue: "DSP-1" },
30125
30157
  description: "Read an issue or project-document summary, targeted ask, or targeted comment reply chain. Do not use it for document " + "contents; use dispatch_doc_read instead. Supply ref, issue, or project plus artifact. " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + OWNER_REFERENCE,
30126
30158
  arguments: (z) => ({
30127
30159
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -30133,6 +30165,7 @@ var dispatchToolSpecs = [
30133
30165
  },
30134
30166
  {
30135
30167
  name: "dispatch_search",
30168
+ example: { query: "astrolabe" },
30136
30169
  description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR.',
30137
30170
  arguments: (z) => ({
30138
30171
  query: z.string({ min: 2 }).describe("Keyword, phrase, or websearch expression; at least 2 characters."),
@@ -30142,6 +30175,7 @@ var dispatchToolSpecs = [
30142
30175
  },
30143
30176
  {
30144
30177
  name: "dispatch_issues",
30178
+ example: { project: "AGENTC" },
30145
30179
  description: "List a project's issues for a roadmap or backlog pass: every issue in one project, each carrying " + "its status, priority, parent, labels, and open-ask count, so you can see backlog shape without " + "opening every issue. Optionally filter by status, parent, label, or how recently it changed. Do " + "not use it to search by keyword or phrase; dispatch_search remains the keyword surface. Rows are " + "capped at limit (default 50, max 250), applied to the response here, not by the server.",
30146
30180
  arguments: (z) => ({
30147
30181
  project: z.string().describe("Project key to list issues from."),
@@ -30154,6 +30188,7 @@ var dispatchToolSpecs = [
30154
30188
  },
30155
30189
  {
30156
30190
  name: "dispatch_architecture_sync",
30191
+ example: { project: "CORE" },
30157
30192
  description: "Import a project's architecture model from its configured source repository now, instead of " + "waiting for the server's five-minute schedule. Returns the imported commit and component " + "count, or the recorded error when the model was rejected (the previous model stays up). " + "The source itself is configured by a human in Settings; 404 SOURCE_NOT_FOUND without one.",
30158
30193
  arguments: (z) => ({
30159
30194
  project: z.string().describe("Project key whose architecture source to sync, such as CORE.")
@@ -30162,6 +30197,7 @@ var dispatchToolSpecs = [
30162
30197
  },
30163
30198
  {
30164
30199
  name: "dispatch_open_asks",
30200
+ example: {},
30165
30201
  description: "List active unanswered asks, oldest first, with age and whose reply is needed. Omit project to " + "see only this session's own authored asks (call before saying you are waiting for human input); " + "supply project to see every open ask across that project's issues and documents, whoever authored " + "them.",
30166
30202
  arguments: (z) => ({
30167
30203
  project: z.string().describe("Project key; when supplied, lists every open ask in the project instead of only this session's own.").optional()
@@ -30170,6 +30206,7 @@ var dispatchToolSpecs = [
30170
30206
  },
30171
30207
  {
30172
30208
  name: "dispatch_whoami",
30209
+ example: {},
30173
30210
  description: "Who Dispatch takes this session for: {session, owner}. owner is the lowercase GitHub login of the human whose personal token you run under (the default assignee of issues you create), or null under the shared token.",
30174
30211
  arguments: () => ({}),
30175
30212
  strict: true
@@ -32260,9 +32297,11 @@ class ToolInputError extends Error {
32260
32297
  problems;
32261
32298
  constructor(tool, problems) {
32262
32299
  const count = problems.length;
32300
+ const help = dispatchInputHelp(tool);
32263
32301
  super([
32264
32302
  `${tool} was not called: ${count} problem${count === 1 ? "" : "s"}`,
32265
- ...problems.map((problem) => `- ${problem}`)
32303
+ ...problems.map((problem) => `- ${problem}`),
32304
+ ...help === undefined ? [] : help.map((line) => `- ${line}`)
32266
32305
  ].join(`
32267
32306
  `));
32268
32307
  this.name = "ToolInputError";
@@ -32270,6 +32309,14 @@ class ToolInputError extends Error {
32270
32309
  this.problems = problems;
32271
32310
  }
32272
32311
  }
32312
+ function dispatchInputHelp(tool) {
32313
+ const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
32314
+ if (spec === undefined)
32315
+ return;
32316
+ const schema = dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
32317
+ const allowed = Object.keys(shapeOf(schema) ?? {}).join(", ") || "none";
32318
+ return [`Allowed keys: ${allowed}`, `Example: ${tool}(${JSON.stringify(spec.example)})`];
32319
+ }
32273
32320
  function unwrap(schema) {
32274
32321
  let current = schema;
32275
32322
  while (current !== undefined) {
@@ -32574,7 +32621,21 @@ function refTarget(ref, kind, id) {
32574
32621
  const ownerRef = ref.owner.kind === "issue" ? dispatchIssueRef(ref.owner.issue) : dispatchDocumentRef(ref.owner.project, `${ref.artifact}`);
32575
32622
  return dispatchChildRef(ownerRef, kind, id);
32576
32623
  }
32577
- var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
32624
+ var canonicalUUIDPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
32625
+ var compactUUIDPattern = /^[0-9a-f]{32}$/i;
32626
+ function normalizeUUID(value) {
32627
+ let compact = value;
32628
+ if (value.slice(0, 9).toLowerCase() === "urn:uuid:") {
32629
+ compact = value.slice(9);
32630
+ } else if (value.length === 38 && value.startsWith("{") && value.endsWith("}")) {
32631
+ compact = value.slice(1, -1);
32632
+ }
32633
+ if (canonicalUUIDPattern.test(compact))
32634
+ compact = compact.replaceAll("-", "");
32635
+ if (!compactUUIDPattern.test(compact))
32636
+ return;
32637
+ return `${compact.slice(0, 8)}-${compact.slice(8, 12)}-${compact.slice(12, 16)}-${compact.slice(16, 20)}-${compact.slice(20)}`.toLowerCase();
32638
+ }
32578
32639
  var askIdProblem = "ask must be a bare ask id or a dispatch://.../ask/<id> reference";
32579
32640
  var commentIdProblem = "comment must be a bare comment id or a dispatch://.../comment/<id> reference";
32580
32641
  var messageIdProblem = "in_reply_to must be a full message id (uuid) or a dispatch://KEY/message/<id> reference";
@@ -32587,12 +32648,13 @@ function messageIdOf(value) {
32587
32648
  const reference = parseDispatchRef(value);
32588
32649
  return reference?.kind === "message" ? reference.id : undefined;
32589
32650
  })() : value;
32590
- return id !== undefined && uuidPattern.test(id) ? id : undefined;
32651
+ return id === undefined ? undefined : normalizeUUID(id);
32591
32652
  }
32592
32653
  var idPrefixPattern = /^[0-9a-f][0-9a-f-]{7,}$/i;
32593
32654
  async function resolveIdPrefix(tool, kind, ref, list) {
32594
- if (uuidPattern.test(ref.id))
32595
- return ref.id;
32655
+ const fullID = normalizeUUID(ref.id);
32656
+ if (fullID !== undefined)
32657
+ return fullID;
32596
32658
  const ownerName = ref.owner.kind === "issue" ? ref.owner.issue : `${ref.owner.project}/${ref.artifact}`;
32597
32659
  if (!idPrefixPattern.test(ref.id)) {
32598
32660
  throw new ToolInputError(tool, [
@@ -32824,21 +32886,53 @@ async function resolveArtifact(client, owner, artifactReference) {
32824
32886
  return { owner, artifact };
32825
32887
  const names = artifacts.filter((candidate) => candidate.name === artifactReference);
32826
32888
  if (names.length > 1) {
32827
- throw new Error(`artifact name ${artifactReference} is ambiguous in project ${owner.project}; ` + `${names.length} documents share it \u2014 use its slug instead`);
32889
+ throw new Error(documentReferenceProblem(artifactReference, names, "project", true));
32890
+ }
32891
+ if (names[0] === undefined) {
32892
+ throw new Error(documentReferenceProblem(artifactReference, artifacts, "project"));
32828
32893
  }
32829
- if (names[0] === undefined)
32830
- throw error;
32831
32894
  return { owner, artifact: names[0] };
32832
32895
  }
32833
32896
  }
32834
32897
  const issue = await client.getIssue(owner.issue);
32835
- const artifact = artifactReference === undefined || artifactReference === "spec" ? issue.artifacts.find((candidate) => candidate.primary || candidate.id === issue.primary_artifact_id) : issue.artifacts.find((candidate) => candidate.id === artifactReference || candidate.slug === artifactReference || candidate.name === artifactReference);
32898
+ let artifact;
32899
+ if (artifactReference === undefined || artifactReference === "spec") {
32900
+ artifact = issue.artifacts.find((candidate) => candidate.primary || candidate.id === issue.primary_artifact_id);
32901
+ } else {
32902
+ artifact = issue.artifacts.find((candidate) => candidate.id === artifactReference || candidate.slug === artifactReference);
32903
+ if (artifact === undefined) {
32904
+ const names = issue.artifacts.filter((candidate) => candidate.name === artifactReference);
32905
+ if (names.length > 1) {
32906
+ throw new Error(documentReferenceProblem(artifactReference, names, "issue", true));
32907
+ }
32908
+ artifact = names[0];
32909
+ }
32910
+ }
32836
32911
  if (!artifact) {
32837
- const slugs = issue.artifacts.map((candidate) => `${candidate.slug}${candidate.primary || candidate.id === issue.primary_artifact_id ? " (primary)" : ""}`);
32838
- throw new Error(`artifact "${artifactReference ?? "spec"}" was not found on issue ${issue.key}; artifacts: ${slugs.length === 0 ? "none" : slugs.join(", ")}`);
32912
+ throw new Error(documentReferenceProblem(artifactReference ?? "spec", issue.artifacts, "issue"));
32839
32913
  }
32840
32914
  return { owner, issue, artifact };
32841
32915
  }
32916
+ var documentHintLimit = 8;
32917
+ function documentReferenceProblem(reference, documents, owner, ambiguous = false) {
32918
+ const hints = documents.slice(0, documentHintLimit).map((document) => `${document.slug} (${document.name})`);
32919
+ const list = hints.length === 0 ? "none" : hints.join(", ");
32920
+ return ambiguous ? `"${reference}" names ${documents.length} documents on this ${owner}; use a slug: ${list}` : `document "${reference}" not found by slug; this ${owner}'s documents: ${list}`;
32921
+ }
32922
+ var askHintLimit = 8;
32923
+ function askIDInputProblem(asks, scope) {
32924
+ const hints = asks.slice(0, askHintLimit).map((ask) => `${ask.id.slice(0, 8)}\u2026 ${textHead(ask.question)}`);
32925
+ return `ask IDs are UUIDs; use the full ask ID; ${scope} open asks: ${hints.length === 0 ? "none" : hints.join(", ")}`;
32926
+ }
32927
+ async function invalidReplyToAskProblem(client, owner, resolved) {
32928
+ if (owner.kind === "issue") {
32929
+ const issue = resolved?.issue ?? await client.getIssue(owner.issue);
32930
+ return askIDInputProblem(issue.open_asks, "this issue's");
32931
+ }
32932
+ if (resolved === undefined)
32933
+ throw new Error("project document is missing its resolved artifact");
32934
+ return askIDInputProblem(await client.getArtifactAsks(resolved.artifact.id, "open"), "this document's");
32935
+ }
32842
32936
  function anchor(artifact, args) {
32843
32937
  const quote = optionalString(args, "quote");
32844
32938
  if (quote === undefined)
@@ -33442,7 +33536,13 @@ ${followsAsk(askOwner)}`,
33442
33536
  const resolved = owner.kind === "project" || artifactReference === undefined ? owner.kind === "project" ? await resolveArtifact(client, owner, artifactReference) : undefined : await resolveArtifact(client, owner, artifactReference);
33443
33537
  const anchored = resolved ? anchor(resolved.artifact, args) : undefined;
33444
33538
  const replyTo = optionalString(args, "reply_to");
33445
- const replyToAsk = optionalString(args, "reply_to_ask");
33539
+ const replyToAskReference = optionalString(args, "reply_to_ask");
33540
+ const replyToAsk = replyToAskReference === undefined ? undefined : normalizeUUID(replyToAskReference);
33541
+ if (replyToAskReference !== undefined && replyToAsk === undefined) {
33542
+ throw new ToolInputError(input.tool, [
33543
+ await invalidReplyToAskProblem(client, owner, resolved)
33544
+ ]);
33545
+ }
33446
33546
  const requestedTurn = optionalString(args, "turn");
33447
33547
  const commentInput = {
33448
33548
  body: stringArg(args, "body"),
package/dist/legion.js CHANGED
@@ -16145,7 +16145,7 @@ import { logger } from "@oh-my-pi/pi-utils";
16145
16145
  // package.json
16146
16146
  var package_default = {
16147
16147
  name: "@sjawhar/pi-legion-envoy",
16148
- version: "1.51.1",
16148
+ version: "1.51.2",
16149
16149
  type: "module",
16150
16150
  omp: {
16151
16151
  extensions: [
@@ -29227,6 +29227,7 @@ var DOC_EDIT_OPS = ["replace", "delete", "insert", "retype", "move"];
29227
29227
  var dispatchToolSpecs = [
29228
29228
  {
29229
29229
  name: "dispatch_issue",
29230
+ example: { project: "DSP", title: "Native workspace" },
29230
29231
  description: "Create a native Dispatch issue for newly tracked work. Search first with dispatch_search; if potentially duplicate issues exist, this returns 409 POSSIBLE_DUPLICATE unless force is true after reading them. " + `Do not use it when an existing issue already covers the work; read or update that issue instead. ${ISSUE_REFERENCE}`,
29231
29232
  arguments: (z) => ({
29232
29233
  project: z.string().describe("Project key for the new issue."),
@@ -29243,6 +29244,7 @@ var dispatchToolSpecs = [
29243
29244
  },
29244
29245
  {
29245
29246
  name: "dispatch_issue_update",
29247
+ example: { issue: "DSP-1", status: "in_progress" },
29246
29248
  description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, link a URL " + "(the pull request that delivers it, a run, a document), set its route, set or clear its parent, " + "or attach it to architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. external_links are " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link. components replaces the issue's own attachment and is allowed on a " + "closed issue. Priority is the human's and is not settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
29247
29249
  arguments: (z) => ({
29248
29250
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -29265,6 +29267,7 @@ var dispatchToolSpecs = [
29265
29267
  },
29266
29268
  {
29267
29269
  name: "dispatch_ask",
29270
+ example: { issue: "DSP-1", question: "Ship this?" },
29268
29271
  description: "Open a durable, answerable decision on an issue or project document. Do not use it for a status update or discussion; " + "use dispatch_message instead. A to-do a human must complete is a question phrased as that to-do, with the options you want (for example Done / Can't). " + "Anchor a document question, thread reply_to/reply_to_ask, or cite a dispatch:// " + `reference \u2014 it must be answerable from its own text and anchor alone, never "see above". A quote anchor is pinned to its block. Question is at most ${ASK_QUESTION_MAX} ` + `characters and has at most 8 options. ${OWNER_REFERENCE}`,
29269
29272
  arguments: (z) => ({
29270
29273
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29288,6 +29291,10 @@ var dispatchToolSpecs = [
29288
29291
  },
29289
29292
  {
29290
29293
  name: "dispatch_edit_ask",
29294
+ example: {
29295
+ ask: "01234567-0000-4000-8000-000000000001",
29296
+ question: "Ship the revised plan?"
29297
+ },
29291
29298
  description: "Edit an open question in place. Use it to correct or refine the same decision; retract the " + "old ask and open a new one when the decision itself changes. Previous text remains in the " + "event log. Only the asking session can edit it; answered or resolved asks cannot be edited.",
29292
29299
  arguments: (z) => ({
29293
29300
  ask: z.string().describe("Ask id to edit."),
@@ -29309,6 +29316,11 @@ var dispatchToolSpecs = [
29309
29316
  },
29310
29317
  {
29311
29318
  name: "dispatch_resolve_ask",
29319
+ example: {
29320
+ ask: "01234567-0000-4000-8000-000000000001",
29321
+ kind: "retracted",
29322
+ reason: "A newer question supersedes this one."
29323
+ },
29312
29324
  description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
29313
29325
  arguments: (z) => ({
29314
29326
  ask: z.string().describe("Ask id to close."),
@@ -29318,6 +29330,7 @@ var dispatchToolSpecs = [
29318
29330
  },
29319
29331
  {
29320
29332
  name: "dispatch_resolve_comment",
29333
+ example: { comment: "01234567-0000-4000-8000-000000000001" },
29321
29334
  description: "Resolve a review comment thread once it has been addressed - typically your own comment " + "after the document was fixed. Any session or human may resolve any open comment on an " + "open issue or project document; reopening a resolved comment is human-only (the dashboard). " + "Not for asks: use dispatch_resolve_ask.",
29322
29335
  arguments: (z) => ({
29323
29336
  comment: z.string().describe("Comment id (uuid), or a dispatch://KEY/comment/<id> or " + "dispatch://PROJECT/artifact/<slug>/comment/<id> reference; a reference accepts an " + "8+ character id prefix that is unique on its owner.")
@@ -29326,6 +29339,7 @@ var dispatchToolSpecs = [
29326
29339
  },
29327
29340
  {
29328
29341
  name: "dispatch_follow",
29342
+ example: { ask: "01234567-0000-4000-8000-000000000001", action: "follow" },
29329
29343
  description: "Follow or unfollow an ask. Every session that opens or replies to an ask follows it: its answer, " + "edits, resolution, and replies reach that session directly. Unfollow to stop; follow to rejoin or " + "to hear an ask you never wrote to. Whole-issue subscription is separate: envoy_subscribe " + "notifications.dispatch.issue.<KEY>.>",
29330
29344
  arguments: (z) => ({
29331
29345
  ask: z.string().describe("Full ask id (uuid)."),
@@ -29335,6 +29349,7 @@ var dispatchToolSpecs = [
29335
29349
  },
29336
29350
  {
29337
29351
  name: "dispatch_comment",
29352
+ example: { issue: "DSP-1", body: "Looks good." },
29338
29353
  description: "Add review feedback to an issue or project document quote, or reply to a question asked with dispatch_ask. " + "Do not use it for an exact replacement; use " + `dispatch_suggest instead. A quote anchor is pinned to its block. Body is at most 2,000 characters. ${OWNER_REFERENCE}`,
29339
29354
  arguments: (z) => ({
29340
29355
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29352,6 +29367,12 @@ var dispatchToolSpecs = [
29352
29367
  },
29353
29368
  {
29354
29369
  name: "dispatch_suggest",
29370
+ example: {
29371
+ issue: "DSP-1",
29372
+ artifact: "spec",
29373
+ quote: "old wording",
29374
+ replace_with: "new wording"
29375
+ },
29355
29376
  description: "Propose an exact replacement for quoted document text. Do not use it for general feedback; use " + `dispatch_comment instead. Optional explanation is at most 2,000 characters. ${OWNER_REFERENCE}`,
29356
29377
  arguments: (z) => ({
29357
29378
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29367,6 +29388,7 @@ var dispatchToolSpecs = [
29367
29388
  },
29368
29389
  {
29369
29390
  name: "dispatch_message",
29391
+ example: { issue: "DSP-1", body: "Implementation started." },
29370
29392
  description: "Post a note humans must read now: a reply to a human's message, a deliverable that landed, or a blocker only " + "they can clear. Never progress or status updates - Dispatch is a high-signal record, not a log. Not a decision " + `(dispatch_ask) or document feedback (dispatch_comment). Body is at most 2,000 characters. ${ISSUE_REFERENCE}`,
29371
29393
  arguments: (z) => ({
29372
29394
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -29376,6 +29398,11 @@ var dispatchToolSpecs = [
29376
29398
  },
29377
29399
  {
29378
29400
  name: "dispatch_doc_edit",
29401
+ example: {
29402
+ issue: "DSP-1",
29403
+ artifact: "spec",
29404
+ ops: [{ op: "replace", find: "old", with: "new" }]
29405
+ },
29379
29406
  description: "Apply deterministic document edits: replace or delete quoted text, insert markdown at an anchor, retype an identified paragraph or typed block into a schema-declared typed block, and delete or move a whole block by its id. " + "Do not use it for review feedback or for reading; use dispatch_comment, dispatch_suggest, or dispatch_doc_read instead. " + "For replace, delete, and quote anchors, find text as rendered: inline Markdown (**bold**, `code`) is tolerated; a leading '# ' matches a heading. replace is inline: with is the new text of the matched span, so a leading list or heading marker stays literal text. " + "A delete whose find is a block's entire text removes the block (a list emptied of its items goes too); delete with block removes any block by id, and move with block relocates one. " + 'Insert and move anchors also accept "start", "end", "heading:<exact heading text>", and "block:<id>"; block ids are the #id of a typed block or a row of GET /api/v1/artifacts/{id}/blocks. ' + `The spec (or any document) holds requirements, design, and decisions - never progress, status, or timestamps. ${OWNER_REFERENCE} ${SPEC_WRITING_GUIDANCE}`,
29380
29407
  arguments: (z) => ({
29381
29408
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29400,6 +29427,7 @@ var dispatchToolSpecs = [
29400
29427
  },
29401
29428
  {
29402
29429
  name: "dispatch_doc_read",
29430
+ example: { issue: "DSP-1" },
29403
29431
  description: "Read a live document or a named document version. Do not use it for issue status, asks, or events; " + "use dispatch_read instead. Supply ref, issue, or project plus artifact; issue plus an omitted artifact reads the primary document. " + OWNER_REFERENCE,
29404
29432
  arguments: (z) => ({
29405
29433
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29412,6 +29440,7 @@ var dispatchToolSpecs = [
29412
29440
  },
29413
29441
  {
29414
29442
  name: "dispatch_request_approval",
29443
+ example: { issue: "DSP-1" },
29415
29444
  description: "Ask a human to approve a document at its current version - the exception path for a spec " + "that departs from what was settled or proposes children, not a step for every issue. Opens an " + "approval ask (Approve / Request changes) in the human's Inbox; the answer pins a review to the " + "document version and arrives as artifact.approved or artifact.changes_requested. A later edit " + "makes an approval stale; request again for the new version. Idempotent while a request is open. " + OWNER_REFERENCE,
29416
29445
  arguments: (z) => ({
29417
29446
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29422,6 +29451,8 @@ var dispatchToolSpecs = [
29422
29451
  },
29423
29452
  {
29424
29453
  name: "dispatch_artifact",
29454
+ example: { issue: "DSP-1", name: "design.md", content: `# Design
29455
+ ` },
29425
29456
  description: "Attach a local file or inline text as an issue artifact or project document. 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. ${OWNER_REFERENCE}`,
29426
29457
  arguments: (z) => ({
29427
29458
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29441,6 +29472,7 @@ var dispatchToolSpecs = [
29441
29472
  },
29442
29473
  {
29443
29474
  name: "dispatch_read",
29475
+ example: { issue: "DSP-1" },
29444
29476
  description: "Read an issue or project-document summary, targeted ask, or targeted comment reply chain. Do not use it for document " + "contents; use dispatch_doc_read instead. Supply ref, issue, or project plus artifact. " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + OWNER_REFERENCE,
29445
29477
  arguments: (z) => ({
29446
29478
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -29452,6 +29484,7 @@ var dispatchToolSpecs = [
29452
29484
  },
29453
29485
  {
29454
29486
  name: "dispatch_search",
29487
+ example: { query: "astrolabe" },
29455
29488
  description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR.',
29456
29489
  arguments: (z) => ({
29457
29490
  query: z.string({ min: 2 }).describe("Keyword, phrase, or websearch expression; at least 2 characters."),
@@ -29461,6 +29494,7 @@ var dispatchToolSpecs = [
29461
29494
  },
29462
29495
  {
29463
29496
  name: "dispatch_issues",
29497
+ example: { project: "AGENTC" },
29464
29498
  description: "List a project's issues for a roadmap or backlog pass: every issue in one project, each carrying " + "its status, priority, parent, labels, and open-ask count, so you can see backlog shape without " + "opening every issue. Optionally filter by status, parent, label, or how recently it changed. Do " + "not use it to search by keyword or phrase; dispatch_search remains the keyword surface. Rows are " + "capped at limit (default 50, max 250), applied to the response here, not by the server.",
29465
29499
  arguments: (z) => ({
29466
29500
  project: z.string().describe("Project key to list issues from."),
@@ -29473,6 +29507,7 @@ var dispatchToolSpecs = [
29473
29507
  },
29474
29508
  {
29475
29509
  name: "dispatch_architecture_sync",
29510
+ example: { project: "CORE" },
29476
29511
  description: "Import a project's architecture model from its configured source repository now, instead of " + "waiting for the server's five-minute schedule. Returns the imported commit and component " + "count, or the recorded error when the model was rejected (the previous model stays up). " + "The source itself is configured by a human in Settings; 404 SOURCE_NOT_FOUND without one.",
29477
29512
  arguments: (z) => ({
29478
29513
  project: z.string().describe("Project key whose architecture source to sync, such as CORE.")
@@ -29481,6 +29516,7 @@ var dispatchToolSpecs = [
29481
29516
  },
29482
29517
  {
29483
29518
  name: "dispatch_open_asks",
29519
+ example: {},
29484
29520
  description: "List active unanswered asks, oldest first, with age and whose reply is needed. Omit project to " + "see only this session's own authored asks (call before saying you are waiting for human input); " + "supply project to see every open ask across that project's issues and documents, whoever authored " + "them.",
29485
29521
  arguments: (z) => ({
29486
29522
  project: z.string().describe("Project key; when supplied, lists every open ask in the project instead of only this session's own.").optional()
@@ -29489,6 +29525,7 @@ var dispatchToolSpecs = [
29489
29525
  },
29490
29526
  {
29491
29527
  name: "dispatch_whoami",
29528
+ example: {},
29492
29529
  description: "Who Dispatch takes this session for: {session, owner}. owner is the lowercase GitHub login of the human whose personal token you run under (the default assignee of issues you create), or null under the shared token.",
29493
29530
  arguments: () => ({}),
29494
29531
  strict: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "1.51.1",
3
+ "version": "1.51.2",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [