Skip to content

Ignore terminal echo before the command line in typescripts - #245

Merged
rongxin-liu merged 1 commit into
help50from
help50-typescript
Sep 21, 2026
Merged

rongxin-liu merged 1 commit into
help50from
help50-typescript

Conversation

@rongxin-liu

Copy link
Copy Markdown
Contributor

Found while testing the codespace integration (cs50/codespace#196).

Problem. script records everything on the pty, including readline's tab-completion listing and the redrawn prompt, history recall, and Ctrl-R. _help50 treated only the first line of the typescript as the command line, so after grep zzz ind<Tab><Tab>oor.py (a command with no output), the leftover index.html indoor.py plus the redrawn prompt were passed to _helpless as the command's output. In plain cli this is invisible because the default _helpless is silent; in the codespace it showed a help50 button whose message was that junk.

Fix. Drop everything through the first line that ends with the executed command as recorded by history, joining backslash continuations (and stripping their PS2 prompts) along the way. Only what follows is treated as output. If no such line is found, fall back to dropping the first logical line, as before.

Testing. Drove an interactive login shell under a pty with a fake _helpless that logs its argument:

  • tab-completed grep zzz indoor.py (no match): _helpless no longer called
  • history recall via up-arrow of a quiet command: not called
  • cat \ + nothere2: payload is cat: nothere2: No such file or directory, no > prompt
  • 1s, make hello.c, python baz.py: helpers unchanged
  • make smoke passes

script records everything on the pty, including tab-completion listings,
history recall, and redrawn prompts. _help50 dropped only the first line as
the command, so after tab-completing a command with no output, the leftover
echo was treated as its output and passed to _helpless. Now drop everything
through the first line that ends with the command as recorded in history,
joining backslash continuations and their PS2 prompts; fall back to dropping
the first logical line if the command isn't found.
@rongxin-liu rongxin-liu self-assigned this Sep 21, 2026
@rongxin-liu
rongxin-liu merged commit 400e6c1 into help50 Sep 21, 2026
3 checks passed
@rongxin-liu
rongxin-liu deleted the help50-typescript branch September 21, 2026 05:12
This was referenced Sep 30, 2026
rongxin-liu added a commit that referenced this pull request Sep 30, 2026
Reimplements help50 in Bash, running locally and automatically per login
shell, without a server. Usage is inspired by systemctl:

- help50 start/stop/status/enable/disable/is-enabled control a session
  that logs the shell's I/O via script to /tmp/help50.$PPID
- help50 COMMAND [ARGS...] runs COMMAND as though typed directly, with
  the same exit status
- HELP50_DISABLED in the environment is a kill switch, so that as a
  Codespaces secret help50 can be turned off fleet-wide without a rebuild

/etc/profile.d/help50.sh installs a PROMPT_COMMAND hook that, after a
failed command, strips the typescript of ANSI/control characters and
terminal echo, bounds the read (first 64K + last 1M) and the output
(first 64 + last 1,024 lines), and passes it to each executable helper in
/opt/cs50/lib/help50/ under a 5-second timeout. Helper output is shown via
_helpful; otherwise _helpless receives the output and command line (a
no-op here, overridden in cs50/codespace to relay to the CS50 Duck).

Also adds /opt/cs50/lib/cli helper functions (_alert, _ansi, _find,
_fold, _sure) used by the make, sqlite3, http-server, and valgrind
wrappers; helpers for bash, cd, clang, make, and python; tests/smoke.sh
(make smoke), run in CI against each architecture's build before pushing
to Docker Hub; and installs bsdextrautils, colorized-logs, file, expect,
and fzf, dropping the Python help50 package.

Squashed from 99 commits, including #244, #245, #246, #247, and #248.

Co-authored-by: Rongxin Liu <10591665+rongxin-liu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant