Skip to main content

Consumer CLI for the learnctl catalog — install and study hands-on courses.

Project description

learnctl

A rich Textual TUI host for the learning-coach skill. learnctl reads a Package the skill generates, calls coach.py for all deterministic state, runs declarative lab checks on the host, and walks the learner through the protocol turn-by-turn with a live terminal UI.

Built on the principle the skill enforces: the LLM is a build-time author, not a run-time dependency. v1 runs the entire free path with no model wired up — discover, resume, active-recall warm-up, prerequisite check, primer reading, hands-on task, declarative verifier, hint ladder, solution, scoring, advance. The two metered LLM turns (interview and the opt-in diagnose) are defined slots that v2 will fill via a pluggable provider.

Install

pip install -e .
export LEARNCTL_COACH=/path/to/learning-coach/scripts/coach.py

Commands

learnctl discover              # list topics under ./learning + progress
learnctl status <topic>        # one-shot dashboard (no TUI)
learnctl study   <topic>       # launch the TUI session

A <topic> is a slug (docker), a folder path (learning/docker), or a state.json path. --root <path> overrides the workspace root for slug lookup.

Keyboard shortcuts (TUI)

The control bar is docked to the bottom of the screen so it can never scroll out of view, and every action has a keyboard shortcut as a fallback:

Key Action Available when
r Reveal answer / Run check recall reveal, task step, verify retry
h Show next hint verify failed and rungs remain
s Show solution verify failed
g / f / m Got it / Fuzzy / Missed (self-rate recall) after recall reveal
c Continue / Dismiss most other turns
1 / 2 / 3 Score 60 / 75 / 90 (manual interview) after the interview
q Quit always

Architecture

Five layers, bottom-up:

Layer File Responsibility
engine engine.py Typed subprocess wrapper around coach.py. The only layer that touches state. Parses the ---JSON--- block from each command into typed results. Subprocess (not import) on purpose — validates the host contract any language could implement.
package package.py Read-only loader for path.json + scenario.json + Markdown. Pure file I/O, no logic.
verifier verifier.py Executes the declarative verify.checks on the host: command and script checks run via subprocess with timeouts; file checks read the filesystem. Evaluates expect (contains/regex/equals/exit_code/json with path matching, including json-lines). Honors per-check os restrictions. v1 runs directly on the host; container isolation is a future opt-in.
session session.py The protocol state machine. Walks WARMUP → PREREQS → PRIMER → TASK → VERIFY → INTERVIEW → SCORE → DONE, emitting Turn objects with type, say, data, expects. The active-recall trio (recall_prompt → recall_reveal → recall_grade) is enforced here — the answer is withheld from the prompt envelope by construction, so no host can leak it early. Host-agnostic and unit-testable without a terminal.
tui tui.py Textual app. Renders say as Markdown in a scrolling transcript, shows the right control buttons for each expects, streams hint rungs into a log, and resumes the session with the chosen response.

Plus __main__.py for the CLI entry point. The session has a stub for a future provider layer (interview / diagnose) — has_llm=False in v1 keeps those turns manual.

Tests

LEARNCTL_COACH=/path/to/coach.py python3 tests/test_foundation.py
LEARNCTL_COACH=/path/to/coach.py python3 tests/test_session.py
LEARNCTL_COACH=/path/to/coach.py python3 tests/test_tui.py
  • test_foundation.py — 8 unit tests for the engine, package, and verifier layers including the expect matchers and the Docker-style json-lines path.
  • test_session.py — drives the full free-path session end-to-end and asserts the turn sequence.
  • test_tui.py — runs the Textual app headlessly via app.run_test(), clicking every button along the path and asserting the final mastery score.

All three currently pass against the real coach.py from the skill.

What's intentionally not in v1

  • LLM provider. The interview turn collects a score manually (score buttons in the TUI); the diagnose button falls back to revealing the solution. v2 will add an interface for interview() / diagnose() / ask() with a null implementation for the offline case and concrete providers (Anthropic, etc.) for hosts that wire one up.
  • Container sandbox. The verifier executes on the host with per-check timeouts; v2 can opt-in to a Docker-based sandbox. The skill's authoring safety contract (scoped, non-destructive, transparent, reversible) is the current safety boundary.
  • Generation commands. learnctl consumes packages; generating them is the skill's job. The CLI doesn't wrap init/add-scenario/add-item because those are author-side commands a chat agent or another tool runs.

Cost model

Zero LLM calls per session in v1 — the entire free path is deterministic and free. v2's metered turns (interview, optional diagnose) match the skill's design: ~1 model call per stage plus opt-in diagnoses when novel-stuck.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

learnctl-0.32.8.tar.gz (340.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

learnctl-0.32.8-py3-none-any.whl (189.7 kB view details)

Uploaded Python 3

File details

Details for the file learnctl-0.32.8.tar.gz.

File metadata

  • Download URL: learnctl-0.32.8.tar.gz
  • Upload date:
  • Size: 340.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for learnctl-0.32.8.tar.gz
Algorithm Hash digest
SHA256 71866907df86e5ece51da964d1161e200b4e7615393b31f3ca709d37ba610fab
MD5 885b0d072e3b310761c127c284dea157
BLAKE2b-256 9fc82bf1eb584785f5f284cba944e4e843f5fccca00cbc52b47aace70ebdd34d

See more details on using hashes here.

Provenance

The following attestation bundles were made for learnctl-0.32.8.tar.gz:

Publisher: publish-learnctl.yml on rchaganti/learnctl-stack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file learnctl-0.32.8-py3-none-any.whl.

File metadata

  • Download URL: learnctl-0.32.8-py3-none-any.whl
  • Upload date:
  • Size: 189.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for learnctl-0.32.8-py3-none-any.whl
Algorithm Hash digest
SHA256 0473a76b9384fd6552730f61ee6d25561c4d02d9852a023d793158b34026a9c6
MD5 8fc1169ea1ac18b736a16e5e6422d482
BLAKE2b-256 aa23f82f261793b88e428a0afda2a8ee7bd00b57dd5e6524948064bfed112282

See more details on using hashes here.

Provenance

The following attestation bundles were made for learnctl-0.32.8-py3-none-any.whl:

Publisher: publish-learnctl.yml on rchaganti/learnctl-stack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page