docs(wiki): resync after learner-dir path fix (~/ai-workflow-course)
@@ -153,7 +153,7 @@ beyond a web browser:
|
||||
1. Open the course's home page — **`https://git.jpaul.io/justin/ai-workflow-course`** — and use its
|
||||
**Download ZIP** (archive) link.
|
||||
2. Unzip it under your home directory so the course's `modules/` folder lands at
|
||||
`~/workflow-course/modules/`. (Rename the unzipped folder to `workflow-course` if your download
|
||||
`~/ai-workflow-course/modules/`. (Rename the unzipped folder to `ai-workflow-course` if your download
|
||||
named it something else.)
|
||||
|
||||
You now have every module's files locally, including this one's under
|
||||
@@ -170,8 +170,8 @@ You now have every module's files locally, including this one's under
|
||||
1. Make a working directory and copy in the starter app from this module's `lab/starter/` folder:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/workflow-course/tasks-app
|
||||
cd ~/workflow-course/tasks-app
|
||||
mkdir -p ~/ai-workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
# copy the three files from modules/01-the-copy-paste-problem/lab/starter/ into here:
|
||||
# tasks.py cli.py README.md
|
||||
```
|
||||
|
||||
@@ -155,7 +155,7 @@ and your AI assistant.
|
||||
1. In your project folder, initialize the repo and make the first commit:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git init -b main # start the repo with its first branch named "main" (Git 2.28+)
|
||||
git status # everything shows as "untracked" — Git sees the files but isn't saving them yet
|
||||
```
|
||||
|
||||
@@ -214,7 +214,7 @@ zero.
|
||||
1. Confirm you're starting clean, then create a branch for the ADR:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git status # want: "working tree clean"
|
||||
git switch -c docs/adr-storage # new branch, named for what it's for
|
||||
git branch # the * shows you're on docs/adr-storage now
|
||||
|
||||
@@ -133,7 +133,7 @@ a model/provider here, this is where the BYO-model choice from above gets made.
|
||||
whole point. The convention is **the current working directory is the project**:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app # the repo from Modules 1–2
|
||||
cd ~/ai-workflow-course/tasks-app # the repo from Modules 1–2
|
||||
your-agent # launch it from inside the project
|
||||
```
|
||||
|
||||
@@ -281,7 +281,7 @@ copy-paste loop back in Module 1, now done right.
|
||||
|
||||
1. Install the tool and authenticate it (steps 1–2 in "Wiring it up").
|
||||
|
||||
2. Point it at the repo (step 3): `cd ~/workflow-course/tasks-app` and launch the agentic CLI from
|
||||
2. Point it at the repo (step 3): `cd ~/ai-workflow-course/tasks-app` and launch the agentic CLI from
|
||||
there, **or** open that folder in your editor and open the assistant's agent panel.
|
||||
|
||||
3. **Confirm read access** (step 4). Ask:
|
||||
|
||||
@@ -188,7 +188,7 @@ editor-integrated AI (Module 4) for the part where the AI obeys the file.
|
||||
(If your tool reads several names, copy it to each, or symlink them.)
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
# replace <YOUR_TOOL_FILE> with the name your tool actually reads:
|
||||
cp /path/to/modules/05-commit-the-ai-config/lab/instructions-file-starter.md <YOUR_TOOL_FILE>
|
||||
```
|
||||
|
||||
@@ -265,7 +265,7 @@ deliberately create and resolve a merge conflict — using the AI to help resolv
|
||||
1. Confirm you're on `main` and clean, then create an experiment branch and switch to it:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git switch main
|
||||
git status # must be clean
|
||||
git switch -c experiment/priorities
|
||||
|
||||
@@ -96,17 +96,17 @@ The branch was never the problem. The single working directory is. You need two
|
||||
repository, each with its own checked-out branch.** One repo, many checkouts.
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app # your existing repo from Module 2
|
||||
cd ~/ai-workflow-course/tasks-app # your existing repo from Module 2
|
||||
git worktree add ../tasks-app-remaining -b feature/remaining
|
||||
```
|
||||
|
||||
That command creates a brand-new folder, `~/workflow-course/tasks-app-remaining`, containing a full
|
||||
That command creates a brand-new folder, `~/ai-workflow-course/tasks-app-remaining`, containing a full
|
||||
checkout of your project on a new branch `feature/remaining`. Your original folder is untouched,
|
||||
still on its own branch. You now have two real directories you can `cd` into, edit, and run
|
||||
independently:
|
||||
|
||||
```
|
||||
~/workflow-course/
|
||||
~/ai-workflow-course/
|
||||
tasks-app/ ← the "main" worktree, on (say) main
|
||||
tasks-app-remaining/ ← a "linked" worktree, on feature/remaining
|
||||
```
|
||||
@@ -152,9 +152,9 @@ git worktree prune # forget worktrees whose folders were
|
||||
|
||||
```bash
|
||||
$ git worktree list
|
||||
/home/you/workflow-course/tasks-app a1b2c3d [main]
|
||||
/home/you/workflow-course/tasks-app-remaining d4e5f6a [feature/remaining]
|
||||
/home/you/workflow-course/tasks-app-wipe 7g8h9i0 [feature/wipe]
|
||||
/home/you/ai-workflow-course/tasks-app a1b2c3d [main]
|
||||
/home/you/ai-workflow-course/tasks-app-remaining d4e5f6a [feature/remaining]
|
||||
/home/you/ai-workflow-course/tasks-app-wipe 7g8h9i0 [feature/wipe]
|
||||
```
|
||||
|
||||
Three folders, one repo, three branches checked out simultaneously. No stashing, no switching, no
|
||||
@@ -243,7 +243,7 @@ branch edit the usage line. (The `sed … > tmp && mv` is just a portable, copy-
|
||||
the edit an agent would make.) In your `tasks-app`:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
|
||||
# Agent A's branch: add `wipe` to the usage line and commit it.
|
||||
git switch -c feature/wipe
|
||||
@@ -303,17 +303,17 @@ git worktree list # should show main + feature/wipe + feature/remaining
|
||||
|
||||
This is the part to actually *do simultaneously*, not one then the other.
|
||||
|
||||
1. Open `~/workflow-course/tasks-app-wipe` in one editor/AI session. Give it the prompt in
|
||||
1. Open `~/ai-workflow-course/tasks-app-wipe` in one editor/AI session. Give it the prompt in
|
||||
`lab/agent-a-prompt.md` — *add a `wipe` command that removes all tasks.*
|
||||
2. Open `~/workflow-course/tasks-app-remaining` in a **second** editor/AI session. Give it the prompt
|
||||
2. Open `~/ai-workflow-course/tasks-app-remaining` in a **second** editor/AI session. Give it the prompt
|
||||
in `lab/agent-b-prompt.md` — *add a `remaining` command that prints the number of pending tasks.*
|
||||
3. Let both work at the same time. While they run, prove the isolation from a third terminal — but
|
||||
use commands that **already exist**. (`wipe` and `remaining` don't yet; the agents are still
|
||||
writing them.) Give each worktree its own task and list it:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-wipe && python cli.py add "from worktree A" && python cli.py list
|
||||
cd ~/workflow-course/tasks-app-remaining && python cli.py add "from worktree B" && python cli.py list
|
||||
cd ~/ai-workflow-course/tasks-app-wipe && python cli.py add "from worktree A" && python cli.py list
|
||||
cd ~/ai-workflow-course/tasks-app-remaining && python cli.py add "from worktree B" && python cli.py list
|
||||
```
|
||||
|
||||
Each `list` shows only its own task — worktree A never sees "from worktree B" and vice versa. Each
|
||||
@@ -324,8 +324,8 @@ This is the part to actually *do simultaneously*, not one then the other.
|
||||
4. In each worktree, commit the agent's work on its own branch:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-wipe && git add . && git commit -m "Add wipe command"
|
||||
cd ~/workflow-course/tasks-app-remaining && git add . && git commit -m "Add remaining command"
|
||||
cd ~/ai-workflow-course/tasks-app-wipe && git add . && git commit -m "Add wipe command"
|
||||
cd ~/ai-workflow-course/tasks-app-remaining && git add . && git commit -m "Add remaining command"
|
||||
```
|
||||
|
||||
Two agents, two commits, two branches — neither ever saw the other's files.
|
||||
@@ -333,8 +333,8 @@ This is the part to actually *do simultaneously*, not one then the other.
|
||||
5. *Now* the new commands exist — run each in its own worktree to watch it work:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-wipe && python cli.py wipe # agent A's new command
|
||||
cd ~/workflow-course/tasks-app-remaining && python cli.py remaining # agent B's new command
|
||||
cd ~/ai-workflow-course/tasks-app-wipe && python cli.py wipe # agent A's new command
|
||||
cd ~/ai-workflow-course/tasks-app-remaining && python cli.py remaining # agent B's new command
|
||||
```
|
||||
|
||||
`remaining` counts a single pending task — the one you added to worktree B in step 3 — because B's
|
||||
@@ -345,7 +345,7 @@ This is the part to actually *do simultaneously*, not one then the other.
|
||||
Bring both features home to `main` in your original worktree:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git switch main
|
||||
git merge feature/wipe
|
||||
git merge feature/remaining
|
||||
|
||||
@@ -90,7 +90,7 @@ the shape is the same:
|
||||
3. Point your local repo at it and push:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git remote add origin <URL-you-copied>
|
||||
git push -u origin main
|
||||
```
|
||||
@@ -315,7 +315,7 @@ WSL, or Git Bash on Windows. Continues the `tasks-app` repo from Module 2.
|
||||
2. Point your repo at the remote and push:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git remote -v # probably empty — no remote yet
|
||||
git remote add origin <URL> # paste the URL you copied
|
||||
git remote -v # now origin shows, for fetch and push
|
||||
@@ -348,7 +348,7 @@ independent* copy, history and all — not a snapshot.
|
||||
5. Now clone the remote into a *separate* directory, as if you were a teammate on a fresh machine:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course
|
||||
cd ~/ai-workflow-course
|
||||
git clone <URL> tasks-app-teammate
|
||||
cd tasks-app-teammate
|
||||
git log --oneline # the ENTIRE history is here — every commit, not just the latest
|
||||
@@ -362,7 +362,7 @@ independent* copy, history and all — not a snapshot.
|
||||
|
||||
```bash
|
||||
# from your original repo:
|
||||
bash ~/workflow-course/tasks-app/verify-backup.sh # (copied from lab/verify-backup.sh)
|
||||
bash ~/ai-workflow-course/tasks-app/verify-backup.sh # (copied from lab/verify-backup.sh)
|
||||
```
|
||||
|
||||
The script confirms (a) you have a remote configured, (b) your local branch is fully pushed
|
||||
@@ -381,7 +381,7 @@ independent* copy, history and all — not a snapshot.
|
||||
7. Edit the README in your *teammate* clone, commit, and push from there:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-teammate
|
||||
cd ~/ai-workflow-course/tasks-app-teammate
|
||||
# edit README.md, then:
|
||||
git add . && git commit -m "Note the remote in the README"
|
||||
git push
|
||||
@@ -390,7 +390,7 @@ independent* copy, history and all — not a snapshot.
|
||||
8. Back in your *original* repo, pull it down:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git fetch # download the new commit, but don't merge yet
|
||||
git log main..origin/main # SEE exactly what's incoming before you take it
|
||||
git pull # now merge it into your local main
|
||||
|
||||
@@ -209,7 +209,7 @@ real change, then review a diff the "AI" produced and catch the trap planted in
|
||||
place of `/path/to/`, the same copy-it-in move from Module 5.)
|
||||
|
||||
```bash
|
||||
mkdir -p ~/workflow-course/review-lab && cd ~/workflow-course/review-lab
|
||||
mkdir -p ~/ai-workflow-course/review-lab && cd ~/ai-workflow-course/review-lab
|
||||
cp /path/to/modules/10-reviewing-code-you-didnt-write/lab/tasks-app/*.py .
|
||||
printf 'tasks.json\n__pycache__/\n' > .gitignore # keep generated runtime state out of your review diffs (Module 2)
|
||||
git init -qb main && git add . && git commit -qm "base: tasks-app" # -b main so the git switch main / git diff main.. steps below resolve
|
||||
|
||||
@@ -246,7 +246,7 @@ do them once on purpose now.
|
||||
1. Make sure you're on a clean `main`:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git switch main
|
||||
git status # should be clean
|
||||
```
|
||||
|
||||
@@ -227,7 +227,7 @@ your machine first.
|
||||
run both checks exactly as CI will:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
pip install ruff
|
||||
python -m unittest # should report all tests passing
|
||||
ruff check . # should report no issues (or fix what it flags)
|
||||
|
||||
@@ -190,7 +190,7 @@ containerize and run the app you already have.
|
||||
Dockerfile top to bottom — every line is commented. Then build:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
docker build -t tasks-app .
|
||||
```
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ config per environment.
|
||||
the before-picture:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
python sync.py
|
||||
```
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ is the one that lands the concept.
|
||||
> global `pip install` is refused on purpose. The clean fix is a virtual environment per project:
|
||||
>
|
||||
> ```bash
|
||||
> cd ~/workflow-course/tasks-app
|
||||
> cd ~/ai-workflow-course/tasks-app
|
||||
> python3 -m venv .venv # one-time
|
||||
> source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
> python3 -m pip install "mcp[cli]"
|
||||
@@ -268,7 +268,7 @@ is the one that lands the concept.
|
||||
> - **The install interpreter must match the config's launch command.** Your MCP client starts the
|
||||
> server by running the `"command"` in its config — *not* your activated shell — so activating a
|
||||
> venv does nothing to help the client find the SDK. You must point `"command"` at the venv's
|
||||
> **absolute** python path (e.g. `~/workflow-course/tasks-app/.venv/bin/python`, or
|
||||
> **absolute** python path (e.g. `~/ai-workflow-course/tasks-app/.venv/bin/python`, or
|
||||
> `...\.venv\Scripts\python.exe` on Windows). If they don't match, the server dies on `import mcp`
|
||||
> and your tool just says "not connected" with no obvious reason — the exact failure this lab is
|
||||
> about avoiding.
|
||||
@@ -276,7 +276,7 @@ is the one that lands the concept.
|
||||
> Before wiring anything, verify with the *same* interpreter the config will launch:
|
||||
>
|
||||
> ```bash
|
||||
> ~/workflow-course/tasks-app/.venv/bin/python -c "import mcp; print('mcp ok')"
|
||||
> ~/ai-workflow-course/tasks-app/.venv/bin/python -c "import mcp; print('mcp ok')"
|
||||
> ```
|
||||
|
||||
### Part A — Connect an existing server (optional warm-up, ~10 min)
|
||||
@@ -350,8 +350,8 @@ That's the entire client/server loop, end to end, with zero code you wrote. Now
|
||||
|
||||
```json
|
||||
"tasks": {
|
||||
"command": "/ABSOLUTE/PATH/TO/workflow-course/tasks-app/.venv/bin/python",
|
||||
"args": ["/ABSOLUTE/PATH/TO/workflow-course/tasks-app/tasks_mcp_server.py"]
|
||||
"command": "/ABSOLUTE/PATH/TO/ai-workflow-course/tasks-app/.venv/bin/python",
|
||||
"args": ["/ABSOLUTE/PATH/TO/ai-workflow-course/tasks-app/tasks_mcp_server.py"]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ seen, producing all four parts without you listing the steps.
|
||||
(e.g. `add-command.md`). If it doesn't, just drop it at the repo root — you'll invoke it by name.
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
cp /path/to/modules/21-skills-teaching-the-ai-your-playbook/lab/add-command-skill.md add-command.md
|
||||
```
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ normal question) and the attacker (you plant content the agent reads).
|
||||
a real-looking task with an injection underneath:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
python cli.py add "$(cat /path/to/lab/poisoned-task.txt)"
|
||||
python cli.py list
|
||||
```
|
||||
|
||||
+1
-1
@@ -247,7 +247,7 @@ out of the agent's `git add -A`, so the change you review in Part B is clean. Th
|
||||
branch:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git checkout -b agent/delete-command
|
||||
|
||||
# Simulate an agent that produces a BROKEN change, then run the gate on it:
|
||||
|
||||
@@ -117,7 +117,7 @@ Each agent gets **its own worktree on its own branch tied to its own issue.** Th
|
||||
keeps a fleet legible:
|
||||
|
||||
```
|
||||
~/workflow-course/
|
||||
~/ai-workflow-course/
|
||||
tasks-app/ ← main worktree, on main (the integration point — no agent works here)
|
||||
tasks-app-42-count/ ← worktree for issue #42, branch feature/42-count, agent A
|
||||
tasks-app-43-docs/ ← worktree for issue #43, branch feature/43-docs, agent B
|
||||
@@ -338,9 +338,9 @@ thing you're waiting on.
|
||||
5. In each worktree, commit the agent's work on its own branch and push it:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-42-count && git add . && git commit -m "Add count command (#42)" && git push -u origin feature/42-count
|
||||
cd ~/workflow-course/tasks-app-43-docs && git add . && git commit -m "Document commands, add changelog (#43)" && git push -u origin feature/43-docs
|
||||
cd ~/workflow-course/tasks-app-44-clear && git add . && git commit -m "Add clear command (#44)" && git push -u origin feature/44-clear
|
||||
cd ~/ai-workflow-course/tasks-app-42-count && git add . && git commit -m "Add count command (#42)" && git push -u origin feature/42-count
|
||||
cd ~/ai-workflow-course/tasks-app-43-docs && git add . && git commit -m "Document commands, add changelog (#43)" && git push -u origin feature/43-docs
|
||||
cd ~/ai-workflow-course/tasks-app-44-clear && git add . && git commit -m "Add clear command (#44)" && git push -u origin feature/44-clear
|
||||
```
|
||||
|
||||
### Part C — Fan in through the funnel
|
||||
@@ -357,7 +357,7 @@ thing you're waiting on.
|
||||
|
||||
```bash
|
||||
# via the forge UI, or locally:
|
||||
cd ~/workflow-course/tasks-app && git switch main
|
||||
cd ~/ai-workflow-course/tasks-app && git switch main
|
||||
git merge feature/42-count # clean
|
||||
git merge feature/43-docs # clean — different files entirely
|
||||
```
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ account, and a working Docker install.
|
||||
2. Branch off `main`, named for the issue:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git switch main && git pull
|
||||
git switch -c 47-due-dates # use your real issue number
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user