ai-whisper 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin/whisper.js +63 -23
  2. package/package.json +3 -3
@@ -4758,7 +4758,7 @@ function acquireCaptureLease(db, collabId, pid, options = {}) {
4758
4758
  acquired_at = excluded.acquired_at`).run(LEASE_ID, collabId, pid, acquiredAt);
4759
4759
  return true;
4760
4760
  });
4761
- return tx();
4761
+ return tx.immediate();
4762
4762
  }
4763
4763
  function releaseCaptureLease(db, collabId) {
4764
4764
  const tx = db.transaction(() => {
@@ -10183,12 +10183,16 @@ async function captureHandbackText(input) {
10183
10183
  let acquired = false;
10184
10184
  const deadline = Date.now() + acquireMaxWaitMs;
10185
10185
  for (; ; ) {
10186
- acquired = acquireCaptureLease(
10187
- input.db,
10188
- input.collabId,
10189
- input.pid,
10190
- input.leaseOptions
10191
- );
10186
+ try {
10187
+ acquired = acquireCaptureLease(
10188
+ input.db,
10189
+ input.collabId,
10190
+ input.pid,
10191
+ input.leaseOptions
10192
+ );
10193
+ } catch {
10194
+ acquired = false;
10195
+ }
10192
10196
  if (acquired) break;
10193
10197
  if (Date.now() >= deadline) break;
10194
10198
  await sleep3(acquireBackoffMs);
@@ -10265,22 +10269,56 @@ function makeChangeCountReader(deps) {
10265
10269
  }
10266
10270
 
10267
10271
  // src/runtime/provider-submit-strategy.ts
10272
+ var PASTE_START = "\x1B[200~";
10273
+ var PASTE_END = "\x1B[201~";
10268
10274
  async function submitInjectedProviderInput(input) {
10269
10275
  const sleep3 = input.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms)));
10270
- if (input.target === "codex") {
10271
- for (const char of input.text) {
10272
- input.writeUserInput(char);
10273
- await sleep3(5);
10274
- }
10276
+ if (input.target === "claude") {
10277
+ input.writeUserInput(input.text);
10278
+ await sleep3(75);
10279
+ input.writeUserInput("\r");
10280
+ return;
10281
+ }
10282
+ const strategy = input.strategyOverride ?? (input.bracketedPasteEnabled ? "bracketed" : "keystream");
10283
+ if (strategy === "bracketed") {
10284
+ const safe = input.text.split(PASTE_END).join("");
10285
+ input.writeUserInput(PASTE_START + safe + PASTE_END);
10275
10286
  await sleep3(100);
10276
10287
  input.writeUserInput("\r");
10277
10288
  return;
10278
10289
  }
10279
- input.writeUserInput(input.text);
10280
- await sleep3(75);
10290
+ if (strategy === "chunk") {
10291
+ input.writeUserInput(input.text);
10292
+ await sleep3(75);
10293
+ input.writeUserInput("\r");
10294
+ return;
10295
+ }
10296
+ for (const char of input.text) {
10297
+ input.writeUserInput(char);
10298
+ await sleep3(5);
10299
+ }
10300
+ await sleep3(100);
10281
10301
  input.writeUserInput("\r");
10282
10302
  }
10283
10303
 
10304
+ // src/runtime/bracketed-paste-detector.ts
10305
+ var ENABLE = "\x1B[?2004h";
10306
+ var RESET2 = "\x1B[?2004l";
10307
+ function createBracketedPasteDetector() {
10308
+ let enabled = false;
10309
+ return {
10310
+ observe(data) {
10311
+ const hi = data.lastIndexOf(ENABLE);
10312
+ const lo = data.lastIndexOf(RESET2);
10313
+ if (hi > lo) enabled = true;
10314
+ else if (lo > hi) enabled = false;
10315
+ },
10316
+ get enabled() {
10317
+ return enabled;
10318
+ }
10319
+ };
10320
+ }
10321
+
10284
10322
  // src/runtime/runtime-debug-log.ts
10285
10323
  import { appendFileSync as appendFileSync4 } from "node:fs";
10286
10324
  function toHex2(text) {
@@ -10308,6 +10346,11 @@ function createRuntimeDebugLogger(input) {
10308
10346
  }
10309
10347
 
10310
10348
  // src/runtime/mount-session-main.ts
10349
+ function resolveCodexSubmitStrategyOverride() {
10350
+ const raw = process.env.AI_WHISPER_CODEX_SUBMIT_STRATEGY;
10351
+ if (raw === "bracketed" || raw === "keystream" || raw === "chunk") return raw;
10352
+ return void 0;
10353
+ }
10311
10354
  var readChangeCount = makeChangeCountReader();
10312
10355
  function safeReapSessions(input) {
10313
10356
  const reap = input.reap ?? ((collabId, agentType, keepSessionId) => {
@@ -10412,6 +10455,8 @@ function createMountSessionRuntime(input) {
10412
10455
  let lastActivityAt = Date.now();
10413
10456
  try {
10414
10457
  const turnCapture = createAssistantTurnCapture();
10458
+ const bracketedPaste = createBracketedPasteDetector();
10459
+ const codexStrategyOverride = resolveCodexSubmitStrategyOverride();
10415
10460
  const debugLog = createRuntimeDebugLogger({
10416
10461
  logPath: process.env.AI_WHISPER_DEBUG_INPUT_LOG ?? null,
10417
10462
  sessionId: process.env.AI_WHISPER_SESSION_ID ?? null
@@ -10433,12 +10478,15 @@ function createMountSessionRuntime(input) {
10433
10478
  await submitInjectedProviderInput({
10434
10479
  target: input.target,
10435
10480
  text,
10436
- writeUserInput: (value) => writeInjectedInput("mounted-submit", value)
10481
+ writeUserInput: (value) => writeInjectedInput("mounted-submit", value),
10482
+ bracketedPasteEnabled: bracketedPaste.enabled,
10483
+ strategyOverride: codexStrategyOverride
10437
10484
  });
10438
10485
  };
10439
10486
  interactiveSession.onProviderOutput?.((data) => {
10440
10487
  lastActivityAt = Date.now();
10441
10488
  turnCapture.recordProviderOutput(data);
10489
+ bracketedPaste.observe(data);
10442
10490
  });
10443
10491
  const onRelay = (directive, sendNow) => {
10444
10492
  if (!resolvedClaim) {
@@ -10563,14 +10611,6 @@ function createMountSessionRuntime(input) {
10563
10611
  pid: process.pid,
10564
10612
  turnText,
10565
10613
  readChangeCount,
10566
- // TEMP 2026-05-29: bump lease poll-acquire from default 4s to 30s
10567
- // to absorb concurrent-collab contention while we land the proper
10568
- // fix (per-provider capture strategies, design doc Phase 2). The
10569
- // auto-handback already waits ≥30s grace + however long the
10570
- // provider takes to idle, so an extra 0–30s of lease wait is
10571
- // invisible. Revert once mount restart / per-provider strategy
10572
- // removes the host-global single-lease bottleneck.
10573
- acquireMaxWaitMs: 3e4,
10574
10614
  runCapture: () => captureClipboardHandback({
10575
10615
  triggerCopy: () => submitInjectedInput2("/copy"),
10576
10616
  // Some provider versions show a picker after /copy (e.g. Claude
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-whisper",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Terminal-first relay for paired AI coding agents (Claude + Codex), driven by structured workflows.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -47,9 +47,9 @@
47
47
  "ink-testing-library": "^4.0.0",
48
48
  "@ai-whisper/adapter-claude": "0.0.0",
49
49
  "@ai-whisper/adapter-codex": "0.0.0",
50
- "@ai-whisper/companion-core": "0.0.0",
50
+ "@ai-whisper/broker": "0.0.0",
51
51
  "@ai-whisper/shared": "0.0.0",
52
- "@ai-whisper/broker": "0.0.0"
52
+ "@ai-whisper/companion-core": "0.0.0"
53
53
  },
54
54
  "files": [
55
55
  "dist",