@sjawhar/opencode-legion-envoy 4.0.0 → 4.0.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.
@@ -14249,13 +14249,13 @@ var dispatchToolSpecs = [
14249
14249
  },
14250
14250
  {
14251
14251
  name: "dispatch_request_approval",
14252
- example: { issue: "DSP-1", summary: "Proposes a live sync in place of the nightly export." },
14253
- description: "Ask a human to approve a document at its current version. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. A later version makes an approval stale, " + "and writing it retracts an open request for an older version; request again for the new " + "one. A repeat at the version an open request names returns that request unchanged. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
14252
+ example: { issue: "DSP-1", summary: "A live sync replaces the nightly export." },
14253
+ description: "Ask a human to approve a document at its current version. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. A later version carries the same open " + "request forward and leaves it waiting on you; once the revision is complete and the human " + "has agreed to every point in it, call this again to hand that request back. The request " + "carries nothing new. A call while it already waits on the human hands nothing back: the " + "same summary changes nothing, and a different one is refused, since it would rewrite the " + "card the human is reading. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
14254
14254
  arguments: (z2) => ({
14255
14255
  issue: z2.string().describe(ISSUE_REFERENCE).optional(),
14256
14256
  project: z2.string().describe("Project key owning the document.").optional(),
14257
14257
  artifact: z2.string().describe("Project document artifact id, slug, or filename; primary document by default for an issue.").optional(),
14258
- summary: z2.string({ min: 1 }).describe("The proposals in this version the human hasn't already agreed to, in one to three sentences.")
14258
+ summary: z2.string({ min: 1 }).describe("What the human is approving, in one to three sentences, and nothing else: no commentary on itself or the conversation, and no question. Request approval only once the human has agreed to every point in the document.")
14259
14259
  }),
14260
14260
  validation: documentOwnerValidation(true)
14261
14261
  },
@@ -15385,7 +15385,8 @@ class DispatchClient {
15385
15385
  return this.#json("POST", ["api", "v1", "asks", id, "resolve"], input);
15386
15386
  }
15387
15387
  async requestApproval(artifactID, input) {
15388
- return this.#json("POST", ["api", "v1", "artifacts", artifactID, "approval-requests"], input);
15388
+ const answer = await this.#jsonAnswer("POST", ["api", "v1", "artifacts", artifactID, "approval-requests"], input);
15389
+ return { ...answer.payload, recorded: answer.status === 201 };
15389
15390
  }
15390
15391
  async editAsk(id, input) {
15391
15392
  return this.#json("PATCH", ["api", "v1", "asks", id], input);
@@ -15530,6 +15531,9 @@ class DispatchClient {
15530
15531
  }
15531
15532
  }
15532
15533
  async#json(method, path2, body, query) {
15534
+ return (await this.#jsonAnswer(method, path2, body, query)).payload;
15535
+ }
15536
+ async#jsonAnswer(method, path2, body, query) {
15533
15537
  const headers = {
15534
15538
  Accept: "application/json",
15535
15539
  Authorization: `Bearer ${this.token}`
@@ -15543,7 +15547,7 @@ class DispatchClient {
15543
15547
  signal: this.#signal,
15544
15548
  ...body === undefined ? {} : { body: JSON.stringify(body) }
15545
15549
  });
15546
- return this.#response(method, url2, response);
15550
+ return { status: response.status, payload: await this.#response(method, url2, response) };
15547
15551
  }
15548
15552
  async#form(method, path2, body) {
15549
15553
  const url2 = this.#url(path2);
@@ -16408,8 +16412,10 @@ function approvalLine(artifact) {
16408
16412
  if (approval === undefined || approval.state === "draft")
16409
16413
  return;
16410
16414
  switch (approval.state) {
16411
- case "awaiting":
16412
- return `Approval: awaiting (requested by ${approval.requested_by?.id ?? "unknown"}, ask ${approval.ask_id ?? "?"})`;
16415
+ case "awaiting": {
16416
+ const turn = approval.waiting_on === undefined ? "" : `, waiting on ${approval.waiting_on}`;
16417
+ return `Approval: awaiting${turn} (requested by ${approval.requested_by?.id ?? "unknown"}, ask ${approval.ask_id ?? "?"})`;
16418
+ }
16413
16419
  case "approved":
16414
16420
  return `Approval: approved v${approval.version} by ${approval.by?.id ?? "unknown"}`;
16415
16421
  case "stale":
@@ -16549,6 +16555,7 @@ function eventHead(event) {
16549
16555
  case "ask.opened":
16550
16556
  case "ask.anchor_refreshed":
16551
16557
  case "ask.edited":
16558
+ case "ask.handed_back":
16552
16559
  case "ask.resolved":
16553
16560
  return textHead(event.payload.question);
16554
16561
  case "ask.answered":
@@ -17296,7 +17303,7 @@ ${followsAsk(askOwner)}`,
17296
17303
  replyToOwnAsk: replyToAsk !== undefined && (comment.advice?.your_open_asks?.some((ask) => ask.id === replyToAsk) ?? false)
17297
17304
  });
17298
17305
  if (replyToAsk !== undefined) {
17299
- const askState = comment.turn === null ? "" : `; ask now waiting on ${comment.turn}`;
17306
+ const askState = comment.ask_waiting_on === undefined ? "" : `; ask now waiting on ${comment.ask_waiting_on}`;
17300
17307
  return {
17301
17308
  text: [
17302
17309
  `Replied on ask ${replyToAsk} (comment ${comment.id}${askState}). ${followsAsk(commentOwner2)}`,
@@ -17307,7 +17314,7 @@ ${followsAsk(askOwner)}`,
17307
17314
  ...commentDetails,
17308
17315
  ask: replyToAsk,
17309
17316
  follows: { ask: replyToAsk },
17310
- ...comment.turn === null ? {} : { ask_waiting_on: comment.turn },
17317
+ ...comment.ask_waiting_on === undefined ? {} : { ask_waiting_on: comment.ask_waiting_on },
17311
17318
  ...comment.advice === undefined ? {} : { advice: comment.advice }
17312
17319
  }
17313
17320
  };
@@ -17411,7 +17418,7 @@ ${followsAsk(askOwner)}`,
17411
17418
  const unchangedOps = edited.unchanged_ops ?? [];
17412
17419
  const unchangedText = unchangedOps.length === 0 ? "" : `; ${unchangedOps.length === 1 ? "operation" : "operations"} ${unchangedOps.join(", ")} changed nothing`;
17413
17420
  const lostOps = edited.lost_ops;
17414
- const lostText = lostOps === undefined || lostOps !== null && lostOps.length === 0 ? "" : lostOps === null ? "; could not confirm this edit survived, because the live document is being reloaded \u2014 re-read it" : `; ${versionText} carries text the live document no longer has: a concurrent change removed what ${lostOps.length === 1 ? "operation" : "operations"} ${lostOps.join(", ")} wrote \u2014 re-read the document`;
17421
+ const lostText = lostOps === undefined || lostOps !== null && lostOps.length === 0 ? "" : lostOps === null ? "; could not confirm this edit survived, because the live document is being reloaded or holds a tree too deep to read \u2014 re-read it" : `; ${versionText} carries text the live document no longer has: a concurrent change removed what ${lostOps.length === 1 ? "operation" : "operations"} ${lostOps.join(", ")} wrote \u2014 re-read the document`;
17415
17422
  const applied = `${head}${unchangedText}${lostText}`;
17416
17423
  const adviceLines = renderAdvice(input.tool, resolvedTopic(resolved).label, edited.advice, {});
17417
17424
  const tokenTrailer = edited.token === undefined ? [] : [`Document token: ${edited.token}`];
@@ -17480,8 +17487,9 @@ ${trailer.join(`
17480
17487
  };
17481
17488
  }
17482
17489
  const details = await followedAskDetails(client, result.ask, resolved.artifact);
17490
+ const outcome = result.recorded ? `Approval requested for ${resolved.artifact.name} (document id ${resolved.artifact.id}) at version ${result.version} (ask ${result.ask.id}).` : `The approval request for ${resolved.artifact.name} (document id ${resolved.artifact.id}) at version ${result.version} (ask ${result.ask.id}) already waits on the human, so this call changed nothing: nothing since it last reached the human (a newer version, a human's reply in its thread, or your progress note) left it waiting on you.`;
17483
17491
  return {
17484
- text: `Approval requested for ${resolved.artifact.name} (document id ${resolved.artifact.id}) at version ${result.version} (ask ${result.ask.id}). The human's Inbox asks: ${JSON.stringify(result.ask.question)}. The answer arrives as artifact.approved or artifact.changes_requested; an edit after approval makes it stale, so request again for the new version.`,
17492
+ text: `${outcome} The human's Inbox asks: ${JSON.stringify(result.ask.question)}. The answer arrives as artifact.approved or artifact.changes_requested; an edit after approval makes it stale, so request again for the new version.`,
17485
17493
  details: { ...details, artifact: resolved.artifact.id, version: result.version }
17486
17494
  };
17487
17495
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/opencode-legion-envoy",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "type": "module",
5
5
  "main": "dist/src/server.js",
6
6
  "exports": {
@@ -182,9 +182,10 @@ was written: re-read the document and decide again, as with `PRECONDITION_FAILED
182
182
  `lost_ops` names operations means the version was written and the live document already lacks what
183
183
  those operations wrote, because the deletion landed after the version: re-read before building on
184
184
  it. `lost_ops: []` is the ordinary outcome, and a result that says it could not confirm the edit
185
- survived means the room is reloading — re-read. An operation that only removes text (`delete`,
186
- `delete_row`, `delete_column`, a `replace` that shortens) is never reported lost: a concurrent
187
- deletion cannot undo a removal.
185
+ survived means the room is reloading or holds a tree too deep to read — re-read, and a read that
186
+ answers `DOC_SCHEMA` says which. An operation that only removes text (`delete`, `delete_row`,
187
+ `delete_column`, a `replace` that shortens) is never reported lost: a concurrent deletion cannot
188
+ undo a removal.
188
189
 
189
190
  `retype` turns the paragraph or typed block with `block` into the named typed `type` in place. It keeps the
190
191
  block id, keeps a typed block's body, and uses `attributes` for client-owned typed attributes. Use it when