Skip to content

fix(terminal): print what a real shell prints — pwd, cd -, export, ls, wc, apt (THI-353) - #390

Merged
thierryvm merged 3 commits into
mainfrom
fix/thi-353-theory-engine
Sep 24, 2026
Merged

thierryvm merged 3 commits into
mainfrom
fix/thi-353-theory-engine

Conversation

@thierryvm

@thierryvm thierryvm commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Why

THI-353, theory ↔ terminal (engine side). Replaying every command shown in the lessons (757) against the engine, from each lesson's starting state, showed the terminal printing something else than what a real shell prints — and than what the lesson shows. Expected values here come from real bash / PowerShell (e.g. wc checked with a real wc on the exact file content), never from the engine itself.

What

  • pwd prints the absolute path (/home/user); only the prompt shortens to ~
  • cd - ($OLDPWD): bash prints the directory, PowerShell stays silent
  • export PATH=$PATH:/opt/bin expands its value
  • PowerShell shows a Windows PATH ($env:PATH) — a read-only view, the shared state is never rewritten
  • git init mon-projet creates the directory and the repository in it (it re-initialised the current one)
  • wc counts UTF-8 bytes plus the final newline: notes.txt = 6 22 143, like the real wc (was 6 22 140); an empty file is 0 0 0 (was 1 line)
  • ls: one alphabetical list (C locale), no directories-first, no trailing /; ls -F marks / and *
  • !! history expansion (sudo !!), echoed like bash
  • apt / apt-get (Linux): changing the system without sudo gives the real dpkg lock error; sudo asks for the password once per session; sudo no longer records the inner command twice in the history
  • killall, Start-Process (UAC note for -Verb RunAs), Windows-format ping
  • Linux command names are case-sensitive (LS is not ls); the not-found message repeats the name as typed (was lower-cased)
  • a recursive rm on the root directory hits the GNU failsafe (--no-preserve-root)

Old tests that encoded the wrong behaviour were updated with the reason in the test: pwd → ~, ls → docs/, sudo -i first line.

Evidence

  • Lesson theory replay: +42 examples match, 1 new difference, which is a content issue for the next PR (the Windows PATH lesson shows echo $PATH with a Unix output; real PowerShell needs $env:PATH)
  • Engine tests: 978 pass (new tests written first, seen red)
  • Chrome (local): pwd, ls, ls -a, cd -, wc, apt update → lock error, sudo !!, LS, the root failsafe — all as in bash
  • Case sensitivity, the not-found name and the root failsafe were also flagged by a beginner-pedagogy audit run in parallel (the rest of that audit is content / UI, next PRs)

Refs THI-353

🤖 Generated with Claude Code

Résumé par Sourcery

Fait davantage correspondre le comportement du terminal simulé à la sortie réelle de Bash et PowerShell pour les commandes courantes liées au système de fichiers, à l’environnement, au réseau, à la gestion des paquets et aux privilèges.

Nouvelles fonctionnalités :

  • Ajout du comportement du shell pour l’expansion de l’historique, le changement de répertoire avec cd -, la gestion simulée des paquets, le lancement de processus et la sortie réseau spécifique à chaque plateforme.
  • Prise en charge réaliste de la gestion des privilèges, notamment l’authentification des sessions sudo et les erreurs de permission apt.

Corrections de bugs :

  • Alignement de la sortie du terminal sur Bash et PowerShell pour les chemins, les variables d’environnement, le nombre de fichiers, les listes de répertoires, la sensibilité à la casse des commandes, l’initialisation de Git et les protections contre la suppression destructive de la racine.

Améliorations :

  • Amélioration de l’émulation des commandes multiplateformes et conservation des vues de PATH spécifiques à l’environnement sans réécrire l’état partagé.

Tests :

  • Ajout de tests couvrant la fidélité du shell sous Linux, macOS et Windows, notamment les commandes, les pipelines, les permissions, l’historique et le formatage de la sortie.
Original summary in English

Résumé par Sourcery

Alignez le comportement et la sortie des commandes du terminal sur ceux de Bash et PowerShell réels dans les workflows courants liés au système de fichiers, à l’environnement, au réseau, à la gestion des paquets et aux privilèges.

Nouvelles fonctionnalités :

  • Ajout d’un comportement réaliste pour la gestion des paquets, les privilèges, l’expansion de l’historique, le lancement de processus et les commandes réseau spécifiques aux plateformes.
  • Prise en charge de la navigation vers le répertoire précédent et de l’initialisation de Git ciblant un répertoire.

Corrections de bugs :

  • Alignement de la sortie du shell simulé sur Bash et PowerShell pour les chemins, les variables d’environnement, le nombre de fichiers, les listes de répertoires, la sensibilité à la casse des commandes et les protections contre la suppression destructive de la racine.

Améliorations :

  • Préservation des vues de PATH spécifiques aux plateformes, tout en améliorant l’émulation des commandes multiplateformes et le comportement des sessions sudo.

Tests :

  • Ajout d’une couverture du moteur pour la fidélité du shell sous Linux, macOS et Windows, notamment pour les commandes, les pipelines, les permissions, l’historique et le formatage de la sortie.
Original summary in English

Summary by Sourcery

Align terminal command behavior and output with real Bash and PowerShell across common filesystem, environment, networking, package-management, and privilege workflows.

New Features:

  • Add realistic package-management, privilege, history-expansion, process-launching, and platform-specific network command behavior.
  • Support previous-directory navigation and directory-targeted Git initialization.

Bug Fixes:

  • Align simulated shell output with Bash and PowerShell for paths, environment variables, file counts, directory listings, command case sensitivity, and destructive root removal safeguards.

Enhancements:

  • Preserve platform-specific PATH views while improving cross-platform command emulation and sudo session behavior.

Tests:

  • Add engine coverage for shell fidelity across Linux, macOS, and Windows, including commands, pipelines, permissions, history, and output formatting.

thierryvm and others added 2 commits September 24, 2026 13:54
…, wc, apt (THI-353)

Theory replay of the lessons (757 commands) against the engine: 42 more
examples now match, expected values taken from real bash / PowerShell.

- pwd prints the absolute path (the prompt shortens to ~, pwd never does)
- cd - returns to $OLDPWD (previousCwd), bash prints it, PowerShell silent
- export expands its value (`export PATH=$PATH:/opt/bin`)
- PowerShell shows a Windows PATH ($env:PATH, echo $env:PATH), never
  written back to the shared state
- git init <dir> creates the directory and the repository in it
- wc counts UTF-8 bytes and the final newline (notes.txt: 6 22 143, as the
  real wc); an empty file is 0 0 0
- ls: one alphabetical list (C locale, no directories-first), no trailing /;
  -F marks / and *
- !! history expansion (`sudo !!`), echoed like bash
- apt / apt-get (Linux): changing the system needs sudo, like the real lock
  error; sudo no longer records the inner command twice in the history
- killall, Start-Process (UAC note for -Verb RunAs), Windows-format ping
- Linux command names are case-sensitive (LS is not ls); the not-found
  message repeats the name as typed
- rm -rf / hits the GNU failsafe

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…cache (THI-353)

The sudo lesson shows '[sudo] password for user:'; the simulator never did.
The first sudo of a session now prints it (info line), later ones reuse the
credential, as the real sudo does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@vercel

vercel Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
terminal-learning Ready Ready Preview Sep 24, 2026 12:06pm UTC

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @thierryvm, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 2 days and 6 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 24, 2026

Copy link
Copy Markdown

Guide du réviseur

Cette PR met à jour les gestionnaires de commandes du moteur de terminal, l’état du shell, les vues de l’environnement et le comportement spécifique aux plateformes afin de correspondre aux sorties attendues de Bash, macOS et PowerShell, avec une large couverture de régressions basée sur les résultats de vrais shells.

Diagramme de séquence de l’exécution des commandes du shell et des sorties tenant compte de l’état

sequenceDiagram
    participant User
    participant Engine as TerminalEngine
    participant Shell as CommandDispatcher
    participant State as TerminalState
    participant Handler as CommandHandler

    User->>Engine: processCommand(input, env)
    Engine->>Engine: expandHistoryBang(input, previous)
    Engine->>State: append commandHistory
    Engine->>Shell: runLine(command, env)
    Shell->>Handler: execute command with state and env
    Handler->>State: update cwd, previousCwd, envVars, or sudoAuthenticated
    Handler-->>Shell: OutputLine[] and newState
    Shell-->>Engine: command result
    Engine-->>User: shell-accurate output
Loading

Modifications fichier par fichier

Modification Détails Fichiers
Aligner les sorties du shell et le comportement de l’état sur la sémantique réelle de Bash, des shells macOS et de PowerShell.
  • Rendre pwd absolu, suivre OLDPWD pour cd -, développer les variables dans export et préserver les vues de PATH propres à chaque environnement.
  • Implémenter le tri et le formatage de ls conformes au shell, un wc tenant compte de l’UTF-8 et des nouvelles lignes, la recherche de commandes sensible à la casse sous Linux, l’expansion de l’historique et la protection contre la suppression de la racine.
  • Ajouter un comportement réaliste pour les privilèges et les gestionnaires de paquets, notamment la mise en cache des identifiants sudo, les échecs liés aux verrous dpkg, les opérations apt et la déduplication de l’historique des commandes sudo.
  • Ajouter un comportement spécifique aux plateformes pour le ping Windows, Start-Process et killall sous Linux.
  • Créer et initialiser un répertoire cible pour git init <dir>.
  • Ajouter des tests complets de fidélité et mettre à jour les attentes historiques afin de documenter le comportement corrigé.
src/app/data/commands/env.ts
src/app/data/commands/network.ts
src/app/data/commands/shellVars.ts
src/app/data/commands/types.ts
src/app/data/commands/windows.ts
src/app/data/terminalEngine.ts
src/test/shellLayer.test.ts
src/test/terminalEngine.test.ts

Conseils et commandes

Interaction avec Sourcery

  • Déclencher une nouvelle revue : commentez @sourcery-ai review sur la pull request.
  • Poursuivre les discussions : répondez directement aux commentaires de revue de Sourcery.
  • Générer une issue GitHub à partir d’un commentaire de revue : demandez à Sourcery de créer une issue à partir d’un commentaire de revue en y répondant. Vous pouvez également répondre à un commentaire de revue avec @sourcery-ai issue pour créer une issue à partir de celui-ci.
  • Générer le titre d’une pull request : écrivez @sourcery-ai n’importe où dans le titre de la pull request pour générer un titre à tout moment. Vous pouvez également commenter @sourcery-ai title sur la pull request pour générer ou régénérer le titre à tout moment.
  • Générer le résumé d’une pull request : écrivez @sourcery-ai summary n’importe où dans le corps de la pull request pour générer un résumé de PR à tout moment, exactement à l’endroit souhaité. Vous pouvez également commenter @sourcery-ai summary sur la pull request pour générer ou régénérer le résumé à tout moment.
  • Générer le guide du réviseur : commentez @sourcery-ai guide sur la pull request pour générer ou régénérer le guide du réviseur à tout moment.
  • Résoudre tous les commentaires de Sourcery : commentez @sourcery-ai resolve sur la pull request pour résoudre tous les commentaires de Sourcery. Cette commande est utile si vous avez déjà traité tous les commentaires et ne souhaitez plus les voir.
  • Ignorer toutes les revues de Sourcery : commentez @sourcery-ai dismiss sur la pull request pour ignorer toutes les revues existantes de Sourcery. Cette commande est particulièrement utile si vous souhaitez repartir de zéro avec une nouvelle revue — n’oubliez pas de commenter @sourcery-ai review pour déclencher une nouvelle revue !

Personnaliser votre expérience

Accédez à votre tableau de bord pour :

  • Activer ou désactiver des fonctionnalités de revue telles que le résumé de pull request généré par Sourcery, le guide du réviseur et d’autres fonctionnalités.
  • Modifier la langue de la revue.
  • Ajouter, supprimer ou modifier les instructions de revue personnalisées.
  • Ajuster les autres paramètres de revue.

Obtenir de l’aide

Original review guide in English

Reviewer's Guide

This PR updates the terminal engine’s command handlers, shell state, environment views, and platform-specific behavior to match expected Bash, macOS, and PowerShell output, with broad regression coverage based on real-shell results.

Sequence diagram for shell command execution and state-aware output

sequenceDiagram
    participant User
    participant Engine as TerminalEngine
    participant Shell as CommandDispatcher
    participant State as TerminalState
    participant Handler as CommandHandler

    User->>Engine: processCommand(input, env)
    Engine->>Engine: expandHistoryBang(input, previous)
    Engine->>State: append commandHistory
    Engine->>Shell: runLine(command, env)
    Shell->>Handler: execute command with state and env
    Handler->>State: update cwd, previousCwd, envVars, or sudoAuthenticated
    Handler-->>Shell: OutputLine[] and newState
    Shell-->>Engine: command result
    Engine-->>User: shell-accurate output
Loading

File-Level Changes

Change Details Files
Align shell output and state behavior with real Bash, macOS shells, and PowerShell semantics.
  • Make pwd absolute, track OLDPWD for cd -, expand variables in export, and preserve environment-specific PATH views.
  • Implement shell-accurate ls sorting/formatting, UTF-8/newline-aware wc, case-sensitive Linux command lookup, history expansion, and root-deletion protection.
  • Add realistic privilege and package-manager behavior, including sudo credential caching, dpkg lock failures, apt operations, and deduplicated sudo command history.
  • Add platform-specific command behavior for Windows ping, Start-Process, and Linux killall.
  • Create and initialize a target directory for git init <dir>.
  • Add comprehensive fidelity tests and update legacy expectations to document corrected behavior.
src/app/data/commands/env.ts
src/app/data/commands/network.ts
src/app/data/commands/shellVars.ts
src/app/data/commands/types.ts
src/app/data/commands/windows.ts
src/app/data/terminalEngine.ts
src/test/shellLayer.test.ts
src/test/terminalEngine.test.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

The sudo exercise asks for 'sudo whoami to see that sudo gives you root';
the simulator answered 'user'. whoami now reports root while sudo runs.
Also documents and tests cd - under PowerShell: Set-Location - exists since
PowerShell 6.2 (the simulated shell is 7.x), silent like the real one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@thierryvm

Copy link
Copy Markdown
Owner Author

Review follow-up (82bd528) — feature-dev:code-reviewer returned FIX FIRST with 2 findings:

  1. sudo whoami answered user — valid, and it contradicted the sudo exercise itself ("pour voir que sudo vous donne les droits root"). Fixed: whoami reports root while sudo runs; test added (seen red first).
  2. "cd - does not exist in PowerShell" — not taken: true for Windows PowerShell 5.1, but PowerShell 6.2 added Set-Location - / Set-Location + (location history), and the simulated shell is 7.x (it already accepts &&, 7.0+). Behaviour kept (silent, like the real one); the code comment now says so, and a Windows test was added.

Final checks on 82bd528: CI green; browser census on the preview 198/198; lesson theory replay +43 examples matching (the single new difference is the Windows PATH lesson showing bash — content PR); Chrome (local): whoami → user, first sudo whoami → password prompt then root, second → root.

@thierryvm
thierryvm merged commit e75bc56 into main Sep 24, 2026
4 checks passed
@thierryvm
thierryvm deleted the fix/thi-353-theory-engine branch September 24, 2026 12:12
thierryvm added a commit that referenced this pull request Sep 24, 2026
…manent replay (THI-353) (#391)

- Replay every terminal session shown in a lesson code block through the
  engine, from the lesson's starting state, in each environment
  (src/test/lessonTheory.test.ts). Known gaps are a shrink-only ratchet
  (lessonTheoryGaps.ts, 174 entries), plus a ceiling on lessons that show
  bash to Windows learners (39).
- Fix 13 lesson examples whose output did not match (ls -l, ls -a,
  grep -n, wc, chmod, chown, apt, stderr, Windows ping) and give the PATH
  and git init lessons a single block per environment.
- ls -l size comes from the content bytes, like wc -c.
- $env:X = "..." expands $env:Y inside double quotes (PowerShell).
- git init prints C:/Users/user/... on Windows, like Git for Windows.
- CHANGELOG and STORY: catch up #389 and #390, add this change.

Co-authored-by: Claude Opus 5.5 <[email protected]>

This branch was successfully deployed

1 active deployment
Preview — 82bd5284 Deployed Sep 24, 2026 by vercel[bot]
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