Remove em-dashes from the wiki generator + README #95
@@ -2,33 +2,34 @@
|
|||||||
### The Toolchain Around AI Coding
|
### The Toolchain Around AI Coding
|
||||||
|
|
||||||
A living course for IT professionals who are comfortable in an AI chat window and starting to build
|
A living course for IT professionals who are comfortable in an AI chat window and starting to build
|
||||||
real software with it — but are still copy-pasting between the chat and their files. The goal is to
|
real software with it, but who are still copy-pasting between the chat and their files. The goal is
|
||||||
replace that loop with durable engineering workflows: version control, collaboration, CI/CD,
|
to replace that loop with durable engineering workflows: version control, collaboration, CI/CD,
|
||||||
runners, and the tools that extend AI into real systems.
|
runners, and the tools that extend AI into real systems.
|
||||||
|
|
||||||
> **Thesis:** the model is the cheap, swappable part. The workflow around it is the skill that
|
> **Thesis:** the model is the cheap, swappable part. The workflow around it is the skill that
|
||||||
> lasts. This course is deliberately model- and vendor-agnostic — whichever LLM you use, the
|
> lasts. This course is deliberately model- and vendor-agnostic: whichever LLM you use, the
|
||||||
> scaffolding is the same.
|
> scaffolding is the same.
|
||||||
|
|
||||||
This repo *is* the course, and it also dogfoods the course: it's version-controlled, it commits its
|
This repo *is* the course, and it also dogfoods the course: it's version-controlled, it commits its
|
||||||
own AI instructions file ([`AGENTS.md`](AGENTS.md), the subject of Module 5), and each module is
|
own AI instructions file ([`AGENTS.md`](AGENTS.md), the subject of Module 5), and each module is
|
||||||
built on a branch and merged through review — exactly the motion the modules teach.
|
built on a branch and merged through review, the same motion the modules teach.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Read it as a book
|
## Read it as a book
|
||||||
|
|
||||||
The lessons are rendered into the **[Wiki](https://git.jpaul.io/justin/ai-workflow-course/wiki)** as a navigable textbook (unit-by-unit
|
The lessons render into the **[Wiki](https://git.jpaul.io/justin/ai-workflow-course/wiki)** as a
|
||||||
sidebar, one page per module). The wiki is generated from `modules/` and kept in sync
|
navigable textbook (unit-by-unit sidebar, one page per module, prev/next links). The wiki is
|
||||||
automatically — it's build output, so read it there but **edit the lessons here in `modules/`**.
|
generated from `modules/` and kept in sync automatically; it's build output, so read it there but
|
||||||
See [`tools/`](tools/) for the generator and the sync workflows.
|
**edit the lessons here in `modules/`**. See [`tools/`](tools/) for the generator and the sync
|
||||||
|
workflows.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Who this is for
|
## Who this is for
|
||||||
|
|
||||||
IT professionals who are fluent in an AI chat window and comfortable with ops concepts — **not
|
IT professionals who are fluent in an AI chat window and comfortable with ops concepts. Not
|
||||||
beginners.** If you already paste code between a chat tab and your editor and feel the friction, you
|
beginners. If you already paste code between a chat tab and your editor and feel the friction, you
|
||||||
are the audience. You will not be taught what a variable is; you will be taught the engineering
|
are the audience. You will not be taught what a variable is; you will be taught the engineering
|
||||||
scaffolding that makes AI-assisted work safe, shareable, and repeatable.
|
scaffolding that makes AI-assisted work safe, shareable, and repeatable.
|
||||||
|
|
||||||
@@ -42,11 +43,11 @@ units, plus a capstone finale.
|
|||||||
|
|
||||||
| Unit | Modules | Theme |
|
| Unit | Modules | Theme |
|
||||||
|------|---------|-------|
|
|------|---------|-------|
|
||||||
| **1 — Get out of the chat window** | 1–7 | The local foundation: version control, committing the AI's config, getting the AI editing real files safely. |
|
| **1: Get out of the chat window** | 1–7 | The local foundation: version control, committing the AI's config, getting the AI editing real files safely. |
|
||||||
| **2 — Make it shareable, reviewable, recoverable** | 8–12 | The team layer: hosting, issues, review, collaboration, recovery. |
|
| **2: Make it shareable, reviewable, recoverable** | 8–12 | The team layer: hosting, issues, review, collaboration, recovery. |
|
||||||
| **3 — Automate the checking and shipping** | 13–19 | The pipeline: tests, CI, security scanning, containers, secrets, delivery, runners. |
|
| **3: Automate the checking and shipping** | 13–19 | The pipeline: tests, CI, security scanning, containers, secrets, delivery, runners. |
|
||||||
| **4 — Extend the AI into your systems** | 20–23 | The frontier: MCP, skills, securing them, existing codebases. |
|
| **4: Extend the AI into your systems** | 20–23 | The frontier: MCP, skills, securing them, existing codebases. |
|
||||||
| **5 — AI in the loop** | 24–27 | Agents inside the pipeline, from assistive to autonomous, plus the evals that make it trustworthy. |
|
| **5: AI in the loop** | 24–27 | Agents inside the pipeline, from assistive to autonomous, plus the evals that make it trustworthy. |
|
||||||
| **Capstone** | finale | One real feature taken end to end. |
|
| **Capstone** | finale | One real feature taken end to end. |
|
||||||
|
|
||||||
**Durable core vs. expansion zone.** Modules 1–14 are the stable foundation. From Module 15 onward
|
**Durable core vs. expansion zone.** Modules 1–14 are the stable foundation. From Module 15 onward
|
||||||
@@ -58,17 +59,29 @@ the reasoning behind the sequencing.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## How git works in this course
|
||||||
|
|
||||||
|
You don't memorize git commands here. Modules 1–3 have you run the basics by hand so you build
|
||||||
|
intuition (the AI is still in a browser chat). Module 4 puts the AI in your editor/CLI, and from
|
||||||
|
there you **direct the AI to do the git work** (commit, branch, merge, revert) and verify the
|
||||||
|
result. Think arithmetic by hand first, then a calculator. You learn that git is critical and how it
|
||||||
|
works; the AI drives the keystrokes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Format and conventions
|
## Format and conventions
|
||||||
|
|
||||||
- **Written lessons + interactive labs.** Every module is a README you read *and* a lab you run at
|
- **Written lessons + interactive labs.** Every module is a README you read *and* a lab you run at
|
||||||
the keyboard. There are no quizzes; there's a "you're done when…" check.
|
the keyboard. There are no quizzes; there's a "you're done when…" check.
|
||||||
- **Run labs on your own machine, any OS.** No sandbox or cloud account required. Where a lab needs
|
- **Run labs on your own machine, any OS.** No sandbox or cloud account required. Where a lab needs
|
||||||
code, it leans on **Python or shell** — picked per lab, kept as small as possible. The *concepts*
|
code, it leans on **Python or shell**, picked per lab, kept as small as possible. The *concepts*
|
||||||
are language-agnostic; the labs just need something concrete to run.
|
are language-agnostic; the labs just need something concrete to run.
|
||||||
|
- **Claude Code as the worked example.** Commands and labs use Claude Code as the concrete agent
|
||||||
|
(`claude --version # sub your own agent`); the concepts stay model- and tool-agnostic.
|
||||||
- **GitHub is the default, not the requirement.** Hosting examples use GitHub because nearly
|
- **GitHub is the default, not the requirement.** Hosting examples use GitHub because nearly
|
||||||
everyone will encounter it, but the course is provider-neutral and includes an optional
|
everyone will encounter it, but the course is provider-neutral and includes an optional
|
||||||
**self-hosted-forge track** for on-prem and air-gapped environments.
|
**self-hosted-forge track** for on-prem and air-gapped environments.
|
||||||
- **Self-checks only.** No grading, no certification — each module ends at a concrete done-criterion.
|
- **Self-checks only.** No grading, no certification; each module ends at a concrete done-criterion.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -77,7 +90,7 @@ the reasoning behind the sequencing.
|
|||||||
```
|
```
|
||||||
ai-workflow-course/
|
ai-workflow-course/
|
||||||
README.md # this file
|
README.md # this file
|
||||||
AGENTS.md # committed AI instructions — dogfoods Module 5 (vendor-neutral name)
|
AGENTS.md # committed AI instructions; dogfoods Module 5 (vendor-neutral name)
|
||||||
the-workflow-syllabus.md # the full course plan (source of truth for structure)
|
the-workflow-syllabus.md # the full course plan (source of truth for structure)
|
||||||
handoff.md # build-context notes for the authoring sessions
|
handoff.md # build-context notes for the authoring sessions
|
||||||
_TEMPLATE.md # the shape every module follows
|
_TEMPLATE.md # the shape every module follows
|
||||||
@@ -98,5 +111,6 @@ ai-workflow-course/
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Planning is complete (27 modules + capstone). Authoring is in progress, built in dependency-chain
|
All 27 modules and the capstone are written and reviewed. The lessons render to the
|
||||||
order. Modules 1–2 are drafted as the reference exemplars; the rest follow.
|
[Wiki](https://git.jpaul.io/justin/ai-workflow-course/wiki) as a textbook, kept in sync from
|
||||||
|
`modules/` by CI. Blog drafts for jpaul.me live under [`blog/`](blog/).
|
||||||
|
|||||||
+11
-11
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
Host-agnostic: this writes Markdown into a target wiki working directory. A thin
|
Host-agnostic: this writes Markdown into a target wiki working directory. A thin
|
||||||
per-host CI wrapper clones the host's `<repo>.wiki.git`, runs this script, then
|
per-host CI wrapper clones the host's `<repo>.wiki.git`, runs this script, then
|
||||||
commits and pushes. The same script feeds both the Gitea and GitHub wikis — only
|
commits and pushes. The same script feeds both the Gitea and GitHub wikis; only
|
||||||
the `--host` URL flavor and the CI wrapper differ.
|
the `--host` URL flavor and the CI wrapper differ.
|
||||||
|
|
||||||
The wiki is GENERATED BUILD OUTPUT. Never hand-edit it; edit modules/ and let CI
|
The wiki is GENERATED BUILD OUTPUT. Never hand-edit it; edit modules/ and let CI
|
||||||
re-render. Labs are NOT copied into the wiki — lesson pages link to the runnable
|
re-render. Labs are NOT copied into the wiki; lesson pages link to the runnable
|
||||||
files back in the main repo. Each page gets prev/next navigation so the wiki reads
|
files back in the main repo. Each page gets prev/next navigation so the wiki reads
|
||||||
like a textbook.
|
like a textbook.
|
||||||
|
|
||||||
@@ -24,11 +24,11 @@ from pathlib import Path
|
|||||||
|
|
||||||
# Unit structure (module numbers), from the syllabus. Drives the textbook nav.
|
# Unit structure (module numbers), from the syllabus. Drives the textbook nav.
|
||||||
UNITS = [
|
UNITS = [
|
||||||
("Unit 1 — Get out of the chat window", range(1, 8)),
|
("Unit 1: Get out of the chat window", range(1, 8)),
|
||||||
("Unit 2 — Make it shareable, reviewable, recoverable", range(8, 13)),
|
("Unit 2: Make it shareable, reviewable, recoverable", range(8, 13)),
|
||||||
("Unit 3 — Automate the checking and shipping", range(13, 20)),
|
("Unit 3: Automate the checking and shipping", range(13, 20)),
|
||||||
("Unit 4 — Extend the AI into your systems", range(20, 24)),
|
("Unit 4: Extend the AI into your systems", range(20, 24)),
|
||||||
("Unit 5 — AI in the Loop", range(24, 28)),
|
("Unit 5: AI in the Loop", range(24, 28)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ def first_h1(text: str, fallback: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def short_title(h1: str) -> str:
|
def short_title(h1: str) -> str:
|
||||||
"""'Module 1 — The Copy-Paste Problem' -> 'The Copy-Paste Problem'."""
|
"""'Module 1: The Copy-Paste Problem' -> 'The Copy-Paste Problem'."""
|
||||||
m = re.match(r"^Module\s+\d+\s*[—:-]\s*(.+)$", h1)
|
m = re.match(r"^Module\s+\d+\s*[—:-]\s*(.+)$", h1)
|
||||||
return m.group(1).strip() if m else h1
|
return m.group(1).strip() if m else h1
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ def rewrite_repo_file_links(body: str, web_base: str, branch: str, host: str) ->
|
|||||||
def banner(source_path: str, source_url: str) -> str:
|
def banner(source_path: str, source_url: str) -> str:
|
||||||
return (
|
return (
|
||||||
f"> 📖 _This page is generated from [`{source_path}`]({source_url}). "
|
f"> 📖 _This page is generated from [`{source_path}`]({source_url}). "
|
||||||
f"**Edit the source, not the wiki** — edits here are overwritten on the next sync. "
|
f"**Edit the source, not the wiki**; edits here are overwritten on the next sync. "
|
||||||
f"Run the hands-on labs from the repo, linked inline._\n"
|
f"Run the hands-on labs from the repo, linked inline._\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ def main() -> int:
|
|||||||
cap_title = None
|
cap_title = None
|
||||||
if cap.exists():
|
if cap.exists():
|
||||||
body = cap.read_text(encoding="utf-8")
|
body = cap.read_text(encoding="utf-8")
|
||||||
cap_title = first_h1(body, "Capstone — The Full Loop")
|
cap_title = first_h1(body, "Capstone: The Full Loop")
|
||||||
seq.append({"page": "capstone", "label": cap_title, "body": body, "slug": None})
|
seq.append({"page": "capstone", "label": cap_title, "body": body, "slug": None})
|
||||||
|
|
||||||
# --- pass 2: write each page with banner + prev/next nav --------------
|
# --- pass 2: write each page with banner + prev/next nav --------------
|
||||||
@@ -212,7 +212,7 @@ def main() -> int:
|
|||||||
home.append("")
|
home.append("")
|
||||||
home.append(
|
home.append(
|
||||||
"\n---\n> 📖 _This wiki is generated from the "
|
"\n---\n> 📖 _This wiki is generated from the "
|
||||||
f"[course repo]({args.web_base}) — edit `modules/` there, not these pages._"
|
f"[course repo]({args.web_base}); edit `modules/` there, not these pages._"
|
||||||
)
|
)
|
||||||
(out / "Home.md").write_text("\n".join(home) + "\n", encoding="utf-8")
|
(out / "Home.md").write_text("\n".join(home) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user