frizz-server 0.15.24 → 0.15.26

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 (106) hide show
  1. package/dist/claude-agent-broker.js +84 -15
  2. package/dist/dev-child.js +3072 -881
  3. package/package.json +1 -1
  4. package/runtime/cc-worker/bin/frizzctl.mjs +18 -5
  5. package/runtime/cc-worker/hooks/deny-ask.mjs +5 -5
  6. package/runtime/cc-worker/hooks/deny-plan.mjs +2 -2
  7. package/runtime/cc-worker/hooks/perm-policy.mjs +3 -2
  8. package/runtime/cc-worker/hooks/session-seed.mjs +1 -1
  9. package/runtime/cc-worker/lib/frizz-tools.mjs +203 -308
  10. package/runtime/cc-worker/skills/gh/SKILL.md +2 -2
  11. package/web-dist/assets/{abnfDiagram-VRR7QNED-Cyq_AHxV.js → abnfDiagram-VRR7QNED-CNyfSRB-.js} +1 -1
  12. package/web-dist/assets/{arc-Biot4XPF.js → arc-B7GpXPgU.js} +1 -1
  13. package/web-dist/assets/architecture-TIHT7OUA-DFqMJLC6.js +1 -0
  14. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-rIrq0Or5.js → architectureDiagram-ZJ3FMSHR-BL9AvVPw.js} +1 -1
  15. package/web-dist/assets/{blockDiagram-677ZJIJ3-CoU4IPAo.js → blockDiagram-677ZJIJ3-Bk0zPEyN.js} +1 -1
  16. package/web-dist/assets/{c4Diagram-LMCZKHZV-IDXrxWzC.js → c4Diagram-LMCZKHZV-DshZ5qfH.js} +1 -1
  17. package/web-dist/assets/channel-BhCIHKNP.js +1 -0
  18. package/web-dist/assets/{chunk-32BRIVSS-D4oDERCE.js → chunk-32BRIVSS-Dizvs5Li.js} +1 -1
  19. package/web-dist/assets/{chunk-52WLFC77-BerQKVJ0.js → chunk-52WLFC77-EMHLNOFY.js} +1 -1
  20. package/web-dist/assets/{chunk-C7G6YPKG-JuYJLbly.js → chunk-C7G6YPKG-fJaXKcoK.js} +1 -1
  21. package/web-dist/assets/{chunk-EX3LRPZG-wOWblJtm.js → chunk-EX3LRPZG-HprJlZtU.js} +1 -1
  22. package/web-dist/assets/{chunk-FWX5IMBZ-CqArLPnj.js → chunk-FWX5IMBZ-D4Kfd-PN.js} +2 -2
  23. package/web-dist/assets/{chunk-HOUHSVGY-Bb8D8Sy0.js → chunk-HOUHSVGY-B6Mk78rz.js} +1 -1
  24. package/web-dist/assets/{chunk-ICXQ74PX-DKHetHix.js → chunk-ICXQ74PX-C82cqtFI.js} +1 -1
  25. package/web-dist/assets/{chunk-MOJQB5TN-LzEqxbeQ.js → chunk-MOJQB5TN-u1x1nYem.js} +1 -1
  26. package/web-dist/assets/{chunk-OGEWGWER-Dz8CpAuR.js → chunk-OGEWGWER-CfTCyDTh.js} +1 -1
  27. package/web-dist/assets/{chunk-PUDLZKDR-kuwrL5oa.js → chunk-PUDLZKDR-C5Tr296g.js} +1 -1
  28. package/web-dist/assets/{chunk-Q4XR5HBZ-DcOWV3Gu.js → chunk-Q4XR5HBZ-CDWIuCum.js} +1 -1
  29. package/web-dist/assets/{chunk-RYQCIY6F-DnbXKsAA.js → chunk-RYQCIY6F-1kBJEeqJ.js} +1 -1
  30. package/web-dist/assets/{chunk-V7JOEXUC-BwuCBTBN.js → chunk-V7JOEXUC-klZC3He0.js} +1 -1
  31. package/web-dist/assets/{chunk-VAUOI2AC-CV_CZRZK.js → chunk-VAUOI2AC-KxE_dl7F.js} +1 -1
  32. package/web-dist/assets/{chunk-VR4S4FIN-LWPikT8q.js → chunk-VR4S4FIN-DzTR01Sr.js} +1 -1
  33. package/web-dist/assets/{chunk-WYO6CB5R-DNl2QRUu.js → chunk-WYO6CB5R-Bz3_NY0w.js} +1 -1
  34. package/web-dist/assets/{chunk-XXDRQBXY-OWPjVUFR.js → chunk-XXDRQBXY-8BnGChAk.js} +1 -1
  35. package/web-dist/assets/{chunk-ZGVPDNZ5-DJaQplR6.js → chunk-ZGVPDNZ5-CrkRzpPb.js} +1 -1
  36. package/web-dist/assets/classDiagram-OUVF2IWQ-BwjDIolk.js +1 -0
  37. package/web-dist/assets/classDiagram-v2-EOCWNBFH-BwjDIolk.js +1 -0
  38. package/web-dist/assets/{cose-bilkent-JH36ORCC-BZT_P9wI.js → cose-bilkent-JH36ORCC-DPG2EHnF.js} +1 -1
  39. package/web-dist/assets/{cynefin-VYW2F7L2-DaK_8y6L.js → cynefin-VYW2F7L2-DxcxILDk.js} +1 -1
  40. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-yIggIpo7.js → cynefinDiagram-TSTJHNR4-7sJ6wP__.js} +1 -1
  41. package/web-dist/assets/{dagre-VKFMJZFB-DjlfaR1L.js → dagre-VKFMJZFB-SJEyJ4rz.js} +1 -1
  42. package/web-dist/assets/{diagram-FQU43EPY-3764FQId.js → diagram-FQU43EPY-Wcdsv0P_.js} +1 -1
  43. package/web-dist/assets/{diagram-G47NLZAW-CtEwbfs4.js → diagram-G47NLZAW-B6BZ7zQo.js} +1 -1
  44. package/web-dist/assets/{diagram-NH7WQ7WH-Bu-wequE.js → diagram-NH7WQ7WH-CtDA1PI9.js} +1 -1
  45. package/web-dist/assets/{diagram-OA4YK3LP-CGfVM6PV.js → diagram-OA4YK3LP-CdpweEmv.js} +1 -1
  46. package/web-dist/assets/{diagram-WEI45ONY-IAJhjXF5.js → diagram-WEI45ONY-7t3uF33P.js} +1 -1
  47. package/web-dist/assets/{dist-BjMNWdF2.js → dist-B9lHlEOl.js} +1 -1
  48. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-CtxSHYhd.js → ebnfDiagram-CCIWWBDH-B3COYz5O.js} +1 -1
  49. package/web-dist/assets/{erDiagram-Q63AITRT-BEfE5XiZ.js → erDiagram-Q63AITRT-Bu2R48kZ.js} +1 -1
  50. package/web-dist/assets/eventmodeling-45OFAUF4-CkJKP4v8.js +1 -0
  51. package/web-dist/assets/flowDiagram-23GEKE2U-GUo1f41A.js +1 -0
  52. package/web-dist/assets/{ganttDiagram-NO4QXBWP-DuTznSXl.js → ganttDiagram-NO4QXBWP-DHaD8AsE.js} +1 -1
  53. package/web-dist/assets/{gitGraph-TEB2WS4Q-Bzgogpn6.js → gitGraph-TEB2WS4Q-4lWdjXjQ.js} +1 -1
  54. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-BvUF8VO2.js → gitGraphDiagram-IHSO6WYX-Cfwf7OSS.js} +1 -1
  55. package/web-dist/assets/index-Ccmq3ie-.css +2 -0
  56. package/web-dist/assets/index-JmPE6HTE.js +369 -0
  57. package/web-dist/assets/{info-DKCQHKI2-UcBlbSp6.js → info-DKCQHKI2-m9CiI1ls.js} +1 -1
  58. package/web-dist/assets/{infoDiagram-FWYZ7A6U-eAOHFBzP.js → infoDiagram-FWYZ7A6U-CuSqktgG.js} +1 -1
  59. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-BonOAiJg.js → ishikawaDiagram-FXEZZL3T-By4RUAid.js} +1 -1
  60. package/web-dist/assets/{journeyDiagram-5HDEW3XC-CemMqrtD.js → journeyDiagram-5HDEW3XC-DG0j1rYj.js} +1 -1
  61. package/web-dist/assets/{kanban-definition-HUTT4EX6-DJa8f4EP.js → kanban-definition-HUTT4EX6-FUs5nKgH.js} +1 -1
  62. package/web-dist/assets/{line-BYOZ3K8_.js → line-hUw2N2pN.js} +1 -1
  63. package/web-dist/assets/{linear-x64YsWw9.js → linear-BO0jjB2S.js} +1 -1
  64. package/web-dist/assets/{mermaid-parser.core-C2_vS_3N.js → mermaid-parser.core-D1gbOxjg.js} +3 -3
  65. package/web-dist/assets/{mermaid.core-CiGOTRKy.js → mermaid.core-DVlHSH5E.js} +3 -3
  66. package/web-dist/assets/{mindmap-definition-LN4V7U3C-Bq7vplEh.js → mindmap-definition-LN4V7U3C-36mZJhg3.js} +1 -1
  67. package/web-dist/assets/{packet-7NZHBO7P-DvLvRzf4.js → packet-7NZHBO7P-ee_dSZ_l.js} +1 -1
  68. package/web-dist/assets/{pegDiagram-2B236MQR-N8wJXW0W.js → pegDiagram-2B236MQR-T04ZP7_1.js} +1 -1
  69. package/web-dist/assets/{pie-RZYD4A2V-BQGCrm7o.js → pie-RZYD4A2V-CgzvejQO.js} +1 -1
  70. package/web-dist/assets/{pieDiagram-ENE6RG2P-DjxRYzEX.js → pieDiagram-ENE6RG2P-CK8_lkQJ.js} +1 -1
  71. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-DB9fHEsF.js → quadrantDiagram-ABIIQ3AL-BX7B-RuD.js} +1 -1
  72. package/web-dist/assets/{radar-I7S5WNFK-CD6hpAV_.js → radar-I7S5WNFK-CCWcFiS2.js} +1 -1
  73. package/web-dist/assets/{railroad-3IZDKUUU-DbssAzLP.js → railroad-3IZDKUUU-D8RYaz8I.js} +1 -1
  74. package/web-dist/assets/railroad-abnf-AHOZXSZD-BIqOg_LJ.js +1 -0
  75. package/web-dist/assets/railroad-ebnf-EBAXGLYW-BRPgZKlP.js +1 -0
  76. package/web-dist/assets/railroad-peg-LSFZ7HO6-Brgy-BUA.js +1 -0
  77. package/web-dist/assets/{railroadDiagram-RFXS5EU6-BWrldtcC.js → railroadDiagram-RFXS5EU6-DGJ0oKTd.js} +1 -1
  78. package/web-dist/assets/{requirementDiagram-TGXJPOKE-cCBJjfiU.js → requirementDiagram-TGXJPOKE-BVQLI9-P.js} +1 -1
  79. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-CmlLuCo5.js → sankeyDiagram-HTMAVEWB-B5ggFMDw.js} +1 -1
  80. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-D67ju6AD.js → sequenceDiagram-DBY2YBRQ-BadwsmJp.js} +1 -1
  81. package/web-dist/assets/{src-wfmlpufd.js → src-DOszP0Mb.js} +1 -1
  82. package/web-dist/assets/{stateDiagram-2N3HPSRC-zxIL4yYs.js → stateDiagram-2N3HPSRC-kImZu5Rm.js} +1 -1
  83. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-CmGlxfpO.js +1 -0
  84. package/web-dist/assets/{swimlanes-5IMT3BWC-Dmolliic.js → swimlanes-5IMT3BWC-CzX_Y32B.js} +1 -1
  85. package/web-dist/assets/swimlanesDiagram-G3AALYLV-UcSbtgIg.js +8 -0
  86. package/web-dist/assets/{timeline-definition-FHXFAJF6-CaYKZ8d2.js → timeline-definition-FHXFAJF6-Kkw3Kc6H.js} +1 -1
  87. package/web-dist/assets/{treeView-QDETBFTQ-Cap29KxK.js → treeView-QDETBFTQ-EuCs9-Ch.js} +1 -1
  88. package/web-dist/assets/{treemap-6X3UGDF4-DHF0hYTF.js → treemap-6X3UGDF4-C8bZntYA.js} +1 -1
  89. package/web-dist/assets/{vennDiagram-L72KCM5P-bYB1b7LV.js → vennDiagram-L72KCM5P-CK-XdQRZ.js} +1 -1
  90. package/web-dist/assets/{wardley-OPB4EBWU-B87GYnFj.js → wardley-OPB4EBWU-DwOmFrbt.js} +1 -1
  91. package/web-dist/assets/{wardleyDiagram-EHGQE667-d_o0fq6c.js → wardleyDiagram-EHGQE667-DtSbjytW.js} +1 -1
  92. package/web-dist/assets/{xychartDiagram-FW5EYKEG-C7Yzxgsj.js → xychartDiagram-FW5EYKEG-C-Onuqe8.js} +1 -1
  93. package/web-dist/index.html +2 -2
  94. package/web-dist/assets/architecture-TIHT7OUA-DbdGmECJ.js +0 -1
  95. package/web-dist/assets/channel-Bsh6-3G4.js +0 -1
  96. package/web-dist/assets/classDiagram-OUVF2IWQ-Ckmyj21K.js +0 -1
  97. package/web-dist/assets/classDiagram-v2-EOCWNBFH-Ckmyj21K.js +0 -1
  98. package/web-dist/assets/eventmodeling-45OFAUF4-Tx1KhZ5X.js +0 -1
  99. package/web-dist/assets/flowDiagram-23GEKE2U-Bl3doL2W.js +0 -1
  100. package/web-dist/assets/index-BTlrPmaN.css +0 -2
  101. package/web-dist/assets/index-Bb1sXlKY.js +0 -352
  102. package/web-dist/assets/railroad-abnf-AHOZXSZD-DgPnlcbw.js +0 -1
  103. package/web-dist/assets/railroad-ebnf-EBAXGLYW-CKHb6BBK.js +0 -1
  104. package/web-dist/assets/railroad-peg-LSFZ7HO6-ElDmcV57.js +0 -1
  105. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-BZGt-oDY.js +0 -1
  106. package/web-dist/assets/swimlanesDiagram-G3AALYLV-wHigalOx.js +0 -8
@@ -26181,15 +26181,16 @@ var RESERVED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "protot
26181
26181
  var DELIVERABLE_CONTROL_CODES = /* @__PURE__ */ new Set([9, 10, 13]);
26182
26182
  function hasUndeliverableInputText(value) {
26183
26183
  for (const character of value) {
26184
- const code = character.codePointAt(0);
26185
- if (code >= 55296 && code <= 57343) return true;
26186
- if (code === 8232 || code === 8233) return true;
26187
- if (code <= 31 || code >= 127 && code <= 159) {
26188
- if (!DELIVERABLE_CONTROL_CODES.has(code)) return true;
26189
- }
26184
+ if (isUndeliverableInputCode(character.codePointAt(0))) return true;
26190
26185
  }
26191
26186
  return false;
26192
26187
  }
26188
+ function isUndeliverableInputCode(code) {
26189
+ if (code >= 55296 && code <= 57343) return true;
26190
+ if (code === 8232 || code === 8233) return true;
26191
+ if (code <= 31 || code >= 127 && code <= 159) return !DELIVERABLE_CONTROL_CODES.has(code);
26192
+ return false;
26193
+ }
26193
26194
  var CLAUDE_BROKER_CAPABILITY_SUBAGENT_STEER = "subagent-steer-v1";
26194
26195
  var CLAUDE_BROKER_CAPABILITY_CANCEL_INPUT = "cancel-input-v1";
26195
26196
  var CLAUDE_BROKER_CAPABILITY_STOP_TASK = "stop-task-v1";
@@ -26197,6 +26198,7 @@ var CLAUDE_BROKER_CAPABILITY_RELOAD_PLUGINS = "reload-plugins-v1";
26197
26198
  var CLAUDE_BROKER_CAPABILITY_RENAME = "rename-v1";
26198
26199
  var CLAUDE_BROKER_CAPABILITY_LIST_SKILLS = "list-skills-v1";
26199
26200
  var CLAUDE_BROKER_CAPABILITY_INPUT_ACK = "input-ack-v1";
26201
+ var CLAUDE_SEND_NOW_OUTCOMES = ["stopped", "delivering", "nothing_waiting"];
26200
26202
  var CLAUDE_INPUT_DROP_DIAGNOSTIC_PREFIX = "input dropped, the agent never received it";
26201
26203
  var ClaudeAgentSdkProtocolError = class extends Error {
26202
26204
  constructor(message) {
@@ -26291,7 +26293,8 @@ function validateInputMessage(value) {
26291
26293
  const text = value.text;
26292
26294
  if (hasUndeliverableInputText(text)) throw new ClaudeAgentSdkProtocolError("input.text contains unsafe text");
26293
26295
  const parentToolUseId = boundedOptionalId(value.parentToolUseId, "input.parentToolUseId");
26294
- return parentToolUseId === void 0 ? { id: id2, text } : { id: id2, text, parentToolUseId };
26296
+ const human = value.human === true ? { human: true } : {};
26297
+ return parentToolUseId === void 0 ? { id: id2, text, ...human } : { id: id2, text, parentToolUseId, ...human };
26295
26298
  }
26296
26299
  function validatePermissionMode(value) {
26297
26300
  if (typeof value === "string" && ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"].includes(value)) {
@@ -26442,6 +26445,11 @@ function redactCredentialSyntax(raw, options = {}) {
26442
26445
  var CLAUDE_AGENT_SDK_CLIENT_APP = "frizz/claude-agent-sdk-foundation";
26443
26446
  var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
26444
26447
  var CLAUDE_SDK_CANCEL_METHOD = "cancelAsyncMessage";
26448
+ var CLAUDE_CLI_CAPABILITY_SEND_NOW = "interrupt_send_now_v1";
26449
+ var CLAUDE_SDK_REQUEST_METHOD = "request";
26450
+ function stillQueuedIds(raw) {
26451
+ return boundedStringArray(raw, "interrupt.stillQueued", 256, 512).map((id2, index) => boundedId(id2, `interrupt.stillQueued[${index}]`));
26452
+ }
26445
26453
  var ENV_KEY_PATTERN = /^[^=\0]+$/;
26446
26454
  var SENSITIVE_ENV_KEY = /(?:API_KEY|AUTH|BASE_URL|BEARER|COOKIE|CREDENTIAL|OAUTH|PASSWORD|PRIVATE|SECRET|TOKEN)/i;
26447
26455
  var MAX_ENV_ENTRIES = 512;
@@ -26467,6 +26475,7 @@ function createClaudeQueryFactory(options) {
26467
26475
  var BoundedAsyncQueue = class {
26468
26476
  buffered = [];
26469
26477
  waiters = [];
26478
+ drainListeners = [];
26470
26479
  ended = false;
26471
26480
  failure;
26472
26481
  limit;
@@ -26489,19 +26498,36 @@ var BoundedAsyncQueue = class {
26489
26498
  if (this.ended || this.failure) return;
26490
26499
  this.ended = true;
26491
26500
  for (const waiter of this.waiters.splice(0)) waiter.resolve({ done: true, value: void 0 });
26501
+ for (const settle of this.drainListeners.splice(0)) settle();
26492
26502
  }
26493
26503
  fail(error) {
26494
26504
  if (this.ended || this.failure) return;
26495
26505
  this.failure = error;
26496
26506
  this.buffered.splice(0);
26497
26507
  for (const waiter of this.waiters.splice(0)) waiter.reject(error);
26508
+ for (const settle of this.drainListeners.splice(0)) settle();
26498
26509
  }
26499
26510
  next() {
26500
26511
  const value = this.buffered.shift();
26501
26512
  if (value !== void 0) return Promise.resolve({ done: false, value });
26502
26513
  if (this.failure) return Promise.reject(this.failure);
26503
26514
  if (this.ended) return Promise.resolve({ done: true, value: void 0 });
26504
- return new Promise((resolve4, reject) => this.waiters.push({ resolve: resolve4, reject }));
26515
+ const parked = new Promise((resolve4, reject) => this.waiters.push({ resolve: resolve4, reject }));
26516
+ for (const settle of this.drainListeners.splice(0)) settle();
26517
+ return parked;
26518
+ }
26519
+ /**
26520
+ * Resolves once the consumer has taken everything pushed so far AND come back for more.
26521
+ *
26522
+ * For a consumer that finishes with one value before it asks for the next — the Agent SDK's input
26523
+ * loop writes each message to the CLI and only then pulls again — that is the instant the last pushed
26524
+ * value has been dealt with. It also resolves when the queue ends or fails: nothing more will be
26525
+ * taken, and the caller's next step meets that state on its own.
26526
+ */
26527
+ whenDrained() {
26528
+ if (this.ended || this.failure) return Promise.resolve();
26529
+ if (this.buffered.length === 0 && this.waiters.length > 0) return Promise.resolve();
26530
+ return new Promise((resolve4) => this.drainListeners.push(resolve4));
26505
26531
  }
26506
26532
  [Symbol.asyncIterator]() {
26507
26533
  return this;
@@ -26629,7 +26655,9 @@ var RealClaudeQueryHandle = class {
26629
26655
  // null = the session's main thread (every follow-up). A sub-agent STEER carries the child's
26630
26656
  // dispatch tool_use id here, which is the CLI's only addressing channel into a running child.
26631
26657
  parent_tool_use_id: parsed.parentToolUseId ?? null,
26632
- uuid: parsed.id
26658
+ uuid: parsed.id,
26659
+ // See ClaudeInputMessage.human: the runtime's send-now is gentle only for a person's message.
26660
+ ...parsed.human ? { origin: { kind: "human" } } : {}
26633
26661
  });
26634
26662
  } catch (error) {
26635
26663
  this.outstandingInputs.delete(parsed.id);
@@ -26651,13 +26679,49 @@ var RealClaudeQueryHandle = class {
26651
26679
  const result = await this.awaitOpenControl(this.sdkQuery.reinitialize());
26652
26680
  return mapControlInitialization(result);
26653
26681
  }
26654
- async interrupt() {
26682
+ async interrupt(options) {
26655
26683
  this.assertOpen();
26656
- await this.ready();
26684
+ const init = await this.ready();
26657
26685
  this.assertOpen();
26686
+ if (options?.sendNow && init.capabilities.includes(CLAUDE_CLI_CAPABILITY_SEND_NOW)) {
26687
+ const sent = await this.sendNow(options.sendNow.messageId);
26688
+ if (sent) return sent;
26689
+ }
26658
26690
  const receipt = await this.awaitOpenControl(this.sdkQuery.interrupt());
26659
26691
  if (!receipt) return void 0;
26660
- return { stillQueued: boundedStringArray(receipt.still_queued, "interrupt.stillQueued", 256, 512).map((id2, index) => boundedId(id2, `interrupt.stillQueued[${index}]`)) };
26692
+ return { stillQueued: stillQueuedIds(receipt.still_queued) };
26693
+ }
26694
+ // The runtime's own send-now (ClaudeInterruptOptions). Undefined ⇒ it could not be asked, and the
26695
+ // caller sends the plain interrupt it would have sent before this existed.
26696
+ //
26697
+ // THE ENVELOPE IS WRITTEN HERE, unlike `cancelInput`'s: SDK 0.3.296 has a method for a plain
26698
+ // interrupt and for `cancel_queued`, and none that carries `send_now`, so the request goes through the
26699
+ // query's own `request` — the same writer every one of its typed controls uses. The CLI advertises the
26700
+ // field (`interrupt_send_now_v1`), and a CLI without it reads the request as a plain interrupt, which
26701
+ // is the fallback anyway. If a later SDK drops `request`, this answers undefined and nothing is lost
26702
+ // but the gentleness; _live_broker_send_now.mts is what would say so.
26703
+ //
26704
+ // ORDER: the request must not overtake the message it names. `send` only PUSHES — the SDK's input loop
26705
+ // writes the message to the CLI on its own schedule — while a control request is written at once, so a
26706
+ // send-now issued straight after `send` reached the CLI first and was answered `nothing_waiting`: the
26707
+ // CLI had never heard of the message, did nothing, and the message then waited out the whole tool call
26708
+ // (measured, 4 of 4, 2026-10-13). `whenDrained` is the SDK having written everything pushed so far.
26709
+ async sendNow(messageId) {
26710
+ const provider = this.sdkQuery;
26711
+ const request = provider[CLAUDE_SDK_REQUEST_METHOD];
26712
+ if (typeof request !== "function") return void 0;
26713
+ const named = messageId !== void 0 && UUID_PATTERN.test(messageId) ? { message_uuid: messageId } : {};
26714
+ await this.input.whenDrained();
26715
+ this.assertOpen();
26716
+ const answer = await this.awaitOpenControl(request.call(this.sdkQuery, { subtype: "interrupt", send_now: true, ...named }));
26717
+ const response = answer?.response;
26718
+ const outcome = CLAUDE_SEND_NOW_OUTCOMES.find((known) => known === response?.send_now);
26719
+ return {
26720
+ stillQueued: Array.isArray(response?.still_queued) ? stillQueuedIds(response.still_queued) : [],
26721
+ // Absent when the CLI answered without one: it took the request as a plain interrupt, which has
26722
+ // happened by now either way, so there is nothing left to fall back to.
26723
+ ...outcome ? { sendNow: outcome } : {}
26724
+ };
26661
26725
  }
26662
26726
  async stopTask(taskId) {
26663
26727
  this.assertOpen();
@@ -28985,9 +29049,14 @@ function runClaudeBroker(config, options = {}) {
28985
29049
  pendingPermissions.delete(msg.requestId);
28986
29050
  e13.resolve(msg.decision);
28987
29051
  }
28988
- } else if (msg.t === "interrupt") void handle.interrupt().catch(() => {
28989
- });
28990
- else if (msg.t === "cancel-input") {
29052
+ } else if (msg.t === "interrupt") {
29053
+ const sendNow = msg.sendNow && typeof msg.sendNow === "object" ? msg.sendNow : void 0;
29054
+ const messageId = typeof sendNow?.messageId === "string" ? sendNow.messageId : void 0;
29055
+ void handle.interrupt(sendNow ? { sendNow: messageId ? { messageId } : {} } : void 0).then((receipt) => {
29056
+ if (sendNow) writeDiagnostic?.({ kind: "stderr", message: `send-now: ${receipt?.sendNow ?? "plain interrupt"}${messageId ? ` id=${messageId}` : ""}`, truncated: false });
29057
+ }, () => {
29058
+ });
29059
+ } else if (msg.t === "cancel-input") {
28991
29060
  const requestId = msg.requestId;
28992
29061
  const id2 = typeof msg.id === "string" ? msg.id : "";
28993
29062
  void handle.cancelInput(id2).then(