ai-whisper 0.4.2 → 0.4.4

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 (171) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/bin/broker-daemon.d.ts +3 -0
  3. package/dist/bin/broker-daemon.d.ts.map +1 -0
  4. package/dist/bin/companion-agent.d.ts +3 -0
  5. package/dist/bin/companion-agent.d.ts.map +1 -0
  6. package/dist/bin/relay-monitor.d.ts +3 -0
  7. package/dist/bin/relay-monitor.d.ts.map +1 -0
  8. package/dist/bin/whisper.d.ts +3 -0
  9. package/dist/bin/whisper.d.ts.map +1 -0
  10. package/dist/bin/whisper.js +182 -100
  11. package/dist/commands/collab/dashboard.d.ts +18 -0
  12. package/dist/commands/collab/dashboard.d.ts.map +1 -0
  13. package/dist/commands/collab/inspect.d.ts +23 -0
  14. package/dist/commands/collab/inspect.d.ts.map +1 -0
  15. package/dist/commands/collab/mount.d.ts +54 -0
  16. package/dist/commands/collab/mount.d.ts.map +1 -0
  17. package/dist/commands/collab/reconnect.d.ts +44 -0
  18. package/dist/commands/collab/reconnect.d.ts.map +1 -0
  19. package/dist/commands/collab/recover.d.ts +33 -0
  20. package/dist/commands/collab/recover.d.ts.map +1 -0
  21. package/dist/commands/collab/relay-monitor.d.ts +21 -0
  22. package/dist/commands/collab/relay-monitor.d.ts.map +1 -0
  23. package/dist/commands/collab/start.d.ts +53 -0
  24. package/dist/commands/collab/start.d.ts.map +1 -0
  25. package/dist/commands/collab/status.d.ts +6 -0
  26. package/dist/commands/collab/status.d.ts.map +1 -0
  27. package/dist/commands/collab/stop.d.ts +13 -0
  28. package/dist/commands/collab/stop.d.ts.map +1 -0
  29. package/dist/commands/collab/tell.d.ts +26 -0
  30. package/dist/commands/collab/tell.d.ts.map +1 -0
  31. package/dist/commands/skill/install.d.ts +12 -0
  32. package/dist/commands/skill/install.d.ts.map +1 -0
  33. package/dist/commands/workflow/cancel.d.ts +14 -0
  34. package/dist/commands/workflow/cancel.d.ts.map +1 -0
  35. package/dist/commands/workflow/inspect.d.ts +40 -0
  36. package/dist/commands/workflow/inspect.d.ts.map +1 -0
  37. package/dist/commands/workflow/list.d.ts +27 -0
  38. package/dist/commands/workflow/list.d.ts.map +1 -0
  39. package/dist/commands/workflow/pause.d.ts +14 -0
  40. package/dist/commands/workflow/pause.d.ts.map +1 -0
  41. package/dist/commands/workflow/resume.d.ts +17 -0
  42. package/dist/commands/workflow/resume.d.ts.map +1 -0
  43. package/dist/commands/workflow/start.d.ts +60 -0
  44. package/dist/commands/workflow/start.d.ts.map +1 -0
  45. package/dist/commands/workflow/types.d.ts +2 -0
  46. package/dist/commands/workflow/types.d.ts.map +1 -0
  47. package/dist/create-cli.d.ts +4 -0
  48. package/dist/create-cli.d.ts.map +1 -0
  49. package/dist/index.d.ts +5 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/runtime/action-inference.d.ts +3 -0
  52. package/dist/runtime/action-inference.d.ts.map +1 -0
  53. package/dist/runtime/artifact-input.d.ts +2 -0
  54. package/dist/runtime/artifact-input.d.ts.map +1 -0
  55. package/dist/runtime/assistant-turn-capture.d.ts +14 -0
  56. package/dist/runtime/assistant-turn-capture.d.ts.map +1 -0
  57. package/dist/runtime/bracketed-paste-detector.d.ts +16 -0
  58. package/dist/runtime/bracketed-paste-detector.d.ts.map +1 -0
  59. package/dist/runtime/broker-artifact-service.d.ts +48 -0
  60. package/dist/runtime/broker-artifact-service.d.ts.map +1 -0
  61. package/dist/runtime/broker-connect.d.ts +9 -0
  62. package/dist/runtime/broker-connect.d.ts.map +1 -0
  63. package/dist/runtime/broker-daemon.d.ts +25 -0
  64. package/dist/runtime/broker-daemon.d.ts.map +1 -0
  65. package/dist/runtime/busy-indicator.d.ts +11 -0
  66. package/dist/runtime/busy-indicator.d.ts.map +1 -0
  67. package/dist/runtime/capture-handback-text.d.ts +39 -0
  68. package/dist/runtime/capture-handback-text.d.ts.map +1 -0
  69. package/dist/runtime/clipboard-change-count.d.ts +12 -0
  70. package/dist/runtime/clipboard-change-count.d.ts.map +1 -0
  71. package/dist/runtime/clipboard-handback-capture.d.ts +13 -0
  72. package/dist/runtime/clipboard-handback-capture.d.ts.map +1 -0
  73. package/dist/runtime/collab-resolver.d.ts +36 -0
  74. package/dist/runtime/collab-resolver.d.ts.map +1 -0
  75. package/dist/runtime/companion-agent-loop.d.ts +13 -0
  76. package/dist/runtime/companion-agent-loop.d.ts.map +1 -0
  77. package/dist/runtime/context-injector.d.ts +20 -0
  78. package/dist/runtime/context-injector.d.ts.map +1 -0
  79. package/dist/runtime/context-policy.d.ts +3 -0
  80. package/dist/runtime/context-policy.d.ts.map +1 -0
  81. package/dist/runtime/current-tty.d.ts +2 -0
  82. package/dist/runtime/current-tty.d.ts.map +1 -0
  83. package/dist/runtime/dashboard-glyph.d.ts +12 -0
  84. package/dist/runtime/dashboard-glyph.d.ts.map +1 -0
  85. package/dist/runtime/dashboard-state.d.ts +182 -0
  86. package/dist/runtime/dashboard-state.d.ts.map +1 -0
  87. package/dist/runtime/dashboard-view.d.ts +34 -0
  88. package/dist/runtime/dashboard-view.d.ts.map +1 -0
  89. package/dist/runtime/dashboard.d.ts +46 -0
  90. package/dist/runtime/dashboard.d.ts.map +1 -0
  91. package/dist/runtime/evaluator-config.d.ts +21 -0
  92. package/dist/runtime/evaluator-config.d.ts.map +1 -0
  93. package/dist/runtime/evaluator-observer.d.ts +8 -0
  94. package/dist/runtime/evaluator-observer.d.ts.map +1 -0
  95. package/dist/runtime/id-factory.d.ts +5 -0
  96. package/dist/runtime/id-factory.d.ts.map +1 -0
  97. package/dist/runtime/launcher.d.ts +39 -0
  98. package/dist/runtime/launcher.d.ts.map +1 -0
  99. package/dist/runtime/live-session-broker-executor.d.ts +8 -0
  100. package/dist/runtime/live-session-broker-executor.d.ts.map +1 -0
  101. package/dist/runtime/live-session.d.ts +25 -0
  102. package/dist/runtime/live-session.d.ts.map +1 -0
  103. package/dist/runtime/load-dot-env.d.ts +6 -0
  104. package/dist/runtime/load-dot-env.d.ts.map +1 -0
  105. package/dist/runtime/local-multiline-composer.d.ts +23 -0
  106. package/dist/runtime/local-multiline-composer.d.ts.map +1 -0
  107. package/dist/runtime/mount-session-main.d.ts +44 -0
  108. package/dist/runtime/mount-session-main.d.ts.map +1 -0
  109. package/dist/runtime/mounted-turn-owned-relay.d.ts +160 -0
  110. package/dist/runtime/mounted-turn-owned-relay.d.ts.map +1 -0
  111. package/dist/runtime/on-demand-processing.d.ts +23 -0
  112. package/dist/runtime/on-demand-processing.d.ts.map +1 -0
  113. package/dist/runtime/operator-inspect-captures.d.ts +6 -0
  114. package/dist/runtime/operator-inspect-captures.d.ts.map +1 -0
  115. package/dist/runtime/operator-inspect-verdicts.d.ts +6 -0
  116. package/dist/runtime/operator-inspect-verdicts.d.ts.map +1 -0
  117. package/dist/runtime/operator-inspect.d.ts +137 -0
  118. package/dist/runtime/operator-inspect.d.ts.map +1 -0
  119. package/dist/runtime/paths.d.ts +2 -0
  120. package/dist/runtime/paths.d.ts.map +1 -0
  121. package/dist/runtime/port-allocator.d.ts +7 -0
  122. package/dist/runtime/port-allocator.d.ts.map +1 -0
  123. package/dist/runtime/port-utils.d.ts +3 -0
  124. package/dist/runtime/port-utils.d.ts.map +1 -0
  125. package/dist/runtime/process-start-time.d.ts +7 -0
  126. package/dist/runtime/process-start-time.d.ts.map +1 -0
  127. package/dist/runtime/provider-submit-strategy.d.ts +13 -0
  128. package/dist/runtime/provider-submit-strategy.d.ts.map +1 -0
  129. package/dist/runtime/providers.d.ts +17 -0
  130. package/dist/runtime/providers.d.ts.map +1 -0
  131. package/dist/runtime/record-evaluator-status.d.ts +9 -0
  132. package/dist/runtime/record-evaluator-status.d.ts.map +1 -0
  133. package/dist/runtime/recovery-guard.d.ts +12 -0
  134. package/dist/runtime/recovery-guard.d.ts.map +1 -0
  135. package/dist/runtime/relay-directive.d.ts +4 -0
  136. package/dist/runtime/relay-directive.d.ts.map +1 -0
  137. package/dist/runtime/relay-line-buffer.d.ts +22 -0
  138. package/dist/runtime/relay-line-buffer.d.ts.map +1 -0
  139. package/dist/runtime/relay-monitor.d.ts +26 -0
  140. package/dist/runtime/relay-monitor.d.ts.map +1 -0
  141. package/dist/runtime/relay-orchestrator-evaluator.d.ts +160 -0
  142. package/dist/runtime/relay-orchestrator-evaluator.d.ts.map +1 -0
  143. package/dist/runtime/relay-orchestrator.d.ts +116 -0
  144. package/dist/runtime/relay-orchestrator.d.ts.map +1 -0
  145. package/dist/runtime/relay-pane-writer.d.ts +28 -0
  146. package/dist/runtime/relay-pane-writer.d.ts.map +1 -0
  147. package/dist/runtime/relay-service.d.ts +76 -0
  148. package/dist/runtime/relay-service.d.ts.map +1 -0
  149. package/dist/runtime/relay-view-input.d.ts +17 -0
  150. package/dist/runtime/relay-view-input.d.ts.map +1 -0
  151. package/dist/runtime/relay-view-state.d.ts +86 -0
  152. package/dist/runtime/relay-view-state.d.ts.map +1 -0
  153. package/dist/runtime/relay-view.d.ts +16 -0
  154. package/dist/runtime/relay-view.d.ts.map +1 -0
  155. package/dist/runtime/reply-wait.d.ts +21 -0
  156. package/dist/runtime/reply-wait.d.ts.map +1 -0
  157. package/dist/runtime/runtime-debug-log.d.ts +7 -0
  158. package/dist/runtime/runtime-debug-log.d.ts.map +1 -0
  159. package/dist/runtime/state-root.d.ts +3 -0
  160. package/dist/runtime/state-root.d.ts.map +1 -0
  161. package/dist/runtime/terminal-input-normalizer.d.ts +11 -0
  162. package/dist/runtime/terminal-input-normalizer.d.ts.map +1 -0
  163. package/dist/runtime/theme.d.ts +15 -0
  164. package/dist/runtime/theme.d.ts.map +1 -0
  165. package/dist/runtime/version-check.d.ts +17 -0
  166. package/dist/runtime/version-check.d.ts.map +1 -0
  167. package/dist/runtime/wait-for-broker-ready.d.ts +13 -0
  168. package/dist/runtime/wait-for-broker-ready.d.ts.map +1 -0
  169. package/dist/runtime/workspace-id.d.ts +3 -0
  170. package/dist/runtime/workspace-id.d.ts.map +1 -0
  171. package/package.json +3 -3
@@ -9497,6 +9497,10 @@ function createMountedTurnOwnedRelay(input) {
9497
9497
  }
9498
9498
  const STALE_HANDOFF_AFTER_MS = 5 * 6e4;
9499
9499
  const HAND_BACK_READY_AFTER_MS = 3e4;
9500
+ const autoHandbackMaxAttempts = Math.max(1, input.autoHandbackMaxAttempts ?? 3);
9501
+ const autoHandbackRetryMs = Math.max(0, input.autoHandbackRetryMs ?? 1e4);
9502
+ const autoHandbackAttempts = /* @__PURE__ */ new Map();
9503
+ let autoHandbackInFlight = false;
9500
9504
  let disconnectHandled = false;
9501
9505
  let lastOwnerCardKey = null;
9502
9506
  let renderedOwnerCardLines = 0;
@@ -9788,110 +9792,134 @@ ${hint}`,
9788
9792
  if (accepted === null || autoHandbackFiredFor === accepted.handoffId || (input.isPausedInput?.() ?? false)) {
9789
9793
  return;
9790
9794
  }
9791
- autoHandbackFiredFor = accepted.handoffId;
9792
- input.turnCapture?.finishAssistantTurn();
9793
- const turnResult = input.turnCapture?.extractLatestAssistantTurn() ?? { confidence: "low", text: null };
9794
- console.warn(
9795
- `[ai-whisper] auto-handback fire: target=${input.currentAgent} handoff=${accepted.handoffId} turnLen=${(turnResult.text ?? "").length} turnConf=${turnResult.confidence}`
9796
- );
9797
- let clipboardText = null;
9798
- let leaseDegraded = false;
9799
- let interferenceDetected = false;
9795
+ const retryState = autoHandbackAttempts.get(accepted.handoffId) ?? {
9796
+ attempts: 0,
9797
+ nextEligibleAt: 0
9798
+ };
9799
+ if (Date.now() < retryState.nextEligibleAt) {
9800
+ return;
9801
+ }
9802
+ if (autoHandbackInFlight) return;
9803
+ autoHandbackInFlight = true;
9800
9804
  try {
9801
- const captureResult = await input.captureHandbackText?.(turnResult.text ?? "") ?? null;
9802
- if (typeof captureResult === "string") {
9803
- clipboardText = captureResult;
9804
- } else if (captureResult !== null) {
9805
- interferenceDetected = captureResult.interferenceDetected;
9806
- if (captureResult.status === "captured") {
9807
- clipboardText = captureResult.text;
9805
+ input.turnCapture?.finishAssistantTurn();
9806
+ const turnResult = input.turnCapture?.extractLatestAssistantTurn() ?? { confidence: "low", text: null };
9807
+ console.warn(
9808
+ `[ai-whisper] auto-handback fire: target=${input.currentAgent} handoff=${accepted.handoffId} turnLen=${(turnResult.text ?? "").length} turnConf=${turnResult.confidence}`
9809
+ );
9810
+ let clipboardText = null;
9811
+ let leaseDegraded = false;
9812
+ let interferenceDetected = false;
9813
+ try {
9814
+ const captureResult = await input.captureHandbackText?.(turnResult.text ?? "") ?? null;
9815
+ if (typeof captureResult === "string") {
9816
+ clipboardText = captureResult;
9817
+ } else if (captureResult !== null) {
9818
+ interferenceDetected = captureResult.interferenceDetected;
9819
+ if (captureResult.status === "captured") {
9820
+ clipboardText = captureResult.text;
9821
+ } else {
9822
+ leaseDegraded = true;
9823
+ console.warn(
9824
+ `[ai-whisper] capture lease degraded: target=${input.currentAgent} handoff=${accepted.handoffId} interference=${interferenceDetected} \u2014 /copy was NOT executed; PTY fallback only`
9825
+ );
9826
+ }
9808
9827
  } else {
9809
- leaseDegraded = true;
9810
9828
  console.warn(
9811
- `[ai-whisper] capture lease degraded: target=${input.currentAgent} handoff=${accepted.handoffId} interference=${interferenceDetected} \u2014 /copy was NOT executed; PTY fallback only`
9829
+ `[ai-whisper] capture pipeline returned null: target=${input.currentAgent} handoff=${accepted.handoffId} \u2014 captureHandbackText short-circuited (likely no session claim)`
9812
9830
  );
9813
9831
  }
9814
- } else {
9832
+ } catch (err) {
9833
+ clipboardText = null;
9834
+ const msg = err instanceof Error ? `${err.message}
9835
+ ${err.stack ?? ""}` : String(err);
9815
9836
  console.warn(
9816
- `[ai-whisper] capture pipeline returned null: target=${input.currentAgent} handoff=${accepted.handoffId} \u2014 captureHandbackText short-circuited (likely no session claim)`
9837
+ `[ai-whisper] capture pipeline threw (swallowed): target=${input.currentAgent} handoff=${accepted.handoffId}
9838
+ ${msg}`
9817
9839
  );
9818
9840
  }
9819
- } catch (err) {
9820
- clipboardText = null;
9821
- const msg = err instanceof Error ? `${err.message}
9822
- ${err.stack ?? ""}` : String(err);
9823
- console.warn(
9824
- `[ai-whisper] capture pipeline threw (swallowed): target=${input.currentAgent} handoff=${accepted.handoffId}
9825
- ${msg}`
9826
- );
9827
- }
9828
- const classification = classifyCapture(turnResult, clipboardText);
9829
- const captureStatus = classification.status;
9830
- let requestText = captureStatus === "ok" ? clipboardText ?? "" : "";
9831
- if (leaseDegraded && (turnResult.text ?? "").trim().length > 0) {
9832
- requestText = turnResult.text;
9833
- }
9834
- const currentAcceptedId = getAcceptedHandoff()?.handoffId;
9835
- const abortedByRaceGuard = currentAcceptedId !== accepted.handoffId;
9836
- const handoffMeta = input.broker.control.getHandoffWithWorkflowMeta?.(accepted.handoffId) ?? null;
9837
- const samplesAllowed = process.env["AI_WHISPER_NO_CAPTURE_SAMPLES"] !== "1";
9838
- const sampleOf = (text) => {
9839
- if (text === null) return null;
9840
- if (!samplesAllowed) return null;
9841
- return text.slice(0, 200);
9842
- };
9843
- const now = (/* @__PURE__ */ new Date()).toISOString();
9844
- try {
9845
- input.broker.control.recordCaptureDiagnostic?.({
9841
+ const classification = classifyCapture(turnResult, clipboardText);
9842
+ const captureStatus = classification.status;
9843
+ let requestText = captureStatus === "ok" ? clipboardText ?? "" : "";
9844
+ if (leaseDegraded && (turnResult.text ?? "").trim().length > 0) {
9845
+ requestText = turnResult.text;
9846
+ }
9847
+ const capturedNothing = captureStatus === "no_response_captured";
9848
+ if (capturedNothing && retryState.attempts + 1 < autoHandbackMaxAttempts) {
9849
+ retryState.attempts += 1;
9850
+ retryState.nextEligibleAt = Date.now() + autoHandbackRetryMs;
9851
+ autoHandbackAttempts.set(accepted.handoffId, retryState);
9852
+ console.warn(
9853
+ `[ai-whisper] auto-handback empty capture \u2014 retrying: target=${input.currentAgent} handoff=${accepted.handoffId} attempt=${retryState.attempts}/${autoHandbackMaxAttempts}`
9854
+ );
9855
+ return;
9856
+ }
9857
+ autoHandbackFiredFor = accepted.handoffId;
9858
+ autoHandbackAttempts.delete(accepted.handoffId);
9859
+ const currentAcceptedId = getAcceptedHandoff()?.handoffId;
9860
+ const abortedByRaceGuard = currentAcceptedId !== accepted.handoffId;
9861
+ const handoffMeta = input.broker.control.getHandoffWithWorkflowMeta?.(accepted.handoffId) ?? null;
9862
+ const samplesAllowed = process.env["AI_WHISPER_NO_CAPTURE_SAMPLES"] !== "1";
9863
+ const sampleOf = (text) => {
9864
+ if (text === null) return null;
9865
+ if (!samplesAllowed) return null;
9866
+ return text.slice(0, 200);
9867
+ };
9868
+ const now = (/* @__PURE__ */ new Date()).toISOString();
9869
+ try {
9870
+ input.broker.control.recordCaptureDiagnostic?.({
9871
+ handoffId: accepted.handoffId,
9872
+ collabId: input.collabId,
9873
+ chainId: handoffMeta?.chainId ?? null,
9874
+ workflowId: handoffMeta?.workflowId ?? null,
9875
+ targetProvider: input.currentAgent,
9876
+ captureStatus,
9877
+ clipLen: (clipboardText ?? "").length,
9878
+ turnLen: (turnResult.text ?? "").length,
9879
+ turnConfidence: turnResult.confidence,
9880
+ jaccardScore: classification.jaccardScore,
9881
+ containmentScore: classification.containmentScore,
9882
+ clipSample: sampleOf(clipboardText),
9883
+ turnSample: sampleOf(turnResult.text),
9884
+ abortedByRaceGuard,
9885
+ interferenceDetected,
9886
+ now
9887
+ });
9888
+ } catch (err) {
9889
+ console.warn(
9890
+ `[ai-whisper] capture diagnostic write failed: ${err instanceof Error ? err.message : String(err)}`
9891
+ );
9892
+ }
9893
+ if (process.env["AI_WHISPER_DEBUG_CAPTURE"]) {
9894
+ const { writeFileSync: writeFileSync3 } = await import("node:fs");
9895
+ writeFileSync3(
9896
+ process.env["AI_WHISPER_DEBUG_CAPTURE"],
9897
+ JSON.stringify({
9898
+ captureStatus,
9899
+ jaccardScore: classification.jaccardScore,
9900
+ containmentScore: classification.containmentScore,
9901
+ turnTextLen: (turnResult.text ?? "").length,
9902
+ clipLen: (clipboardText ?? "").length,
9903
+ turnText: turnResult.text,
9904
+ clipText: clipboardText
9905
+ }, null, 2),
9906
+ "utf8"
9907
+ );
9908
+ }
9909
+ if (abortedByRaceGuard) return;
9910
+ input.broker.control.handoffBackRelay?.({
9846
9911
  handoffId: accepted.handoffId,
9847
- collabId: input.collabId,
9848
- chainId: handoffMeta?.chainId ?? null,
9849
- workflowId: handoffMeta?.workflowId ?? null,
9850
- targetProvider: input.currentAgent,
9912
+ nextHandoffId: `handoff_${now.replace(/[^0-9]/g, "")}`,
9913
+ senderAgent: input.currentAgent,
9914
+ targetAgent: accepted.senderAgent,
9915
+ requestText,
9851
9916
  captureStatus,
9852
- clipLen: (clipboardText ?? "").length,
9853
- turnLen: (turnResult.text ?? "").length,
9854
- turnConfidence: turnResult.confidence,
9855
- jaccardScore: classification.jaccardScore,
9856
- containmentScore: classification.containmentScore,
9857
- clipSample: sampleOf(clipboardText),
9858
- turnSample: sampleOf(turnResult.text),
9859
- abortedByRaceGuard,
9860
- interferenceDetected,
9861
9917
  now
9862
9918
  });
9863
- } catch (err) {
9864
- console.warn(
9865
- `[ai-whisper] capture diagnostic write failed: ${err instanceof Error ? err.message : String(err)}`
9866
- );
9867
- }
9868
- if (process.env["AI_WHISPER_DEBUG_CAPTURE"]) {
9869
- const { writeFileSync: writeFileSync3 } = await import("node:fs");
9870
- writeFileSync3(
9871
- process.env["AI_WHISPER_DEBUG_CAPTURE"],
9872
- JSON.stringify({
9873
- captureStatus,
9874
- jaccardScore: classification.jaccardScore,
9875
- containmentScore: classification.containmentScore,
9876
- turnTextLen: (turnResult.text ?? "").length,
9877
- clipLen: (clipboardText ?? "").length,
9878
- turnText: turnResult.text,
9879
- clipText: clipboardText
9880
- }, null, 2),
9881
- "utf8"
9882
- );
9919
+ input.turnCapture?.reset();
9920
+ } finally {
9921
+ autoHandbackInFlight = false;
9883
9922
  }
9884
- if (abortedByRaceGuard) return;
9885
- input.broker.control.handoffBackRelay?.({
9886
- handoffId: accepted.handoffId,
9887
- nextHandoffId: `handoff_${now.replace(/[^0-9]/g, "")}`,
9888
- senderAgent: input.currentAgent,
9889
- targetAgent: accepted.senderAgent,
9890
- requestText,
9891
- captureStatus,
9892
- now
9893
- });
9894
- input.turnCapture?.reset();
9895
9923
  },
9896
9924
  handleOwnerDisconnect() {
9897
9925
  if (disconnectHandled) return;
@@ -10269,22 +10297,56 @@ function makeChangeCountReader(deps) {
10269
10297
  }
10270
10298
 
10271
10299
  // src/runtime/provider-submit-strategy.ts
10300
+ var PASTE_START = "\x1B[200~";
10301
+ var PASTE_END = "\x1B[201~";
10272
10302
  async function submitInjectedProviderInput(input) {
10273
10303
  const sleep3 = input.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms)));
10274
- if (input.target === "codex") {
10275
- for (const char of input.text) {
10276
- input.writeUserInput(char);
10277
- await sleep3(5);
10278
- }
10304
+ if (input.target === "claude") {
10305
+ input.writeUserInput(input.text);
10306
+ await sleep3(75);
10307
+ input.writeUserInput("\r");
10308
+ return;
10309
+ }
10310
+ const strategy = input.strategyOverride ?? (input.bracketedPasteEnabled ? "bracketed" : "keystream");
10311
+ if (strategy === "bracketed") {
10312
+ const safe = input.text.split(PASTE_END).join("");
10313
+ input.writeUserInput(PASTE_START + safe + PASTE_END);
10279
10314
  await sleep3(100);
10280
10315
  input.writeUserInput("\r");
10281
10316
  return;
10282
10317
  }
10283
- input.writeUserInput(input.text);
10284
- await sleep3(75);
10318
+ if (strategy === "chunk") {
10319
+ input.writeUserInput(input.text);
10320
+ await sleep3(75);
10321
+ input.writeUserInput("\r");
10322
+ return;
10323
+ }
10324
+ for (const char of input.text) {
10325
+ input.writeUserInput(char);
10326
+ await sleep3(5);
10327
+ }
10328
+ await sleep3(100);
10285
10329
  input.writeUserInput("\r");
10286
10330
  }
10287
10331
 
10332
+ // src/runtime/bracketed-paste-detector.ts
10333
+ var ENABLE = "\x1B[?2004h";
10334
+ var RESET2 = "\x1B[?2004l";
10335
+ function createBracketedPasteDetector() {
10336
+ let enabled = false;
10337
+ return {
10338
+ observe(data) {
10339
+ const hi = data.lastIndexOf(ENABLE);
10340
+ const lo = data.lastIndexOf(RESET2);
10341
+ if (hi > lo) enabled = true;
10342
+ else if (lo > hi) enabled = false;
10343
+ },
10344
+ get enabled() {
10345
+ return enabled;
10346
+ }
10347
+ };
10348
+ }
10349
+
10288
10350
  // src/runtime/runtime-debug-log.ts
10289
10351
  import { appendFileSync as appendFileSync4 } from "node:fs";
10290
10352
  function toHex2(text) {
@@ -10312,6 +10374,15 @@ function createRuntimeDebugLogger(input) {
10312
10374
  }
10313
10375
 
10314
10376
  // src/runtime/mount-session-main.ts
10377
+ function resolveCodexSubmitStrategyOverride() {
10378
+ const raw = process.env.AI_WHISPER_CODEX_SUBMIT_STRATEGY;
10379
+ if (raw === "bracketed" || raw === "keystream" || raw === "chunk") return raw;
10380
+ return void 0;
10381
+ }
10382
+ function resolvePositiveIntEnv(name) {
10383
+ const n = Number(process.env[name] ?? "");
10384
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : void 0;
10385
+ }
10315
10386
  var readChangeCount = makeChangeCountReader();
10316
10387
  function safeReapSessions(input) {
10317
10388
  const reap = input.reap ?? ((collabId, agentType, keepSessionId) => {
@@ -10416,6 +10487,8 @@ function createMountSessionRuntime(input) {
10416
10487
  let lastActivityAt = Date.now();
10417
10488
  try {
10418
10489
  const turnCapture = createAssistantTurnCapture();
10490
+ const bracketedPaste = createBracketedPasteDetector();
10491
+ const codexStrategyOverride = resolveCodexSubmitStrategyOverride();
10419
10492
  const debugLog = createRuntimeDebugLogger({
10420
10493
  logPath: process.env.AI_WHISPER_DEBUG_INPUT_LOG ?? null,
10421
10494
  sessionId: process.env.AI_WHISPER_SESSION_ID ?? null
@@ -10437,12 +10510,15 @@ function createMountSessionRuntime(input) {
10437
10510
  await submitInjectedProviderInput({
10438
10511
  target: input.target,
10439
10512
  text,
10440
- writeUserInput: (value) => writeInjectedInput("mounted-submit", value)
10513
+ writeUserInput: (value) => writeInjectedInput("mounted-submit", value),
10514
+ bracketedPasteEnabled: bracketedPaste.enabled,
10515
+ strategyOverride: codexStrategyOverride
10441
10516
  });
10442
10517
  };
10443
10518
  interactiveSession.onProviderOutput?.((data) => {
10444
10519
  lastActivityAt = Date.now();
10445
10520
  turnCapture.recordProviderOutput(data);
10521
+ bracketedPaste.observe(data);
10446
10522
  });
10447
10523
  const onRelay = (directive, sendNow) => {
10448
10524
  if (!resolvedClaim) {
@@ -10597,7 +10673,13 @@ function createMountSessionRuntime(input) {
10597
10673
  return runConfirm();
10598
10674
  },
10599
10675
  prefillHandbackFromCapture: false,
10600
- turnCapture
10676
+ turnCapture,
10677
+ autoHandbackMaxAttempts: resolvePositiveIntEnv(
10678
+ "AI_WHISPER_AUTO_HANDBACK_MAX_ATTEMPTS"
10679
+ ),
10680
+ autoHandbackRetryMs: resolvePositiveIntEnv(
10681
+ "AI_WHISPER_AUTO_HANDBACK_RETRY_MS"
10682
+ )
10601
10683
  });
10602
10684
  const mountedTurnRelay = turnRelay;
10603
10685
  interactiveSession.onExit(() => {
@@ -0,0 +1,18 @@
1
+ type BrokerLike = {
2
+ stop: () => Promise<void>;
3
+ };
4
+ type RuntimeLike = {
5
+ start: () => void;
6
+ stop: () => Promise<void>;
7
+ waitUntilStopped: () => Promise<void>;
8
+ };
9
+ export declare function runCollabDashboard(input?: {
10
+ stdout?: NodeJS.WritableStream;
11
+ /** Eligible-collab window in ms (overrides env + default). */
12
+ windowMs?: number;
13
+ __createBroker?: () => BrokerLike;
14
+ __createRuntime?: (broker: BrokerLike, dashboardId: string, stdout: NodeJS.WritableStream) => RuntimeLike;
15
+ __noSignals?: boolean;
16
+ }): Promise<void>;
17
+ export {};
18
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/dashboard.ts"],"names":[],"mappings":"AAKA,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAChD,KAAK,WAAW,GAAG;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,KAAK,CAAC,EAAE;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,UAAU,CAAC;IAClC,eAAe,CAAC,EAAE,CACjB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,KACzB,WAAW,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,iBAsDA"}
@@ -0,0 +1,23 @@
1
+ export type CapturesArg = true | string;
2
+ export type VerdictsArg = true | string;
3
+ type BrokerAssessor = (input: {
4
+ host: string;
5
+ port: number;
6
+ pid: number;
7
+ }) => Promise<{
8
+ ok: boolean;
9
+ }>;
10
+ export declare function runCollabInspect(input: {
11
+ cwd: string;
12
+ collabIdOverride?: string;
13
+ now: string;
14
+ watch: boolean;
15
+ captures?: CapturesArg;
16
+ verdicts?: VerdictsArg;
17
+ assessBroker?: BrokerAssessor;
18
+ write?: (chunk: string) => void;
19
+ sleep?: (ms: number) => Promise<void>;
20
+ watchIntervalMs?: number;
21
+ }): Promise<string | null>;
22
+ export {};
23
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/inspect.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC;AACxC,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC;AAKxC,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACZ,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAE/B,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB,0BA4JA"}
@@ -0,0 +1,54 @@
1
+ import { assessBrokerDaemon } from "../../runtime/broker-daemon.js";
2
+ import { createMountSessionRuntime } from "../../runtime/mount-session-main.js";
3
+ import { runCollabRecover } from "./recover.js";
4
+ import { runCollabStart } from "./start.js";
5
+ export declare function recordMountedSession(input: {
6
+ cwd: string;
7
+ agentType: "codex" | "claude";
8
+ ttyPath: string;
9
+ pid: number;
10
+ collabIdOverride?: string;
11
+ }): void;
12
+ export declare function runCollabMount(input: {
13
+ workspaceRoot: string;
14
+ collabIdOverride?: string;
15
+ target: "codex" | "claude";
16
+ /**
17
+ * Args forwarded after `--` to the visible agent binary spawn
18
+ * (e.g. `mount codex -- --full-auto --model gpt-5`). Threaded to
19
+ * createInteractiveSessionForTarget only — the relay/companion provider
20
+ * side is unaffected. Defaults to []. No shell escaping; the CLI relies
21
+ * on commander 13's variadic positional to yield a clean string[].
22
+ */
23
+ passthroughArgs?: string[];
24
+ now: string;
25
+ resolveCurrentTty?: () => string;
26
+ createRuntime?: typeof createMountSessionRuntime;
27
+ assessBroker?: typeof assessBrokerDaemon;
28
+ /**
29
+ * Test seam: override the auto-create call. Defaults to runCollabStart.
30
+ * Used in tests to simulate a parallel mount winning the create race.
31
+ */
32
+ runStartFn?: typeof runCollabStart;
33
+ /**
34
+ * Test seam: override the pid liveness check used when deciding whether a
35
+ * "bound" binding has a live owner. Defaults to defaultIsPidAlive.
36
+ */
37
+ isPidAlive?: (pid: number) => boolean;
38
+ /**
39
+ * Test seam: override the daemon-revive call used to transparently re-adopt
40
+ * an existing active collab whose daemon is dead. Defaults to runCollabRecover.
41
+ */
42
+ runRecoverFn?: typeof runCollabRecover;
43
+ /**
44
+ * Test seam: liveness probe for the resolved collab's DAEMON pid. The
45
+ * resolver treats any non-null pid as "live" (it does not call
46
+ * process.kill), so a stale non-null pid left behind by a crashed/restarted
47
+ * daemon would otherwise be reused as if healthy. mount probes the daemon
48
+ * pid here and, when dead, transparently re-adopts via recover. Defaults to
49
+ * defaultIsPidAlive. NOTE: distinct from `isPidAlive`, which probes the
50
+ * mounted session-attachment owner pid.
51
+ */
52
+ isDaemonPidAlive?: (pid: number) => boolean;
53
+ }): Promise<void>;
54
+ //# sourceMappingURL=mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/mount.ts"],"names":[],"mappings":"AASA,OAAO,EACN,kBAAkB,EAElB,MAAM,gCAAgC,CAAC;AAMxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAOhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAY5C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,IAAI,CAyBP;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,yBAAyB,CAAC;IACjD,YAAY,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACzC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,cAAc,CAAC;IACnC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACvC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C,iBAoPA"}
@@ -0,0 +1,44 @@
1
+ import { type BrokerRuntime } from "@ai-whisper/broker";
2
+ export interface ReattachableSession {
3
+ agentType: "codex" | "claude";
4
+ attachmentKind: "mounted" | "adopted";
5
+ ttyPath: string;
6
+ pid: number | null;
7
+ }
8
+ export declare function listReattachableSessions(input: {
9
+ cwd: string;
10
+ collabIdOverride?: string;
11
+ }): ReattachableSession[];
12
+ export declare function runCollabReconnect(input: {
13
+ workspaceRoot: string;
14
+ collabIdOverride?: string;
15
+ target: "codex" | "claude";
16
+ now: string;
17
+ resolveCurrentTty?: () => string;
18
+ startMountedSession?: (input: {
19
+ target: "codex" | "claude";
20
+ workspaceRoot: string;
21
+ ttyPath: string;
22
+ claimId: string;
23
+ secret: string;
24
+ broker: BrokerRuntime;
25
+ }) => Promise<void>;
26
+ }): Promise<{
27
+ mode: "mounted";
28
+ claim: {
29
+ status: "pending" | "consumed" | "expired" | "replaced";
30
+ version: 1;
31
+ collabId: string;
32
+ createdAt: string;
33
+ claimId: string;
34
+ agentType: "codex" | "claude";
35
+ mode: "attach" | "rebind" | "reconnect";
36
+ targetMode: "snippet_shell" | "adopt_current_tty" | "explicit_tty" | "mount_current_tty";
37
+ targetTtyPath: string | null;
38
+ secret: string;
39
+ expiresAt: string;
40
+ consumedAt: string | null;
41
+ };
42
+ ttyPath: string;
43
+ }>;
44
+ //# sourceMappingURL=reconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAM3F,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC9B,cAAc,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,mBAAmB,EAAE,CAyBxB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE;QAC7B,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,aAAa,CAAC;KACtB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;;;;;;;;;;;;;;;;;GAmFA"}
@@ -0,0 +1,33 @@
1
+ import { type IsAliveResult } from "@ai-whisper/broker";
2
+ export interface CollabRecoverResult {
3
+ collabId: string;
4
+ host: string;
5
+ port: number;
6
+ pid: number;
7
+ }
8
+ export interface CollabRecoverOpts {
9
+ cwd: string;
10
+ collabIdOverride?: string;
11
+ explicitPort?: number;
12
+ portRange?: readonly [number, number];
13
+ now: () => string;
14
+ isPortFreeOs: (port: number) => Promise<boolean>;
15
+ isAlive?: (pid: number) => Promise<IsAliveResult>;
16
+ spawnBroker: (input: {
17
+ collabId: string;
18
+ host: string;
19
+ port: number;
20
+ sqlitePath: string;
21
+ }) => number;
22
+ waitForReady: (input: {
23
+ host: string;
24
+ port: number;
25
+ collabId: string;
26
+ timeoutMs: number;
27
+ }) => Promise<boolean>;
28
+ signalProcess: (pid: number, signal: "SIGTERM" | "SIGKILL") => void;
29
+ readyTimeoutMs?: number;
30
+ staleThresholdMs?: number;
31
+ }
32
+ export declare function runCollabRecover(opts: CollabRecoverOpts): Promise<CollabRecoverResult>;
33
+ //# sourceMappingURL=recover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/recover.ts"],"names":[],"mappings":"AAAA,OAAO,EAQN,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACnB,KAAK,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,KAAK,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAgBD,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,mBAAmB,CAAC,CAiO9B"}
@@ -0,0 +1,21 @@
1
+ import { assessBrokerDaemon } from "../../runtime/broker-daemon.js";
2
+ export interface RelayMonitorTargets {
3
+ collabId: string;
4
+ sqlitePath: string;
5
+ }
6
+ export declare function resolveRelayMonitorTargets(input: {
7
+ cwd: string;
8
+ collabIdOverride?: string;
9
+ }): RelayMonitorTargets;
10
+ export declare function runCollabRelayMonitor(input: {
11
+ cwd: string;
12
+ collabIdOverride?: string;
13
+ assessBroker?: typeof assessBrokerDaemon;
14
+ brokerEnv?: {
15
+ sqlitePath: string;
16
+ host: string;
17
+ port: number;
18
+ collabId: string;
19
+ };
20
+ }): Promise<void>;
21
+ //# sourceMappingURL=relay-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-monitor.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/relay-monitor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAKpE,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,mBAAmB,CAetB;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACzC,SAAS,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACjF,iBAuEA"}
@@ -0,0 +1,53 @@
1
+ import type { LaunchMode, LaunchResult } from "../../runtime/launcher.js";
2
+ export interface CollabStartResult {
3
+ collabId: string;
4
+ port: number;
5
+ host: string;
6
+ pid: number;
7
+ }
8
+ export interface CollabStartOpts {
9
+ cwd: string;
10
+ displayName: string;
11
+ launchMode: LaunchMode;
12
+ tmuxSession?: string;
13
+ explicitPort?: number;
14
+ portRange?: readonly [number, number];
15
+ now: () => string;
16
+ isPortFreeOs: (port: number) => Promise<boolean>;
17
+ spawnBroker: (input: {
18
+ collabId: string;
19
+ host: string;
20
+ port: number;
21
+ sqlitePath: string;
22
+ }) => number;
23
+ waitForReady: (input: {
24
+ host: string;
25
+ port: number;
26
+ collabId: string;
27
+ timeoutMs: number;
28
+ }) => Promise<boolean>;
29
+ signalProcess: (pid: number, signal: "SIGTERM" | "SIGKILL") => void;
30
+ readyTimeoutMs?: number;
31
+ }
32
+ export declare function runCollabStart(opts: CollabStartOpts): Promise<CollabStartResult>;
33
+ /**
34
+ * Persists the runtime metadata produced by `launchSessions` so that
35
+ * `whisper collab stop` can tear down what `start` launched. Symmetric
36
+ * with `recordMountedSession` in mount.ts.
37
+ *
38
+ * - tmux mode: records the deterministic tmux session name on the collab
39
+ * row so stop issues `tmux kill-session`.
40
+ * - terminals mode: records each launched codex/claude window (kind
41
+ * "owned") so stop closes the window and signals the pid. The
42
+ * relay-monitor's terminal window/pid cannot live in
43
+ * `session_attachment` (its PK is `(collab_id, agent_type,
44
+ * attachment_kind)` and `agent_type` is constrained to
45
+ * `codex|claude`), so they are persisted on the `collab` row
46
+ * instead (parallel to `tmux_session`) for stop to tear down.
47
+ */
48
+ export declare function recordLaunchedSessions(input: {
49
+ collabId: string;
50
+ launchMode: "tmux" | "terminals";
51
+ launch: LaunchResult;
52
+ }): void;
53
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/start.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAW1E,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,KAAK,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACnB,KAAK,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,KAAK,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,wBAAsB,cAAc,CACnC,IAAI,EAAE,eAAe,GACnB,OAAO,CAAC,iBAAiB,CAAC,CA2K5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,MAAM,EAAE,YAAY,CAAC;CACrB,GAAG,IAAI,CAsEP"}
@@ -0,0 +1,6 @@
1
+ export declare function runCollabStatus(input: {
2
+ cwd: string;
3
+ collabIdOverride?: string;
4
+ json?: boolean;
5
+ }): string;
6
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/collab/status.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CACf,GAAG,MAAM,CA8DT"}