@borgee/agents-host 0.2.74 → 0.2.94

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 (82) hide show
  1. package/README.md +11 -24
  2. package/dist/agents-host.d.ts +6 -4
  3. package/dist/agents-host.js +127 -16
  4. package/dist/background-runs.d.ts +24 -0
  5. package/dist/background-runs.js +184 -0
  6. package/dist/chat/chat-control-plane.d.ts +7 -1
  7. package/dist/chat/sdk-chat-control-plane.d.ts +7 -2
  8. package/dist/chat/sdk-chat-control-plane.js +22 -0
  9. package/dist/context/claude-file-brief.js +3 -3
  10. package/dist/context/injection.d.ts +18 -12
  11. package/dist/context/injection.js +53 -53
  12. package/dist/context/prompt.js +10 -10
  13. package/dist/context/resolved-working-folder.d.ts +3 -0
  14. package/dist/context/resolved-working-folder.js +106 -0
  15. package/dist/context/turn-preparation.js +1 -1
  16. package/dist/managed-daemon.js +30 -30
  17. package/dist/plugin-sdk.js +315 -29
  18. package/dist/plugin-sdk.js.map +3 -3
  19. package/dist/policy/authorization-audit.d.ts +1 -1
  20. package/dist/policy/copilot-permission.d.ts +9 -0
  21. package/dist/policy/copilot-permission.js +120 -1
  22. package/dist/progress-to-activity.d.ts +1 -1
  23. package/dist/progress-to-activity.js +1 -0
  24. package/dist/providers/claude/adapter.d.ts +2 -1
  25. package/dist/providers/claude/adapter.js +36 -1
  26. package/dist/providers/claude/background-run-observer.d.ts +32 -0
  27. package/dist/providers/claude/background-run-observer.js +381 -0
  28. package/dist/providers/claude/cli-client.d.ts +12 -0
  29. package/dist/providers/claude/cli-client.js +453 -72
  30. package/dist/providers/claude/foreground-handoff.d.ts +4 -0
  31. package/dist/providers/claude/foreground-handoff.js +45 -0
  32. package/dist/providers/claude/task-cancellation-protocol.d.ts +14 -0
  33. package/dist/providers/claude/task-cancellation-protocol.js +21 -0
  34. package/dist/providers/codex/adapter.d.ts +1 -1
  35. package/dist/providers/codex/adapter.js +7 -0
  36. package/dist/providers/codex/cli-client.js +8 -7
  37. package/dist/providers/codex/project-doc.js +6 -6
  38. package/dist/providers/copilot/activity-metadata.d.ts +3 -0
  39. package/dist/providers/copilot/activity-metadata.js +19 -0
  40. package/dist/providers/copilot/adapter.d.ts +6 -2
  41. package/dist/providers/copilot/adapter.js +27 -1
  42. package/dist/providers/copilot/cli-client.d.ts +37 -10
  43. package/dist/providers/copilot/cli-client.js +756 -122
  44. package/dist/providers/copilot/sdk-session.d.ts +149 -0
  45. package/dist/providers/copilot/sdk-session.js +981 -0
  46. package/dist/providers/create-provider.js +33 -0
  47. package/dist/providers/provider-adapter.d.ts +24 -1
  48. package/dist/providers/provider-adapter.js +17 -0
  49. package/dist/types.d.ts +40 -11
  50. package/dist/vendor/claude-agent-acp/LICENSE +191 -0
  51. package/dist/vendor/claude-agent-acp/NOTICE +8 -0
  52. package/dist/vendor/claude-agent-acp/dist/acp-agent.d.ts +1017 -0
  53. package/dist/vendor/claude-agent-acp/dist/acp-agent.d.ts.map +1 -0
  54. package/dist/vendor/claude-agent-acp/dist/acp-agent.js +6305 -0
  55. package/dist/vendor/claude-agent-acp/dist/borgee-foreground-handoff-bridge.js +322 -0
  56. package/dist/vendor/claude-agent-acp/dist/borgee-task-cancellation-bridge.js +101 -0
  57. package/dist/vendor/claude-agent-acp/dist/borgee-task-lifecycle-bridge.js +58 -0
  58. package/dist/vendor/claude-agent-acp/dist/elicitation.d.ts +130 -0
  59. package/dist/vendor/claude-agent-acp/dist/elicitation.d.ts.map +1 -0
  60. package/dist/vendor/claude-agent-acp/dist/elicitation.js +304 -0
  61. package/dist/vendor/claude-agent-acp/dist/index.d.ts +3 -0
  62. package/dist/vendor/claude-agent-acp/dist/index.d.ts.map +1 -0
  63. package/dist/vendor/claude-agent-acp/dist/index.js +75 -0
  64. package/dist/vendor/claude-agent-acp/dist/lib.d.ts +6 -0
  65. package/dist/vendor/claude-agent-acp/dist/lib.d.ts.map +1 -0
  66. package/dist/vendor/claude-agent-acp/dist/lib.js +5 -0
  67. package/dist/vendor/claude-agent-acp/dist/settings.d.ts +68 -0
  68. package/dist/vendor/claude-agent-acp/dist/settings.d.ts.map +1 -0
  69. package/dist/vendor/claude-agent-acp/dist/settings.js +185 -0
  70. package/dist/vendor/claude-agent-acp/dist/tools.d.ts +102 -0
  71. package/dist/vendor/claude-agent-acp/dist/tools.d.ts.map +1 -0
  72. package/dist/vendor/claude-agent-acp/dist/tools.js +1000 -0
  73. package/dist/vendor/claude-agent-acp/dist/utils.d.ts +16 -0
  74. package/dist/vendor/claude-agent-acp/dist/utils.d.ts.map +1 -0
  75. package/dist/vendor/claude-agent-acp/dist/utils.js +81 -0
  76. package/dist/vendor/claude-agent-acp/package.json +85 -0
  77. package/package.json +15 -10
  78. package/skills/borgee-agent/references/task-properties.md +3 -3
  79. package/skills/borgee-agent/scripts/borgee-agent.mjs +1 -1
  80. package/skills/borgee-agent/scripts/borgee-agent.py +1 -1
  81. package/dist/context/resolved-workspace.d.ts +0 -3
  82. package/dist/context/resolved-workspace.js +0 -106
@@ -3722,8 +3722,8 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
3722
3722
  // ../sdk/plugin-ts/dist/errors.js
3723
3723
  var BorgeeError = class extends Error {
3724
3724
  code;
3725
- constructor(message, code) {
3726
- super(message);
3725
+ constructor(message, code, options) {
3726
+ super(message, options);
3727
3727
  this.name = "BorgeeError";
3728
3728
  this.code = code;
3729
3729
  }
@@ -3743,6 +3743,95 @@ var PermissionDeniedError = class extends BorgeeError {
3743
3743
  }
3744
3744
  };
3745
3745
 
3746
+ // ../sdk/plugin-ts/dist/channel-contracts.js
3747
+ var isZoneId = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,128}$/.test(value);
3748
+ var validateChannelPlacement = (parentId) => {
3749
+ if (parentId !== null && (!isZoneId(parentId) || parentId === "null")) {
3750
+ throw new BorgeeError("parentId is required: pass null for Default or a Zone ID", "channel.placement_invalid");
3751
+ }
3752
+ };
3753
+ var rejectChannelPlacementUpdate = (input) => {
3754
+ for (const field of ["parentId", "parent_id", "channelType", "channel_type", "kind"]) {
3755
+ if (Object.hasOwn(input, field)) {
3756
+ throw new BorgeeError(`${field} cannot be changed after channel creation`, "channel.field_immutable");
3757
+ }
3758
+ }
3759
+ };
3760
+ var validateListZonesInput = (input) => {
3761
+ if (!isZoneId(input.guildId)) {
3762
+ throw new BorgeeError("guildId must be a nonempty opaque ID", "zone.input_invalid");
3763
+ }
3764
+ if (input.limit !== void 0 && (!Number.isInteger(input.limit) || input.limit < 1 || input.limit > 50)) {
3765
+ throw new BorgeeError("limit must be an integer between 1 and 50", "zone.input_invalid");
3766
+ }
3767
+ if (input.after !== void 0 && !isZoneId(input.after)) {
3768
+ throw new BorgeeError("after must be a nonempty opaque Zone ID", "zone.input_invalid");
3769
+ }
3770
+ };
3771
+
3772
+ // ../sdk/plugin-ts/dist/bpp/channel-results.js
3773
+ var invalidResult = (field) => new BorgeeError(`Invalid channel result: ${field}`, "bpp.invalid_result");
3774
+ var record = (value, field) => {
3775
+ if (!value || typeof value !== "object" || Array.isArray(value))
3776
+ throw invalidResult(field);
3777
+ return value;
3778
+ };
3779
+ var requiredString = (value, field) => {
3780
+ if (typeof value !== "string")
3781
+ throw invalidResult(field);
3782
+ return value;
3783
+ };
3784
+ var decodeChannel = (value) => {
3785
+ const channel = record(value, "channel");
3786
+ if (!isZoneId(channel.id))
3787
+ throw invalidResult("id");
3788
+ if (channel.parent_id !== null && !isZoneId(channel.parent_id))
3789
+ throw invalidResult("parent_id");
3790
+ return {
3791
+ id: channel.id,
3792
+ name: requiredString(channel.name, "name"),
3793
+ kind: requiredString(channel.kind, "kind"),
3794
+ parentId: channel.parent_id
3795
+ };
3796
+ };
3797
+ var decodeChannels = (value) => {
3798
+ if (!Array.isArray(value))
3799
+ throw invalidResult("channels");
3800
+ return value.map(decodeChannel);
3801
+ };
3802
+ var decodeZone = (value) => {
3803
+ const zone = record(value, "zone");
3804
+ if (!isZoneId(zone.id))
3805
+ throw invalidResult("zone.id");
3806
+ const name = requiredString(zone.name, "zone.name");
3807
+ if (new RegExp("^\\p{White_Space}|\\p{White_Space}$", "u").test(name) || [...name].length < 1 || [...name].length > 100 || /[\p{Cc}\p{Cs}]/u.test(name)) {
3808
+ throw invalidResult("zone.name");
3809
+ }
3810
+ return { id: zone.id, name };
3811
+ };
3812
+ var decodeZonePage = (value, input) => {
3813
+ const page = record(value, "Zone page");
3814
+ if (!Array.isArray(page.zones))
3815
+ throw invalidResult("zones");
3816
+ const limit = input?.limit ?? 20;
3817
+ if (page.zones.length > limit)
3818
+ throw invalidResult("zones exceed the requested limit");
3819
+ const zones = page.zones.map(decodeZone);
3820
+ let previous = input?.after;
3821
+ for (const zone of zones) {
3822
+ if (previous !== void 0 && zone.id <= previous)
3823
+ throw invalidResult("Zone IDs must follow the cursor in ascending order");
3824
+ previous = zone.id;
3825
+ }
3826
+ const nextAfter = page.next_after;
3827
+ if (nextAfter !== null) {
3828
+ if (!isZoneId(nextAfter) || zones.length !== limit || nextAfter !== zones.at(-1)?.id) {
3829
+ throw invalidResult("next_after must be null or the final ID of a full page");
3830
+ }
3831
+ }
3832
+ return { zones, nextAfter };
3833
+ };
3834
+
3746
3835
  // ../sdk/plugin-ts/dist/bpp/bpp-transport.js
3747
3836
  var PROTOCOL_VERSION = "bpp-1";
3748
3837
  var CONFIG_ACK_REASONS = /* @__PURE__ */ new Set([
@@ -3757,6 +3846,8 @@ var WS_CLOSE_AUTH_FAILED = 4004;
3757
3846
  var RESULT_STATUS_OK = "ok";
3758
3847
  var STOP_TURN_ACTION = "stop_turn";
3759
3848
  var STOP_TURN_CHANNEL_ID_INVALID = "stop_turn_channel_id_invalid";
3849
+ var STOP_BACKGROUND_RUN_ACTION = "stop_background_run";
3850
+ var STOP_BACKGROUND_RUN_TARGET_INVALID = "stop_background_run_target_invalid";
3760
3851
  var SERVER_REQUEST_FAILED = "server_request_failed";
3761
3852
  var BppTransport = class {
3762
3853
  performTimeoutMs;
@@ -3777,6 +3868,7 @@ var BppTransport = class {
3777
3868
  // send issued during a reconnect never races ahead of the handshake.
3778
3869
  online = false;
3779
3870
  terminal = false;
3871
+ stopBackgroundRunHandler;
3780
3872
  inboundChain = Promise.resolve();
3781
3873
  configChain = Promise.resolve();
3782
3874
  configAcks = /* @__PURE__ */ new Map();
@@ -3811,6 +3903,9 @@ var BppTransport = class {
3811
3903
  setStopTurnHandler(handler) {
3812
3904
  this.stopTurnHandler = handler;
3813
3905
  }
3906
+ setStopBackgroundRunHandler(handler) {
3907
+ this.stopBackgroundRunHandler = handler;
3908
+ }
3814
3909
  getResolvedAgentId() {
3815
3910
  return this.currentAgentId();
3816
3911
  }
@@ -3881,7 +3976,7 @@ var BppTransport = class {
3881
3976
  }
3882
3977
  }
3883
3978
  }
3884
- // ---- perform (上行) ----
3979
+ // ---- Outbound operations ----
3885
3980
  async perform(action, opts) {
3886
3981
  if (action.op === "report_task_started") {
3887
3982
  this.sendTaskStarted(action);
@@ -3923,11 +4018,17 @@ var BppTransport = class {
3923
4018
  this.pending.delete(nonce);
3924
4019
  reject(new BorgeeError(`semantic_action ${action.op} timed out`, "bpp.action_timeout"));
3925
4020
  }, remaining);
3926
- this.pending.set(nonce, { op: action.op, resolve, reject, timer });
4021
+ this.pending.set(nonce, {
4022
+ op: action.op,
4023
+ ...action.op === "list_zones" ? { zoneInput: { guildId: action.guildId, limit: action.limit, after: action.after } } : {},
4024
+ resolve,
4025
+ reject,
4026
+ timer
4027
+ });
3927
4028
  this.send(frame);
3928
4029
  });
3929
4030
  }
3930
- // ---- socket 生命周期 ----
4031
+ // ---- Socket lifecycle ----
3931
4032
  // Transition the given socket to ONLINE. Bails if the socket is stale (a reconnect replaced it),
3932
4033
  // so a handshake completing on a prior socket cannot flip online across a reconnect.
3933
4034
  goOnline(source) {
@@ -4097,7 +4198,7 @@ var BppTransport = class {
4097
4198
  this.heartbeatTimer = void 0;
4098
4199
  }
4099
4200
  }
4100
- // ---- 下行分发 ----
4201
+ // ---- Inbound dispatch ----
4101
4202
  onMessage(raw, source) {
4102
4203
  if (source !== this.ws)
4103
4204
  return;
@@ -4153,7 +4254,13 @@ var BppTransport = class {
4153
4254
  this.pending.delete(frame.nonce);
4154
4255
  clearTimeout(p.timer);
4155
4256
  if (frame.status === RESULT_STATUS_OK) {
4156
- const result = decodeActionResult(p.op, frame.payload);
4257
+ let result;
4258
+ try {
4259
+ result = decodeActionResult(p.op, frame.payload, p.zoneInput);
4260
+ } catch (error) {
4261
+ p.reject(error);
4262
+ return;
4263
+ }
4157
4264
  if (p.op === "get_me" && result && typeof result === "object") {
4158
4265
  const id = result.id;
4159
4266
  if (id)
@@ -4286,6 +4393,10 @@ var BppTransport = class {
4286
4393
  await this.answerStopTurn(id, data);
4287
4394
  return;
4288
4395
  }
4396
+ if (action === STOP_BACKGROUND_RUN_ACTION) {
4397
+ await this.answerStopBackgroundRun(id, data);
4398
+ return;
4399
+ }
4289
4400
  if (!this.serverRequestHandler) {
4290
4401
  this.send({ type: "response", id, error: "no_server_request_handler" });
4291
4402
  return;
@@ -4336,7 +4447,38 @@ var BppTransport = class {
4336
4447
  }
4337
4448
  return { aborted };
4338
4449
  }
4339
- // ---- task 生命周期上行 ----
4450
+ async answerStopBackgroundRun(id, data) {
4451
+ const channelId = data.channel_id;
4452
+ const runId = data.run_id;
4453
+ if (typeof channelId !== "string" || channelId === "" || typeof runId !== "string" || runId === "") {
4454
+ this.send({ type: "response", id, error: STOP_BACKGROUND_RUN_TARGET_INVALID });
4455
+ return;
4456
+ }
4457
+ try {
4458
+ const answer = this.stopBackgroundRunHandler ? await this.stopBackgroundRunHandler(channelId, runId) : {
4459
+ outcome: "unsupported",
4460
+ reason: "Targeted background-run cancellation is not registered"
4461
+ };
4462
+ this.send({ type: "response", id, data: this.asStopBackgroundRunResult(answer) });
4463
+ } catch (err) {
4464
+ this.logger?.warn("bpp.stop_background_run_handler_failed", err);
4465
+ this.send({ type: "response", id, error: SERVER_REQUEST_FAILED });
4466
+ }
4467
+ }
4468
+ asStopBackgroundRunResult(answer) {
4469
+ const candidate = answer;
4470
+ if (!candidate || !["stopped", "not_found", "unsupported"].includes(candidate.outcome)) {
4471
+ return {
4472
+ outcome: "unsupported",
4473
+ reason: "Targeted background-run cancellation returned an unusable answer"
4474
+ };
4475
+ }
4476
+ return {
4477
+ outcome: candidate.outcome,
4478
+ ...typeof candidate.reason === "string" && candidate.reason !== "" ? { reason: candidate.reason } : {}
4479
+ };
4480
+ }
4481
+ // ---- Task lifecycle output ----
4340
4482
  sendTaskStarted(action) {
4341
4483
  const frame = {
4342
4484
  type: "task_started",
@@ -4384,7 +4526,13 @@ var BppTransport = class {
4384
4526
  reason: "",
4385
4527
  stream: "",
4386
4528
  text: "",
4387
- turn_state: ""
4529
+ turn_state: "",
4530
+ run_id: "",
4531
+ run_state: "",
4532
+ started_at: 0,
4533
+ finished_at: 0,
4534
+ stop_supported: false,
4535
+ stop_unsupported_reason: ""
4388
4536
  };
4389
4537
  switch (action.activity.shape) {
4390
4538
  case "activity":
@@ -4396,6 +4544,9 @@ var BppTransport = class {
4396
4544
  frame.detail = action.activity.detail ?? "";
4397
4545
  frame.parent_id = action.activity.parentId ?? "";
4398
4546
  frame.subagent = action.activity.subagent ?? false;
4547
+ frame.background = action.activity.background;
4548
+ frame.background_state = action.activity.backgroundState;
4549
+ frame.follow_up_control = action.activity.followUpControl;
4399
4550
  frame.reason = action.activity.reason ?? "";
4400
4551
  if (action.activity.paths)
4401
4552
  frame.paths = action.activity.paths;
@@ -4413,13 +4564,24 @@ var BppTransport = class {
4413
4564
  case "turn":
4414
4565
  frame.turn_state = action.activity.state;
4415
4566
  break;
4567
+ case "background_run":
4568
+ frame.run_id = action.activity.runId;
4569
+ frame.label = action.activity.label;
4570
+ frame.run_state = action.activity.state;
4571
+ frame.parent_id = action.activity.parentId ?? "";
4572
+ frame.started_at = action.activity.startedAt;
4573
+ frame.finished_at = action.activity.finishedAt ?? 0;
4574
+ frame.reason = action.activity.reason ?? "";
4575
+ frame.stop_supported = action.activity.stopSupported;
4576
+ frame.stop_unsupported_reason = action.activity.stopUnsupportedReason ?? "";
4577
+ break;
4416
4578
  }
4417
4579
  this.send(frame);
4418
4580
  }
4419
4581
  sendTyping(action) {
4420
4582
  this.send({ type: "typing", channel_id: action.channelId });
4421
4583
  }
4422
- // ---- 低层发送 ----
4584
+ // ---- Low-level output ----
4423
4585
  send(frame) {
4424
4586
  if (!this.isOpen())
4425
4587
  return;
@@ -4519,7 +4681,8 @@ function encodeActionPayload(action) {
4519
4681
  return {
4520
4682
  channel_id: action.channelId,
4521
4683
  content: action.body,
4522
- reply_to_id: action.replyToId
4684
+ reply_to_id: action.replyToId,
4685
+ content_type: action.contentType
4523
4686
  };
4524
4687
  case "edit_message":
4525
4688
  return { message_id: action.messageId, content: action.body };
@@ -4545,15 +4708,21 @@ function encodeActionPayload(action) {
4545
4708
  case "list_users":
4546
4709
  case "list_channels":
4547
4710
  return {};
4711
+ case "list_zones":
4712
+ validateListZonesInput(action);
4713
+ return { guild_id: action.guildId, limit: action.limit, after: action.after };
4548
4714
  case "create_channel":
4715
+ validateChannelPlacement(action.parentId);
4549
4716
  return {
4550
4717
  guild_id: action.guildId,
4551
4718
  name: action.name,
4719
+ parent_id: action.parentId,
4552
4720
  topic: action.topic,
4553
4721
  visibility: action.visibility,
4554
4722
  member_ids: action.memberIds
4555
4723
  };
4556
4724
  case "update_channel":
4725
+ rejectChannelPlacementUpdate(action);
4557
4726
  return {
4558
4727
  channel_id: action.channelId,
4559
4728
  name: action.name,
@@ -4597,7 +4766,20 @@ function encodeActionPayload(action) {
4597
4766
  return {};
4598
4767
  }
4599
4768
  }
4600
- function decodeActionResult(op, payloadJSON) {
4769
+ function decodeActionResult(op, payloadJSON, zoneInput) {
4770
+ if (op === "list_zones" || op === "list_channels" || op === "create_channel" || op === "update_channel") {
4771
+ let value;
4772
+ try {
4773
+ value = JSON.parse(payloadJSON);
4774
+ } catch (cause) {
4775
+ throw new BorgeeError("Invalid JSON in channel result", "bpp.invalid_result", { cause });
4776
+ }
4777
+ if (op === "list_zones")
4778
+ return decodeZonePage(value, zoneInput);
4779
+ if (op === "list_channels")
4780
+ return decodeChannels(value);
4781
+ return decodeChannel(value);
4782
+ }
4601
4783
  const p = safeParseJSON(payloadJSON);
4602
4784
  switch (op) {
4603
4785
  case "send_message":
@@ -4614,7 +4796,7 @@ function decodeActionResult(op, payloadJSON) {
4614
4796
  case "delete_message":
4615
4797
  case "react":
4616
4798
  return void 0;
4617
- // 客户端方法返回 void
4799
+ // These client methods return void.
4618
4800
  case "read_channel_history": {
4619
4801
  const arr = Array.isArray(p) ? p : [];
4620
4802
  return arr.map((m) => ({
@@ -4637,21 +4819,6 @@ function decodeActionResult(op, payloadJSON) {
4637
4819
  kind: u.kind === "agent" ? "agent" : "user"
4638
4820
  }));
4639
4821
  }
4640
- case "list_channels": {
4641
- const arr = Array.isArray(p) ? p : [];
4642
- return arr.map((c) => ({
4643
- id: String(c.id ?? ""),
4644
- name: String(c.name ?? ""),
4645
- kind: String(c.kind ?? "")
4646
- }));
4647
- }
4648
- case "create_channel":
4649
- case "update_channel":
4650
- return {
4651
- id: String(p.id ?? ""),
4652
- name: String(p.name ?? ""),
4653
- kind: String(p.kind ?? "")
4654
- };
4655
4822
  case "set_topic":
4656
4823
  case "delete_channel":
4657
4824
  return void 0;
@@ -4954,7 +5121,8 @@ var Client = class {
4954
5121
  op: "send_message",
4955
5122
  channelId: input.channelId,
4956
5123
  body: input.body,
4957
- replyToId: input.replyToId
5124
+ replyToId: input.replyToId,
5125
+ contentType: input.contentType
4958
5126
  });
4959
5127
  }
4960
5128
  async editMessage(input) {
@@ -4991,16 +5159,19 @@ var Client = class {
4991
5159
  return await this.t.perform({ op: "list_channels" });
4992
5160
  }
4993
5161
  async createChannel(input) {
5162
+ validateChannelPlacement(input.parentId);
4994
5163
  return await this.t.perform({
4995
5164
  op: "create_channel",
4996
5165
  guildId: input.guildId,
4997
5166
  name: input.name,
5167
+ parentId: input.parentId,
4998
5168
  topic: input.topic,
4999
5169
  visibility: input.visibility,
5000
5170
  memberIds: input.memberIds
5001
5171
  });
5002
5172
  }
5003
5173
  async updateChannel(input) {
5174
+ rejectChannelPlacementUpdate(input);
5004
5175
  return await this.t.perform({
5005
5176
  op: "update_channel",
5006
5177
  channelId: input.channelId,
@@ -5009,6 +5180,10 @@ var Client = class {
5009
5180
  archived: input.archived
5010
5181
  });
5011
5182
  }
5183
+ async listZones(input) {
5184
+ validateListZonesInput(input);
5185
+ return await this.t.perform({ op: "list_zones", ...input });
5186
+ }
5012
5187
  async setTopic(input) {
5013
5188
  await this.t.perform({ op: "set_topic", channelId: input.channelId, topic: input.topic });
5014
5189
  }
@@ -5141,6 +5316,9 @@ var Client = class {
5141
5316
  onStopTurn(handler) {
5142
5317
  this.t.setStopTurnHandler?.(handler);
5143
5318
  }
5319
+ onStopBackgroundRun(handler) {
5320
+ this.t.setStopBackgroundRunHandler?.(handler);
5321
+ }
5144
5322
  emit(event, payload) {
5145
5323
  for (const h of this.listeners[event]) {
5146
5324
  try {
@@ -5177,8 +5355,116 @@ var Client = class {
5177
5355
  function createBorgeePlugin(opts) {
5178
5356
  return new Client(opts, new BppTransport());
5179
5357
  }
5358
+
5359
+ // ../sdk/plugin-ts/dist/draft-message.js
5360
+ var THROTTLE_MS = 250;
5361
+ var DraftMessageController = class {
5362
+ client;
5363
+ channelId;
5364
+ replyToId;
5365
+ messageId = null;
5366
+ currentBody = "";
5367
+ pendingBody = null;
5368
+ timer = null;
5369
+ sealed = false;
5370
+ writeChain = Promise.resolve();
5371
+ constructor(client, channelId, replyToId) {
5372
+ this.client = client;
5373
+ this.channelId = channelId;
5374
+ this.replyToId = replyToId;
5375
+ }
5376
+ /**
5377
+ * Offer the whole body as it currently reads — not a delta. Nothing is written
5378
+ * for up to {@link THROTTLE_MS}, and only the last body offered in that window
5379
+ * is; blank text is ignored, which is why a producer that has not yet emitted
5380
+ * anything visible never creates an empty message.
5381
+ */
5382
+ update(text) {
5383
+ if (this.sealed || !text.trim())
5384
+ return;
5385
+ this.pendingBody = text;
5386
+ if (this.timer)
5387
+ return;
5388
+ this.timer = setTimeout(() => {
5389
+ this.timer = null;
5390
+ void this.flushPending().catch(() => {
5391
+ });
5392
+ }, THROTTLE_MS);
5393
+ }
5394
+ /**
5395
+ * Seal the draft at `finalText` and resolve once that text is on the wire.
5396
+ * Empty final text means the draft said nothing worth keeping, so the message
5397
+ * is deleted rather than left showing a body the producer has disowned.
5398
+ */
5399
+ async finalize(finalText) {
5400
+ this.sealed = true;
5401
+ if (this.timer) {
5402
+ clearTimeout(this.timer);
5403
+ this.timer = null;
5404
+ }
5405
+ if (finalText.trim()) {
5406
+ this.pendingBody = finalText;
5407
+ await this.flushPending();
5408
+ this.messageId = null;
5409
+ return;
5410
+ }
5411
+ await this.enqueue(async () => {
5412
+ if (!this.messageId)
5413
+ return;
5414
+ await this.client.deleteMessage({ messageId: this.messageId });
5415
+ this.messageId = null;
5416
+ });
5417
+ }
5418
+ /** Seal the draft and remove whatever it published. */
5419
+ async discard() {
5420
+ this.sealed = true;
5421
+ if (this.timer) {
5422
+ clearTimeout(this.timer);
5423
+ this.timer = null;
5424
+ }
5425
+ this.pendingBody = null;
5426
+ await this.enqueue(async () => {
5427
+ if (!this.messageId)
5428
+ return;
5429
+ await this.client.deleteMessage({ messageId: this.messageId });
5430
+ this.messageId = null;
5431
+ });
5432
+ }
5433
+ /** Whether a message has actually been published yet. */
5434
+ get hasMessage() {
5435
+ return this.messageId !== null;
5436
+ }
5437
+ async flushPending() {
5438
+ await this.enqueue(async () => {
5439
+ const body = this.pendingBody;
5440
+ if (!body || body === this.currentBody)
5441
+ return;
5442
+ if (this.messageId) {
5443
+ await this.client.editMessage({ messageId: this.messageId, body });
5444
+ } else {
5445
+ const posted = await this.client.sendMessage({
5446
+ channelId: this.channelId,
5447
+ body,
5448
+ replyToId: this.replyToId
5449
+ });
5450
+ this.messageId = posted.messageId;
5451
+ }
5452
+ this.currentBody = body;
5453
+ });
5454
+ }
5455
+ /**
5456
+ * Run `op` after every write queued before it. The same callback handles both
5457
+ * settlements deliberately: a rejected write must not wedge the chain, and a
5458
+ * producer that keeps typing after one failed edit still gets its next one.
5459
+ */
5460
+ enqueue(op) {
5461
+ this.writeChain = this.writeChain.then(op, op);
5462
+ return this.writeChain;
5463
+ }
5464
+ };
5180
5465
  export {
5181
5466
  BorgeeError,
5467
+ DraftMessageController,
5182
5468
  PermissionDeniedError,
5183
5469
  createBorgeePlugin
5184
5470
  };