@sjawhar/opencode-legion-envoy 1.40.1 → 1.40.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.
Files changed (2) hide show
  1. package/dist/src/server.js +112 -12
  2. package/package.json +1 -1
@@ -13808,6 +13808,7 @@ var DOC_EDIT_OPS = ["replace", "delete", "insert", "retype", "move"];
13808
13808
  var dispatchToolSpecs = [
13809
13809
  {
13810
13810
  name: "dispatch_issue",
13811
+ example: { project: "DSP", title: "Native workspace" },
13811
13812
  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}`,
13812
13813
  arguments: (z) => ({
13813
13814
  project: z.string().describe("Project key for the new issue."),
@@ -13824,6 +13825,7 @@ var dispatchToolSpecs = [
13824
13825
  },
13825
13826
  {
13826
13827
  name: "dispatch_issue_update",
13828
+ example: { issue: "DSP-1", status: "in_progress" },
13827
13829
  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}`,
13828
13830
  arguments: (z) => ({
13829
13831
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -13846,6 +13848,7 @@ var dispatchToolSpecs = [
13846
13848
  },
13847
13849
  {
13848
13850
  name: "dispatch_ask",
13851
+ example: { issue: "DSP-1", question: "Ship this?" },
13849
13852
  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}`,
13850
13853
  arguments: (z) => ({
13851
13854
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -13869,6 +13872,10 @@ var dispatchToolSpecs = [
13869
13872
  },
13870
13873
  {
13871
13874
  name: "dispatch_edit_ask",
13875
+ example: {
13876
+ ask: "01234567-0000-4000-8000-000000000001",
13877
+ question: "Ship the revised plan?"
13878
+ },
13872
13879
  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.",
13873
13880
  arguments: (z) => ({
13874
13881
  ask: z.string().describe("Ask id to edit."),
@@ -13890,6 +13897,11 @@ var dispatchToolSpecs = [
13890
13897
  },
13891
13898
  {
13892
13899
  name: "dispatch_resolve_ask",
13900
+ example: {
13901
+ ask: "01234567-0000-4000-8000-000000000001",
13902
+ kind: "retracted",
13903
+ reason: "A newer question supersedes this one."
13904
+ },
13893
13905
  description: "Retract an open question that is moot or resolve one after finding the answer. This closes the question without answering it.",
13894
13906
  arguments: (z) => ({
13895
13907
  ask: z.string().describe("Ask id to close."),
@@ -13899,6 +13911,7 @@ var dispatchToolSpecs = [
13899
13911
  },
13900
13912
  {
13901
13913
  name: "dispatch_resolve_comment",
13914
+ example: { comment: "01234567-0000-4000-8000-000000000001" },
13902
13915
  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.",
13903
13916
  arguments: (z) => ({
13904
13917
  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.")
@@ -13907,6 +13920,7 @@ var dispatchToolSpecs = [
13907
13920
  },
13908
13921
  {
13909
13922
  name: "dispatch_follow",
13923
+ example: { ask: "01234567-0000-4000-8000-000000000001", action: "follow" },
13910
13924
  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>.>",
13911
13925
  arguments: (z) => ({
13912
13926
  ask: z.string().describe("Full ask id (uuid)."),
@@ -13916,6 +13930,7 @@ var dispatchToolSpecs = [
13916
13930
  },
13917
13931
  {
13918
13932
  name: "dispatch_comment",
13933
+ example: { issue: "DSP-1", body: "Looks good." },
13919
13934
  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}`,
13920
13935
  arguments: (z) => ({
13921
13936
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -13933,6 +13948,12 @@ var dispatchToolSpecs = [
13933
13948
  },
13934
13949
  {
13935
13950
  name: "dispatch_suggest",
13951
+ example: {
13952
+ issue: "DSP-1",
13953
+ artifact: "spec",
13954
+ quote: "old wording",
13955
+ replace_with: "new wording"
13956
+ },
13936
13957
  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}`,
13937
13958
  arguments: (z) => ({
13938
13959
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -13948,6 +13969,7 @@ var dispatchToolSpecs = [
13948
13969
  },
13949
13970
  {
13950
13971
  name: "dispatch_message",
13972
+ example: { issue: "DSP-1", body: "Implementation started." },
13951
13973
  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}`,
13952
13974
  arguments: (z) => ({
13953
13975
  issue: z.string().describe(ISSUE_REFERENCE),
@@ -13957,6 +13979,11 @@ var dispatchToolSpecs = [
13957
13979
  },
13958
13980
  {
13959
13981
  name: "dispatch_doc_edit",
13982
+ example: {
13983
+ issue: "DSP-1",
13984
+ artifact: "spec",
13985
+ ops: [{ op: "replace", find: "old", with: "new" }]
13986
+ },
13960
13987
  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}`,
13961
13988
  arguments: (z) => ({
13962
13989
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -13981,6 +14008,7 @@ var dispatchToolSpecs = [
13981
14008
  },
13982
14009
  {
13983
14010
  name: "dispatch_doc_read",
14011
+ example: { issue: "DSP-1" },
13984
14012
  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,
13985
14013
  arguments: (z) => ({
13986
14014
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -13993,6 +14021,7 @@ var dispatchToolSpecs = [
13993
14021
  },
13994
14022
  {
13995
14023
  name: "dispatch_request_approval",
14024
+ example: { issue: "DSP-1" },
13996
14025
  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,
13997
14026
  arguments: (z) => ({
13998
14027
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -14003,6 +14032,8 @@ var dispatchToolSpecs = [
14003
14032
  },
14004
14033
  {
14005
14034
  name: "dispatch_artifact",
14035
+ example: { issue: "DSP-1", name: "design.md", content: `# Design
14036
+ ` },
14006
14037
  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}`,
14007
14038
  arguments: (z) => ({
14008
14039
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -14022,6 +14053,7 @@ var dispatchToolSpecs = [
14022
14053
  },
14023
14054
  {
14024
14055
  name: "dispatch_read",
14056
+ example: { issue: "DSP-1" },
14025
14057
  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,
14026
14058
  arguments: (z) => ({
14027
14059
  issue: z.string().describe(ISSUE_REFERENCE).optional(),
@@ -14033,6 +14065,7 @@ var dispatchToolSpecs = [
14033
14065
  },
14034
14066
  {
14035
14067
  name: "dispatch_search",
14068
+ example: { query: "astrolabe" },
14036
14069
  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.',
14037
14070
  arguments: (z) => ({
14038
14071
  query: z.string({ min: 2 }).describe("Keyword, phrase, or websearch expression; at least 2 characters."),
@@ -14042,6 +14075,7 @@ var dispatchToolSpecs = [
14042
14075
  },
14043
14076
  {
14044
14077
  name: "dispatch_issues",
14078
+ example: { project: "AGENTC" },
14045
14079
  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.",
14046
14080
  arguments: (z) => ({
14047
14081
  project: z.string().describe("Project key to list issues from."),
@@ -14054,6 +14088,7 @@ var dispatchToolSpecs = [
14054
14088
  },
14055
14089
  {
14056
14090
  name: "dispatch_architecture_sync",
14091
+ example: { project: "CORE" },
14057
14092
  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.",
14058
14093
  arguments: (z) => ({
14059
14094
  project: z.string().describe("Project key whose architecture source to sync, such as CORE.")
@@ -14062,6 +14097,7 @@ var dispatchToolSpecs = [
14062
14097
  },
14063
14098
  {
14064
14099
  name: "dispatch_open_asks",
14100
+ example: {},
14065
14101
  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.",
14066
14102
  arguments: (z) => ({
14067
14103
  project: z.string().describe("Project key; when supplied, lists every open ask in the project instead of only this session's own.").optional()
@@ -14070,6 +14106,7 @@ var dispatchToolSpecs = [
14070
14106
  },
14071
14107
  {
14072
14108
  name: "dispatch_whoami",
14109
+ example: {},
14073
14110
  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.",
14074
14111
  arguments: () => ({}),
14075
14112
  strict: true
@@ -15172,9 +15209,11 @@ class ToolInputError extends Error {
15172
15209
  problems;
15173
15210
  constructor(tool, problems) {
15174
15211
  const count = problems.length;
15212
+ const help = dispatchInputHelp(tool);
15175
15213
  super([
15176
15214
  `${tool} was not called: ${count} problem${count === 1 ? "" : "s"}`,
15177
- ...problems.map((problem) => `- ${problem}`)
15215
+ ...problems.map((problem) => `- ${problem}`),
15216
+ ...help === undefined ? [] : help.map((line) => `- ${line}`)
15178
15217
  ].join(`
15179
15218
  `));
15180
15219
  this.name = "ToolInputError";
@@ -15182,6 +15221,14 @@ class ToolInputError extends Error {
15182
15221
  this.problems = problems;
15183
15222
  }
15184
15223
  }
15224
+ function dispatchInputHelp(tool) {
15225
+ const spec = dispatchToolSpecs.find((candidate) => candidate.name === tool);
15226
+ if (spec === undefined)
15227
+ return;
15228
+ const schema = dispatchToolSchema(spec, zodSchemaApi(exports_external), { strict: true });
15229
+ const allowed = Object.keys(shapeOf(schema) ?? {}).join(", ") || "none";
15230
+ return [`Allowed keys: ${allowed}`, `Example: ${tool}(${JSON.stringify(spec.example)})`];
15231
+ }
15185
15232
  function unwrap(schema) {
15186
15233
  let current = schema;
15187
15234
  while (current !== undefined) {
@@ -15486,7 +15533,21 @@ function refTarget(ref, kind, id) {
15486
15533
  const ownerRef = ref.owner.kind === "issue" ? dispatchIssueRef(ref.owner.issue) : dispatchDocumentRef(ref.owner.project, `${ref.artifact}`);
15487
15534
  return dispatchChildRef(ownerRef, kind, id);
15488
15535
  }
15489
- var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15536
+ var canonicalUUIDPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15537
+ var compactUUIDPattern = /^[0-9a-f]{32}$/i;
15538
+ function normalizeUUID(value) {
15539
+ let compact = value;
15540
+ if (value.slice(0, 9).toLowerCase() === "urn:uuid:") {
15541
+ compact = value.slice(9);
15542
+ } else if (value.length === 38 && value.startsWith("{") && value.endsWith("}")) {
15543
+ compact = value.slice(1, -1);
15544
+ }
15545
+ if (canonicalUUIDPattern.test(compact))
15546
+ compact = compact.replaceAll("-", "");
15547
+ if (!compactUUIDPattern.test(compact))
15548
+ return;
15549
+ return `${compact.slice(0, 8)}-${compact.slice(8, 12)}-${compact.slice(12, 16)}-${compact.slice(16, 20)}-${compact.slice(20)}`.toLowerCase();
15550
+ }
15490
15551
  var askIdProblem = "ask must be a bare ask id or a dispatch://.../ask/<id> reference";
15491
15552
  var commentIdProblem = "comment must be a bare comment id or a dispatch://.../comment/<id> reference";
15492
15553
  var messageIdProblem = "in_reply_to must be a full message id (uuid) or a dispatch://KEY/message/<id> reference";
@@ -15499,12 +15560,13 @@ function messageIdOf(value) {
15499
15560
  const reference = parseDispatchRef(value);
15500
15561
  return reference?.kind === "message" ? reference.id : undefined;
15501
15562
  })() : value;
15502
- return id !== undefined && uuidPattern.test(id) ? id : undefined;
15563
+ return id === undefined ? undefined : normalizeUUID(id);
15503
15564
  }
15504
15565
  var idPrefixPattern = /^[0-9a-f][0-9a-f-]{7,}$/i;
15505
15566
  async function resolveIdPrefix(tool, kind, ref, list) {
15506
- if (uuidPattern.test(ref.id))
15507
- return ref.id;
15567
+ const fullID = normalizeUUID(ref.id);
15568
+ if (fullID !== undefined)
15569
+ return fullID;
15508
15570
  const ownerName = ref.owner.kind === "issue" ? ref.owner.issue : `${ref.owner.project}/${ref.artifact}`;
15509
15571
  if (!idPrefixPattern.test(ref.id)) {
15510
15572
  throw new ToolInputError(tool, [
@@ -15736,21 +15798,53 @@ async function resolveArtifact(client, owner, artifactReference) {
15736
15798
  return { owner, artifact };
15737
15799
  const names = artifacts.filter((candidate) => candidate.name === artifactReference);
15738
15800
  if (names.length > 1) {
15739
- throw new Error(`artifact name ${artifactReference} is ambiguous in project ${owner.project}; ` + `${names.length} documents share it \u2014 use its slug instead`);
15801
+ throw new Error(documentReferenceProblem(artifactReference, names, "project", true));
15802
+ }
15803
+ if (names[0] === undefined) {
15804
+ throw new Error(documentReferenceProblem(artifactReference, artifacts, "project"));
15740
15805
  }
15741
- if (names[0] === undefined)
15742
- throw error;
15743
15806
  return { owner, artifact: names[0] };
15744
15807
  }
15745
15808
  }
15746
15809
  const issue = await client.getIssue(owner.issue);
15747
- 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);
15810
+ let artifact;
15811
+ if (artifactReference === undefined || artifactReference === "spec") {
15812
+ artifact = issue.artifacts.find((candidate) => candidate.primary || candidate.id === issue.primary_artifact_id);
15813
+ } else {
15814
+ artifact = issue.artifacts.find((candidate) => candidate.id === artifactReference || candidate.slug === artifactReference);
15815
+ if (artifact === undefined) {
15816
+ const names = issue.artifacts.filter((candidate) => candidate.name === artifactReference);
15817
+ if (names.length > 1) {
15818
+ throw new Error(documentReferenceProblem(artifactReference, names, "issue", true));
15819
+ }
15820
+ artifact = names[0];
15821
+ }
15822
+ }
15748
15823
  if (!artifact) {
15749
- const slugs = issue.artifacts.map((candidate) => `${candidate.slug}${candidate.primary || candidate.id === issue.primary_artifact_id ? " (primary)" : ""}`);
15750
- throw new Error(`artifact "${artifactReference ?? "spec"}" was not found on issue ${issue.key}; artifacts: ${slugs.length === 0 ? "none" : slugs.join(", ")}`);
15824
+ throw new Error(documentReferenceProblem(artifactReference ?? "spec", issue.artifacts, "issue"));
15751
15825
  }
15752
15826
  return { owner, issue, artifact };
15753
15827
  }
15828
+ var documentHintLimit = 8;
15829
+ function documentReferenceProblem(reference, documents, owner, ambiguous = false) {
15830
+ const hints = documents.slice(0, documentHintLimit).map((document) => `${document.slug} (${document.name})`);
15831
+ const list = hints.length === 0 ? "none" : hints.join(", ");
15832
+ 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}`;
15833
+ }
15834
+ var askHintLimit = 8;
15835
+ function askIDInputProblem(asks, scope) {
15836
+ const hints = asks.slice(0, askHintLimit).map((ask) => `${ask.id.slice(0, 8)}\u2026 ${textHead(ask.question)}`);
15837
+ return `ask IDs are UUIDs; use the full ask ID; ${scope} open asks: ${hints.length === 0 ? "none" : hints.join(", ")}`;
15838
+ }
15839
+ async function invalidReplyToAskProblem(client, owner, resolved) {
15840
+ if (owner.kind === "issue") {
15841
+ const issue = resolved?.issue ?? await client.getIssue(owner.issue);
15842
+ return askIDInputProblem(issue.open_asks, "this issue's");
15843
+ }
15844
+ if (resolved === undefined)
15845
+ throw new Error("project document is missing its resolved artifact");
15846
+ return askIDInputProblem(await client.getArtifactAsks(resolved.artifact.id, "open"), "this document's");
15847
+ }
15754
15848
  function anchor(artifact, args) {
15755
15849
  const quote = optionalString(args, "quote");
15756
15850
  if (quote === undefined)
@@ -16354,7 +16448,13 @@ ${followsAsk(askOwner)}`,
16354
16448
  const resolved = owner.kind === "project" || artifactReference === undefined ? owner.kind === "project" ? await resolveArtifact(client, owner, artifactReference) : undefined : await resolveArtifact(client, owner, artifactReference);
16355
16449
  const anchored = resolved ? anchor(resolved.artifact, args) : undefined;
16356
16450
  const replyTo = optionalString(args, "reply_to");
16357
- const replyToAsk = optionalString(args, "reply_to_ask");
16451
+ const replyToAskReference = optionalString(args, "reply_to_ask");
16452
+ const replyToAsk = replyToAskReference === undefined ? undefined : normalizeUUID(replyToAskReference);
16453
+ if (replyToAskReference !== undefined && replyToAsk === undefined) {
16454
+ throw new ToolInputError(input.tool, [
16455
+ await invalidReplyToAskProblem(client, owner, resolved)
16456
+ ]);
16457
+ }
16358
16458
  const requestedTurn = optionalString(args, "turn");
16359
16459
  const commentInput = {
16360
16460
  body: stringArg(args, "body"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/opencode-legion-envoy",
3
- "version": "1.40.1",
3
+ "version": "1.40.2",
4
4
  "type": "module",
5
5
  "main": "dist/src/server.js",
6
6
  "exports": {