From 35a2c79aba82feba3e9151ef88a8a8723f114baf Mon Sep 17 00:00:00 2001 From: Rongxin Liu <10591665+rongxin-liu@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:57:46 -0400 Subject: [PATCH 1/2] send the command line along with the output to the duck cs50/cli#246 passes the failed command's line to _helpless as a second argument. Include it, as a transcript ($ cmd, then output), so cs50.ai can see what the student ran, not just what came back. --- etc/profile.d/codespace.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/etc/profile.d/codespace.sh b/etc/profile.d/codespace.sh index 5f15a6c8..e55cc267 100644 --- a/etc/profile.d/codespace.sh +++ b/etc/profile.d/codespace.sh @@ -118,13 +118,18 @@ if [ `id -u` -ne 0 ]; then # No helper matched: offer the duck the failed command's output to explain. # If there's no output (e.g., grep with no match, or a program exiting 1), there's # nothing to explain, and any button still showing is about an earlier command. + # $1 is the output, $2 the command line; the duck gets both, as a transcript. _helpless() { if [[ -z "${1//[[:space:]]/}" ]]; then _help50_hide return fi _alert "$(_ansi "🦆 Click \`help50\` above for help with that error.")" - _help50_button ask "$1" + if [[ -n "$2" ]]; then + _help50_button ask "$ $2"$'\n'"$1" + else + _help50_button ask "$1" + fi } # Command succeeded: hide the button, if showing From 19e614b76fd17fea28fcc9202ccba7a447337aff Mon Sep 17 00:00:00 2001 From: Rongxin Liu <10591665+rongxin-liu@users.noreply.github.com> Date: Tue, 22 Sep 2026 01:14:28 -0400 Subject: [PATCH 2/2] smoke-test the transcript _helpless sends to the duck _help50_button hands the payload to command50 with output discarded, so no check could see it. Stub it and assert both forms: with a command line, "$ cmd" then the output; without one, the output alone. Whitespace-only output still hides the button even when a command line is supplied. --- tests/smoke.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/smoke.sh b/tests/smoke.sh index 2eb27291..cafbb5fd 100755 --- a/tests/smoke.sh +++ b/tests/smoke.sh @@ -38,6 +38,15 @@ if run "$IMAGE" bash --login -c 'test -f /etc/profile.d/help50.sh -a -f /opt/cs5 test -z "$(_helpless " " 2>&1)" && _helpless "cat: x: No such file" 2>&1 | grep -q help50' + # _help50_button discards command50's output, so stub it to see the payload + check "the duck gets the command line and output as a transcript (or output alone without a command)" + run "$IMAGE" bash --login -c ' + _alert() { :; } + _help50_button() { printf "%s" "$2"; } + test "$(_helpless "cat: x: No such file" "cat x")" = "$(printf "%s\n%s" "$ cat x" "cat: x: No such file")" && + test "$(_helpless "cat: x: No such file")" = "cat: x: No such file" && + test -z "$(_helpless " " "cat x")"' + check "root shells (Sysadmins profile) do not start help50" run --user root "$IMAGE" bash --login -c 'test -z "${HELP50:-}" && ! declare -F _helpful > /dev/null' else