Skip to content

feat(lessons): multi-step exercises checked on the terminal state - #403

Merged
thierryvm merged 1 commit into
mainfrom
feature/multi-step-exercises
Sep 29, 2026
Merged

thierryvm merged 1 commit into
mainfrom
feature/multi-step-exercises

Conversation

@thierryvm

@thierryvm thierryvm commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Why

Until now an exercise only saw the text the learner typed, never what the terminal did with it. Two consequences:

  • the conflict lesson validated on git merge, then jumped to the next lesson 2.5 s later: the learner saw CONFLICT and never resolved it, which is the whole point of the lesson;
  • a command that failed could still validate (cat .env outside the project printed an error and completed the exercise).

What changes

  • Multi-step exercises (src/app/data/exerciseSteps.ts). Exercise is now either one command (validate) or steps, each with a check on the terminal state after the command ({command, env, state, prevState, lines}), an optional warn for a known mistake, and an exercise-level restart. progressExercise is pure and shared by LessonPage and the tests. A command can complete several steps when their results are already there, never skip one whose result is missing.
  • One-command exercises go through the same engine as a single step, and now also require that the command printed no error line.
  • Conflicts lesson: 5 steps — git merge feature/nouvelle-feature → cat index.html (Windows Get-Content) → git checkout --theirs index.html → git add index.html → git commit --no-edit. git add with the markers still in prints advice (git checkout feature/nouvelle-feature -- index.html); git merge --abort restarts at step 1; a merge commit that recorded the markers never completes.
  • dotenv / scripts: 2 steps (cd projets, then the command). Windows now teaches bash script.sh (PowerShell does not run a bash script itself).
  • LessonPage: auto-advance removed. Success shows in the terminal (the only visible pane on mobile) and in a role="status" panel with a « Suivant » CTA; the nav « Suivant » is filled once done. Steps are listed with their state (sr-only labels). Progress belongs to one terminal session: « Réinitialiser » and every environment change start over (a session counter, so Linux → Windows → Linux cannot bring stale steps back). An exercise already completed can be redone without recording it twice.
  • TerminalEmulator: onCommand(command, state, {lines, prevState}) may return feedback lines, printed after the command's output in their own colour.
  • validateConflicts removed (the conflict steps read the git state). scripts/export-curriculum.ts reports steps exercises.

Verification

  • Real Git 2.56 in a throwaway repository for every output and claim of the conflict exercise, including Updated 0 paths from the index for checkout --theirs after a premature git add. terminal-fidelity-auditor: 12 MATCH, 1 COSMETIC (git log decoration on a TTY), 0 wrong.
  • Tests: exerciseSteps.test.ts (engine, conflict walk-through, warn, abort, markers committed, Windows) and lessonPageExercise.test.tsx (no auto-advance, Suivant, failed command, steps, Réinitialiser, env round-trip, replay) — both shown red against the previous LessonPage. lessonFidelity replays every solution through progressExercise; the garbage-input tests now assert no exercise advances.
  • type-check, lint, full suite 2944 passed, build. Ratchets unchanged (148 / 34 / 0).
  • Gates: curriculum-validator (0 critical), test-runner, ui-auditor (0 critical, 3 warnings fixed), feature-dev:code-reviewer (1 important fixed: stale steps after an env round-trip; 2 minor fixed).
  • Local browser run, desktop and 390 px: the five steps, the warning, the chained steps, success, no navigation after 4 s, Suivant visible, no horizontal overflow, no console error.

Known, out of scope: the Windows engine still runs .\script.sh as bash (real PowerShell hands it to the file association) — planned with the Windows fidelity work.

🤖 Generated with Claude Code

Résumé par Sourcery

Valider les exercices par rapport à l’état final du terminal et guider les apprenants tout au long de leur réalisation en plusieurs étapes, sans navigation automatique.

Nouvelles fonctionnalités :

  • Ajouter des exercices en plusieurs étapes pilotés par l’état final, notamment la résolution de conflits Git de bout en bout ainsi que des exercices dotenv/script progressifs dans différents environnements.
  • Afficher la progression des étapes, les avertissements contextuels, les retours du terminal et une navigation explicite en cas de réussite dans l’interface de la leçon.
  • Enseigner bash script.sh pour les exercices de scripts Windows.

Corrections de bugs :

  • Empêcher les commandes échouées de terminer les exercices en exigeant une sortie de commande sans erreur.
  • Empêcher la progression obsolète des exercices de subsister après la réinitialisation du terminal ou un changement d’environnement.
  • Empêcher les exercices de résolution de conflits de se terminer lorsque les marqueurs de conflit sont validés.

Améliorations :

  • Unifier la progression des exercices à une commande et en plusieurs étapes grâce à un moteur partagé et pur.
  • Remplacer la navigation automatique des leçons par une action explicite « Suivant » et permettre de rejouer les exercices terminés.
  • Mettre à jour les exports du programme, les vérifications de fidélité et la couverture des commandes de la page d’accueil pour les exercices basés sur des étapes.

Documentation :

  • Documenter le nouveau comportement des exercices en plusieurs étapes, la validation de l’état du terminal, la progression manuelle et les instructions relatives aux scripts Windows dans le journal des modifications, la story et la feuille de route.

Tests :

  • Ajouter une couverture pour la progression des exercices, la résolution des conflits et les scénarios de récupération, les commandes échouées, le comportement sous Windows, les retours du terminal, les interactions avec l’interface des leçons, les réinitialisations de session, les allers-retours entre environnements et la relecture.

Tâches :

  • Supprimer le validateur obsolète des commandes de conflit au profit de vérifications de l’état du terminal.
Original summary in English

Summary by Sourcery

Validate exercises against the terminal state and guide learners through multi-step completion without automatic navigation.

New Features:

  • Add terminal-state-driven multi-step exercises, including end-to-end Git conflict resolution and staged dotenv/script exercises across environments.
  • Display step progress, contextual warnings, terminal feedback, and explicit success navigation in the lesson interface.
  • Teach bash script.sh for Windows script exercises.

Bug Fixes:

  • Prevent failed commands from completing exercises by requiring error-free command output.
  • Prevent stale exercise progress from surviving terminal resets or environment changes.
  • Prevent conflict exercises from completing when conflict markers are committed.

Enhancements:

  • Unify one-command and multi-step exercise progression through a shared pure engine.
  • Replace automatic lesson navigation with an explicit « Suivant » action and support replaying completed exercises.
  • Update curriculum exports, fidelity checks, and landing-page command coverage for step-based exercises.

Documentation:

  • Document the new multi-step exercise behavior, terminal-state validation, manual progression, and Windows script guidance in the changelog, story, and roadmap.

Tests:

  • Add coverage for exercise progression, conflict resolution and recovery paths, failed commands, Windows behavior, terminal feedback, lesson UI interactions, session resets, environment round-trips, and replay.

Chores:

  • Remove the obsolete conflict command validator in favor of terminal-state checks.

An exercise can now have steps, each checked on the terminal state after
the command (a merge in progress, a file without conflict markers, a
merge commit), not on the text typed. A pure engine, progressExercise,
is shared by LessonPage and the tests, which replay every solution the
way a learner types it. One-command exercises are a single step, and a
command that printed an error no longer validates.

- Conflicts lesson: five steps, from git merge to git commit --no-edit,
  with advice for git add while the markers are still in, and a restart
  after git merge --abort. Every output checked against Git 2.56.
- dotenv and scripts lessons: two steps (cd projets, then the command).
  Windows now teaches bash script.sh.
- LessonPage: no more auto-advance after 2.5 s. The success shows in the
  panel and in the terminal, and « Suivant » waits for the learner.
  Progress belongs to one terminal session (Réinitialiser, env change).
- TerminalEmulator: onCommand gets the output and the previous state,
  and may return feedback lines printed after the command output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 29, 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 29, 2026 9:59pm 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 3 days and 21 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Guide du réviseur

Cette PR introduit un moteur partagé d’exercices basé sur l’état final du terminal pour les leçons à commande unique et les leçons en plusieurs étapes, migre les leçons clés — en particulier la résolution des conflits Git — vers une progression basée sur l’état avec rejet des erreurs et conseils de récupération, et met à jour le terminal/l’interface utilisateur afin de préserver la progression par session tout en remplaçant l’avance automatique par une navigation explicite et accessible.

Diagramme de séquence pour la validation des commandes du terminal

sequenceDiagram
    participant Learner
    participant TerminalEmulator
    participant TerminalEngine
    participant ExerciseEngine as progressExercise
    participant LessonPage

    Learner->>TerminalEmulator: Enter command
    TerminalEmulator->>TerminalEngine: Execute command
    TerminalEngine-->>TerminalEmulator: newState, lines
    TerminalEmulator->>ExerciseEngine: progressExercise(exercise, step, command, state, prevState, lines)
    ExerciseEngine-->>TerminalEmulator: StepProgress and feedback
    TerminalEmulator-->>Learner: Output and feedback lines
    ExerciseEngine-->>LessonPage: Updated step or completed state
    LessonPage-->>Learner: Step status or Suivant CTA
Loading

Diagramme de flux de la progression d’un exercice basé sur l’état du terminal

flowchart TD
    A[Command entered] --> B[TerminalEmulator executes command]
    B --> C[progressExercise receives state, prevState, lines]
    C --> D{Current step check passes?}
    D -- No --> E{Known mistake?}
    E -- Yes --> F[Print warning feedback]
    E -- No --> G[Keep current step]
    D -- Yes --> H[Advance one or more completed steps]
    H --> I{All steps complete?}
    I -- No --> J[Print next-step feedback]
    I -- Yes --> K[Mark lesson complete and show Suivant]
Loading

Diagramme de flux de l’exercice de résolution des conflits Git

flowchart TD
    A[git merge feature/nouvelle-feature] --> B{Merge conflict present?}
    B -- Yes --> C[Read index.html]
    C --> D{Conflict markers removed?}
    D -- No --> E[git checkout --theirs index.html]
    E --> D
    D -- Yes --> F[git add index.html]
    F --> G{Index has no conflict markers?}
    G -- No --> H[Print repair guidance]
    H --> E
    G -- Yes --> I[git commit --no-edit]
    I --> J{Merge commit has two parents and no markers?}
    J -- Yes --> K[Exercise complete]
    J -- No --> L[Do not complete]
    B -- No --> M[Remain on merge step]
    C --> N[git merge --abort]
    N --> O[Restart at step 1]
Loading

Modifications au niveau des fichiers

Modification Détails Fichiers
Remplacer la validation basée sur le texte des commandes par une progression des exercices pilotée par l’état du terminal.
  • Introduire des modèles typés pour les exercices à une commande et en plusieurs étapes, avec des vérifications, des avertissements et une gestion du redémarrage pour chaque étape.
  • Ajouter un moteur de progression partagé et pur qui consomme la sortie des commandes ainsi que l’état du terminal avant/après, rejette les commandes produisant des erreurs et peut faire avancer les étapes déjà satisfaites sans ignorer les résultats manquants.
  • Migrer les exercices dotenv, scripts et de résolution des conflits de fusion ; modéliser la leçon sur les conflits comme un workflow Git en cinq étapes et supprimer son validateur dédié.
  • Mettre à jour l’export du programme ainsi que les tests de fidélité et de couverture afin de rejouer les exercices via le moteur partagé.
src/app/data/curriculum.ts
src/app/data/exerciseSteps.ts
src/app/data/validators.ts
scripts/export-curriculum.ts
src/test/curriculumEnvAwareness.test.ts
src/test/exerciseSteps.test.ts
src/test/lessonFidelity.test.ts
src/test/landingTotals.test.ts
src/test/lessonSolutions.ts
src/test/validators.test.ts
Intégrer la progression des exercices au terminal et à l’interface des leçons sans navigation automatique.
  • Transmettre la sortie des commandes et l’état précédent du terminal aux callbacks de LessonPage, puis afficher les retours renvoyés après la sortie des commandes en conservant les couleurs.
  • Suivre la progression pour chaque session de terminal, avec une réinitialisation lors de la réinitialisation du terminal ou des changements d’environnement, y compris les allers-retours entre environnements.
  • Afficher l’état de l’étape, les indices, les retours de réussite, les messages d’état accessibles ainsi qu’une action explicite Suivant/Tableau de bord ; permettre de rejouer les exercices terminés sans créer d’enregistrements de réussite en double.
  • Supprimer l’avance automatique différée et mettre l’accent sur la navigation après la fin de l’exercice.
src/app/components/LessonPage.tsx
src/app/components/TerminalEmulator.tsx
src/test/lessonPageExercise.test.tsx
src/test/terminalEmulatorInitialState.test.tsx
Aligner la documentation destinée aux apprenants et la feuille de route sur le nouveau comportement des exercices.
  • Documenter la résolution des conflits de bout en bout, la validation des résultats du terminal, les avertissements, la navigation manuelle et les conseils concernant les scripts bash sous Windows.
  • Mettre à jour le contenu de la feuille de route et de la page d’accueil afin d’identifier les exercices en plusieurs étapes vérifiés par l’état du terminal ainsi que la leçon sur les conflits.
CHANGELOG.md
STORY.md
docs/ROADMAP.md
docs/plan.md
src/app/data/landingContent.ts

Conseils et commandes

Interagir 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. Particulièrement utile si vous souhaitez recommencer 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 les 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 introduces a shared terminal-state exercise engine for both single-command and multi-step lessons, migrates key lessons—especially Git conflict resolution—to state-based progression with error rejection and recovery guidance, and updates the terminal/UI to preserve progress per session while replacing auto-advance with accessible, explicit navigation.

Sequence diagram for terminal command validation

sequenceDiagram
    participant Learner
    participant TerminalEmulator
    participant TerminalEngine
    participant ExerciseEngine as progressExercise
    participant LessonPage

    Learner->>TerminalEmulator: Enter command
    TerminalEmulator->>TerminalEngine: Execute command
    TerminalEngine-->>TerminalEmulator: newState, lines
    TerminalEmulator->>ExerciseEngine: progressExercise(exercise, step, command, state, prevState, lines)
    ExerciseEngine-->>TerminalEmulator: StepProgress and feedback
    TerminalEmulator-->>Learner: Output and feedback lines
    ExerciseEngine-->>LessonPage: Updated step or completed state
    LessonPage-->>Learner: Step status or Suivant CTA
Loading

Flow diagram for terminal-state exercise progression

flowchart TD
    A[Command entered] --> B[TerminalEmulator executes command]
    B --> C[progressExercise receives state, prevState, lines]
    C --> D{Current step check passes?}
    D -- No --> E{Known mistake?}
    E -- Yes --> F[Print warning feedback]
    E -- No --> G[Keep current step]
    D -- Yes --> H[Advance one or more completed steps]
    H --> I{All steps complete?}
    I -- No --> J[Print next-step feedback]
    I -- Yes --> K[Mark lesson complete and show Suivant]
Loading

Flow diagram for Git conflict resolution exercise

flowchart TD
    A[git merge feature/nouvelle-feature] --> B{Merge conflict present?}
    B -- Yes --> C[Read index.html]
    C --> D{Conflict markers removed?}
    D -- No --> E[git checkout --theirs index.html]
    E --> D
    D -- Yes --> F[git add index.html]
    F --> G{Index has no conflict markers?}
    G -- No --> H[Print repair guidance]
    H --> E
    G -- Yes --> I[git commit --no-edit]
    I --> J{Merge commit has two parents and no markers?}
    J -- Yes --> K[Exercise complete]
    J -- No --> L[Do not complete]
    B -- No --> M[Remain on merge step]
    C --> N[git merge --abort]
    N --> O[Restart at step 1]
Loading

File-Level Changes

Change Details Files
Replace command-text validation with terminal-state-driven exercise progression.
  • Introduce typed one-command and multi-step exercise models with per-step checks, warnings, and restart handling.
  • Add a pure shared progression engine that consumes command output plus before/after terminal state, rejects error-producing commands, and can advance already-satisfied steps without skipping missing results.
  • Migrate dotenv, scripts, and merge-conflict exercises; model the conflict lesson as a five-step Git workflow and remove its dedicated validator.
  • Update curriculum export and fidelity/coverage tests to replay exercises through the shared engine.
src/app/data/curriculum.ts
src/app/data/exerciseSteps.ts
src/app/data/validators.ts
scripts/export-curriculum.ts
src/test/curriculumEnvAwareness.test.ts
src/test/exerciseSteps.test.ts
src/test/lessonFidelity.test.ts
src/test/landingTotals.test.ts
src/test/lessonSolutions.ts
src/test/validators.test.ts
Integrate exercise progression into the terminal and lesson UI without automatic navigation.
  • Pass command output and previous terminal state to LessonPage callbacks, and render returned feedback after command output with preserved colors.
  • Track progress per terminal session, resetting on terminal reset or environment changes, including environment round trips.
  • Display step status, hints, success feedback, accessible status messaging, and an explicit Suivant/Tableau de bord action; allow completed exercises to be replayed without duplicate completion records.
  • Remove the delayed auto-advance and emphasize navigation after completion.
src/app/components/LessonPage.tsx
src/app/components/TerminalEmulator.tsx
src/test/lessonPageExercise.test.tsx
src/test/terminalEmulatorInitialState.test.tsx
Align learner-facing documentation and roadmap material with the new exercise behavior.
  • Document end-to-end conflict resolution, terminal-result validation, warnings, manual navigation, and the Windows bash-script guidance.
  • Update roadmap and landing copy to identify terminal-state-checked multi-step exercises and the conflict lesson.
CHANGELOG.md
STORY.md
docs/ROADMAP.md
docs/plan.md
src/app/data/landingContent.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

@thierryvm
thierryvm merged commit 1155c86 into main Sep 29, 2026
4 checks passed
@thierryvm
thierryvm deleted the feature/multi-step-exercises branch September 29, 2026 22:03

This branch was successfully deployed

1 active deployment
Preview — 08d768e8 Deployed Sep 29, 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