Commit e210277
authored
fix(call): clear wrapped partial transcripts cleanly in npm run call (#11)
## Describe your changes
Fixes a long-standing display bug in `npm run call` where partial assistant transcripts visibly duplicate themselves in the terminal, leaving stacks of `🤖 Assistant: ...` lines on screen instead of overwriting cleanly.
- **Root cause:** `handleControlMessage` in `src/call.ts` was repainting partials with `\r` + N spaces + `\r`. `\r` only returns the cursor to column 0 of the *current* terminal row, so when a partial wraps to multiple rows (very common for assistant utterances on an 80-col terminal — the example that surfaced this was 110 cells wide), only the bottom row gets cleared. Every wrapped row above stays on screen, and the next partial paints another wrapping block on top.
- **Fix:** Compute the previous partial's row count from `process.stdout.columns` and an estimated display width that treats emoji and CJK glyphs as 2 cells, then walk the cursor up with `readline.moveCursor` / `readline.cursorTo` / `readline.clearLine` to erase every row, not just the bottom one.
- **Apply the same clear** before printing speech-update events, the call-ended message, the WebSocket `onclose` log, and the SIGINT/SIGTERM cleanup banner so they don't print on top of an in-flight partial either.
- **Non-TTY mode:** When `process.stdout.isTTY` is false (piping to `tee`, CI logs, redirecting to a file), `\r` was producing literal carriage returns and concatenated lines. We now skip live partial overwrites entirely in non-TTY contexts and only emit finals — one transcript per line, clean logs.
No new dependencies. Pure refactor of an existing function plus two small helpers (`getDisplayWidth`, `clearWrittenLine`) below `connectWebSocket`.
## Relevant Context (linear ticket, slack link, etc)
Surfaced during a manual simulated call (`npm run call -- <org> -s <squad>`) — every assistant turn was producing 5–10 stacked copies of the same `🤖 Assistant: ... Seller C` partial in the terminal, with long stretches of trailing whitespace between them. The duplication signature (identical content, growing whitespace gaps) traced back to `\r` only clearing one wrapped row instead of all of them.
## API Changes
- **Is this changing the public API?**
- [ ] Yes
- [x] No
- **If yes, is it backward‐compatible?**
- [ ] Yes
- [ ] No
N/A. This repo is an internal gitops CLI; the only user-visible change is that `npm run call` now renders partial transcripts cleanly in TTY and emits one line per final transcript in non-TTY contexts. No flags, no commands, no on-disk schema, no platform requests change.
Non backward-compatible changes might break customers' agents. Please proceed with care and notify the team.
## How did you test this?
**Automated:**
- `npx tsc --noEmit` — clean.
- `npm test` — 33/33 passing (no new tests added; existing suite covers the credential walker, path matching, cleanup safety, CLI arg parsing, and clean-resource regression set).
**Width math sanity check:**
- The exact partial that was duplicating in the reported call (`🤖 Assistant: Understood. Let's pick up right where we left off. The last instruction was: first open Seller C`) has a display width of **110 cells** under the new `getDisplayWidth`, which correctly resolves to **2 rows on an 80-col terminal**, **2 rows at 100 cols**, and **1 row at 120+ cols**. Short partials and `🎤 You: ...` lines correctly resolve to 1 row at all standard widths.
**Manual smoke test flagged for reviewer** (requires real terminal + a configured org with an assistant or squad):
- `npm run call -- <org> -a <name>` (or `-s <squad>`) and have a multi-sentence exchange. Confirm that long assistant partials overwrite in place — no stack of duplicate `🤖 Assistant: ...` lines, no leftover wrapped rows.
- Resize the terminal mid-call to a narrow width (e.g. 50 cols) and continue the conversation; partials should still overwrite cleanly when they wrap to 3+ rows.
- Pipe the output to a file: `npm run call -- <org> -a <name> | tee /tmp/call.log`. Confirm the log contains only finals (one per line), no `\r` artifacts, no duplicated partials.
- Press Ctrl+C while a partial is on screen; confirm `👋 Ending call...` prints cleanly without the partial visible above it.1 file changed
Lines changed: 76 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
435 | 435 | | |
436 | 436 | | |
437 | 437 | | |
438 | | - | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
439 | 441 | | |
440 | 442 | | |
441 | 443 | | |
| |||
508 | 510 | | |
509 | 511 | | |
510 | 512 | | |
511 | | - | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
512 | 516 | | |
513 | 517 | | |
514 | 518 | | |
515 | 519 | | |
516 | 520 | | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
517 | 576 | | |
518 | 577 | | |
519 | 578 | | |
| |||
523 | 582 | | |
524 | 583 | | |
525 | 584 | | |
| 585 | + | |
526 | 586 | | |
527 | 587 | | |
528 | | - | |
529 | | - | |
530 | | - | |
531 | | - | |
532 | | - | |
| 588 | + | |
| 589 | + | |
533 | 590 | | |
534 | | - | |
535 | | - | |
536 | | - | |
537 | | - | |
538 | | - | |
539 | | - | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
540 | 597 | | |
541 | 598 | | |
542 | 599 | | |
| |||
546 | 603 | | |
547 | 604 | | |
548 | 605 | | |
549 | | - | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
550 | 609 | | |
551 | 610 | | |
552 | 611 | | |
| |||
565 | 624 | | |
566 | 625 | | |
567 | 626 | | |
568 | | - | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
569 | 630 | | |
570 | 631 | | |
571 | 632 | | |
| |||
0 commit comments