squadrant 0.13.3 → 0.13.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.
package/dist/index.js CHANGED
@@ -2926,7 +2926,7 @@ function hasCCInputBox(screen) {
2926
2926
  return false;
2927
2927
  return lines.slice(topHR + 1, bottomHR).some((l) => /[>❯]/.test(l));
2928
2928
  }
2929
- function readInputBoxRaw(screen) {
2929
+ function readInputBoxRaw(screen, opts) {
2930
2930
  if (!screen)
2931
2931
  return null;
2932
2932
  const lines = screen.split(/\r?\n/);
@@ -2952,7 +2952,8 @@ function readInputBoxRaw(screen) {
2952
2952
  s = s.replace(/\s*[▌█▔▎▏]+\s*$/, "");
2953
2953
  parts.push(s);
2954
2954
  }
2955
- return parts.join("").replace(/\s+$/, "");
2955
+ const joined = parts.join("");
2956
+ return opts?.trim === false ? joined : joined.replace(/\s+$/, "");
2956
2957
  }
2957
2958
  function classifyStartupSurface(screen) {
2958
2959
  if (CC_WORKING_RE.test(screen))
@@ -2973,6 +2974,19 @@ function classifySendOutcome(payload, postBox) {
2973
2974
  return "stuck";
2974
2975
  return "unknown";
2975
2976
  }
2977
+ function classifyDraftLiveness(before, after) {
2978
+ if (before === null || after === null)
2979
+ return "inconclusive";
2980
+ if (after === "")
2981
+ return "no-draft";
2982
+ if (before.length > 0) {
2983
+ const segs = [...new Intl.Segmenter().segment(before)];
2984
+ const expected = segs.slice(0, -1).map((s) => s.segment).join("").replace(/\s+$/, "");
2985
+ if (after === expected)
2986
+ return "real-draft";
2987
+ }
2988
+ return "inconclusive";
2989
+ }
2976
2990
  function createCmuxDriver() {
2977
2991
  return {
2978
2992
  name: "cmux",
@@ -3170,18 +3184,38 @@ function createCmuxDriver() {
3170
3184
  if (!opts?.probe)
3171
3185
  throw new DeferDelivery(draft);
3172
3186
  const before = readInputBoxRaw(screen);
3187
+ const rawBefore = readInputBoxRaw(screen, { trim: false });
3173
3188
  await cmux(["send-key", "--workspace", ws, "--surface", sf, "backspace"]);
3189
+ await new Promise((r) => setTimeout(r, 50));
3174
3190
  let afterScreen = "";
3175
3191
  try {
3176
3192
  afterScreen = await cmux(["read-screen", "--workspace", ws, "--surface", sf]);
3177
3193
  } catch {
3178
3194
  }
3179
3195
  const after = readInputBoxRaw(afterScreen);
3180
- if (before !== null && after !== null && after.length > 0 && after === before.slice(0, -1)) {
3181
- await cmux(["send", "--workspace", ws, "--surface", sf, before.slice(-1)]);
3196
+ const rawAfter = readInputBoxRaw(afterScreen, { trim: false });
3197
+ const liveness = classifyDraftLiveness(before, after);
3198
+ if (liveness === "real-draft") {
3199
+ const segs = before ? [...new Intl.Segmenter().segment(before)] : [];
3200
+ const lastGrapheme = segs.length > 0 ? segs[segs.length - 1].segment : before.slice(-1);
3201
+ await cmux(["send", "--workspace", ws, "--surface", sf, lastGrapheme]);
3182
3202
  throw new DeferDelivery(draft);
3183
3203
  }
3184
- await deliver();
3204
+ if (liveness === "no-draft") {
3205
+ await deliver();
3206
+ return;
3207
+ }
3208
+ if (rawBefore !== null && rawAfter !== null) {
3209
+ if (rawBefore !== rawAfter) {
3210
+ const segs = [...new Intl.Segmenter().segment(rawBefore)];
3211
+ const lastGrapheme = segs.length > 0 ? segs[segs.length - 1].segment : rawBefore.slice(-1);
3212
+ await cmux(["send", "--workspace", ws, "--surface", sf, lastGrapheme]);
3213
+ throw new DeferDelivery(draft);
3214
+ }
3215
+ await deliver();
3216
+ return;
3217
+ }
3218
+ throw new DeferDelivery(draft);
3185
3219
  },
3186
3220
  async listSurfaces(workspaceId) {
3187
3221
  let output;
@@ -4079,8 +4113,8 @@ async function sendFirstTurnWhenReady(runtime, pane, task, preLaunchScreen, acce
4079
4113
  let stable = false;
4080
4114
  for (let i = 0; i < maxPolls && !stable; i++) {
4081
4115
  const screen = await runtime.readPaneScreen(pane) ?? "";
4082
- const hasInputBox = !!acceptanceConfig?.splashMarker || hasCCInputBox(screen);
4083
- if (screen.length > 0 && screen === previousScreen && screen !== preLaunchScreen && hasInputBox) {
4116
+ const ready = acceptanceConfig?.splashMarker ? true : hasCCInputBox(screen) && classifyStartupSurface(screen) === "idle";
4117
+ if (screen.length > 0 && screen === previousScreen && screen !== preLaunchScreen && ready) {
4084
4118
  stable = true;
4085
4119
  } else {
4086
4120
  previousScreen = screen;
@@ -4143,7 +4177,7 @@ var init_crew_pane = __esm({
4143
4177
  init_dist2();
4144
4178
  SEND_FIRST_TURN_FLOOR_MS = 1500;
4145
4179
  POLL_INTERVAL_MS = 750;
4146
- SEND_FIRST_TURN_TIMEOUT_MS = 2e4;
4180
+ SEND_FIRST_TURN_TIMEOUT_MS = 9e4;
4147
4181
  POST_SEND_CHECK_MS = 750;
4148
4182
  SPLASH_MAX_CHECKS = 20;
4149
4183
  SPLASH_RESEND_EVERY_N = 4;