Stage 2: Find your way

What the terminal, Git, GitHub, uv and nbdev do in marisco, and your first pull request with the agent

The agent runs most commands for you. In manual mode, which you set up in stage 1, Claude Code shows you each command before it runs and asks for your approval. Everyday commands, such as git status and git commit, are the exception: the safecmd tool approves them for you. This stage teaches you what those commands do, so that you can decide whether to approve them. You do not need to remember the commands themselves. The cheatsheet lists them.

For more depth, Software Carpentry’s lessons on the Unix shell and version control with Git are written for scientists.

The terminal

The terminal runs a shell, a program that reads the command you type and starts the program it names. A command is a program name followed by arguments, as in cd nbs or marisco-ingest helcom out.nc. Most programs print their options with -h or --help.

The shell always works in one folder, the current folder. pwd prints it. Paths name files and folders. ~ is your home folder, . is the current folder and .. is the folder above it. A path that starts with / or ~ is absolute. Any other path is relative to the current folder.

Environment variables are named values that every program started from the shell can read. ZOTERO_API_KEY is one. PATH is another: it lists the folders where the shell looks for programs. Activating the workspace environment puts ~/aai-ws/.venv/bin at the front of PATH. That is why marisco-ingest is found only in a terminal where the environment is active.

Press Ctrl+C to stop the command that is running. rm deletes files without a trash bin, and there is no undo.

Git

A Git repository is a folder whose history Git records. Your marisco folder is one. Git records history as commits. A commit is a snapshot of the files with a message that says what changed and why.

A change goes through three states. First you edit a file, and the change exists only in your folder. Then git add stages the change, which marks it for the next commit. Finally git commit records the staged changes as a commit. Git can recover anything you have committed. It cannot recover a change you never committed.

A branch is a line of commits. main is the branch that the published package and documentation come from. You make each change on its own branch, and the change reaches main only through a pull request.

Your folder is a copy of the repository on GitHub. Git calls the GitHub copy origin. git push sends your commits to origin, and git pull brings the commits of other people into your folder.

These commands discard work: git restore, git reset --hard, git clean, git branch -D and git push --force. Before you approve one of them, make sure you know what it will discard.

GitHub

GitHub hosts the repository at franckalbinet/marisco, with its issues and pull requests.

An issue describes one task, problem or question, and holds the discussion about it. A pull request (PR) proposes to merge a branch into main. Its page shows the changed lines (the diff), the result of the automatic checks, and the review comments.

Every change follows the same path:

  1. An issue describes the change.
  2. You make the change on a branch, in one or more commits.
  3. You push the branch and open a PR.
  4. GitHub runs the automatic checks (CI).
  5. The maintainer reviews the PR and merges it into main.

main accepts changes only through a PR. GitHub refuses a push to main from your computer.

CI runs three checks, in this order. nbdev-clean must find nothing to clean in the notebooks. nbdev-export must find nothing to change in the marisco/ package. nbdev-test must pass on every notebook. If you run the same three commands before you push, CI passes.

A commit message that contains refs #81 links the commit to issue 81. A commit message with fixes #81 also closes issue 81 when the commit reaches main.

uv and the workspace environment

A Python environment is a folder that holds a Python interpreter and a set of installed packages. Your workspace environment is ~/aai-ws/.venv. uv built it in stage 1. ws-sync keeps it up to date. You rarely run uv yourself.

marisco is installed in editable mode. The environment does not hold a copy of marisco. It points at your marisco folder. Python uses the code in that folder as soon as you change it.

which python prints the path of the Python that the shell finds. When the workspace environment is active, the path starts with ~/aai-ws/.venv (shown in full, as /Users/... or /home/...).

nbdev

marisco’s source code is the Jupyter notebooks in nbs/. nbdev generates the Python package in marisco/ from them. Never edit a file in marisco/, because nbdev-export overwrites it. Edit the notebook instead.

A notebook holds code, the prose that explains it, and the examples that test it. nbdev builds the documentation website from the same notebooks. Directives on the first line of a code cell tell nbdev what to do with that cell. #| export puts the cell in the package. Writing a new handler explains the directives that handlers use.

You use four nbdev commands:

  • nbdev-export regenerates marisco/ from the notebooks.
  • nbdev-clean removes metadata that Jupyter adds to notebooks, such as execution counts. That metadata would otherwise appear in every diff.
  • nbdev-test runs a notebook, or all notebooks, and reports any cell that fails.
  • nbdev-readme regenerates README.md from nbs/index.ipynb.

Your first pull request

Make a small improvement to the documentation, with the agent. For example, fix a typo, an unclear sentence or a broken link in a page under nbs/onboarding/ or nbs/how-to/. You read the onboarding pages recently as a new reader, which makes you a good judge of where they are unclear.

  1. Open an issue on GitHub that describes the change.
  2. Start claude in ~/aai-ws/marisco. Ask it to create a branch, make the change in the notebook, run nbdev-export, nbdev-clean and nbdev-test on that notebook, commit with refs #<issue number>, push the branch and open a PR.
  3. Before you approve each command, say what it will do. If you are not sure, ask the agent to explain the command first.
  4. On the PR page, read the diff and check that CI passes. The maintainer then reviews and merges the PR.
  5. After the merge, return to main and update it: git switch main, then git pull. Delete your branch with git branch -d <branch name>.

Check your understanding

Stage 2 is complete when your first PR is merged and you can answer these questions:

  • Which folder holds marisco’s source code, and which folder must you never edit?
  • What is the difference between a commit and a push?
  • In a new terminal where you have not activated the workspace environment, why does marisco-ingest give command not found?
  • Which Git commands can discard your work?
  • What do the three CI checks verify, and which commands make them pass?
  • Where does your Zotero API key go, and where must it never go?