stepwell
stepwell
CLI + MCP-Server zum Lesen, Prüfen und Verwalten der Projekt-Doku
(BACKLOG.md, PROGRESS.md, docs/archive/*) in Repos, die der
STEPWELL-Methode folgen — Steps, Archiv-Muster, Test-First.
Status: Sechs Phasen fertig. Phase 1 — Core-Library (fehlertolerante Parser,
Status-/Validierungs-Reports) · Phase 2 — MCP-Server + CLI (Read-Tools, Resources) ·
Phase 3 — Mutation (archive_item, progress_update, jeweils Dry-run + Apply) ·
Phase 4 — Locale-Profile (de/en, test-first) · Phase 5 — Server-Name stepwell ·
Phase 6 — Review-Fixes (Stale-Span, Synonym-Regexes, CRLF-Roundtrip, Stale-Check,
STEP_DUPLICATE) + Tool-CRUD (backlog_add/update/remove, progress_plan_phase,
CLI-ASCII-Aliase, title-Parameter).
Aktueller Stand und Step-Historie: PROGRESS.md.
Prinzip
Markdown bleibt Source of Truth. Das Tool liest, validiert und assistiert — es ersetzt die Doku nicht. Geht die Doku verloren, sind keine Daten verloren.
Fehlertoleranz statt Abbruch. Projekte folgen der Methode, nicht byte-genau: Struktur-Drift wird als strukturierte Warnung gemeldet (
ParseResult<T>mitwarnings[]), nie als Crash. Jedes Teil-Ergebnis bleibt abfragbar.Dry-run zuerst. Die beiden schreibenden Tools (
archive_item,progress_update) liefern standardmäßig einen Plan mit Diff-Vorschau; geschrieben wird erst mitdryRun: falsebzw.--apply— danach wird das Ergebnis frisch geparst und verifiziert.Enge Grenze für Schreibzugriffe. Die fehleranfälligen, strukturellen Operationen automatisiert das Tool (verbatim-Verschiebung, Erledigt-Index, Statuszellen, Item-CRUD, Phasen-Planung). Alles andere (Prosa, Ziel-/Abnahme- Texte) editieren Menschen/Agenten direkt in den Markdown-Dateien.
Multi-Projekt. Der Projekt-Root wird je Tool-Call bzw. CLI-Aufruf übergeben — eine Server-Instanz bedient beliebig viele STEPWELL-Projekte.
Datei-Pflicht: Alle vier Dateien sind Pflicht —
BACKLOG.md, PROGRESS.md, docs/archive/BACKLOG_ARCHIVE.md,
docs/archive/PROGRESS_ARCHIVE.md. Fehlt eine, lädt das Projekt nicht
(harter Fehler mit klarer Meldung).
Format-Legende (kanonisch: PLAYBOOK §3 + §7):
Symbol | Bedeutung | ID-Serie |
🔴 kritisch · 🟠 hoch · 🟡 mittel · 🟢 niedrig | Backlog-Priorität = Sektion |
|
🔵 Test-Lücke | Backlog-Priorität = Sektion | keine Serie — explizite ID Pflicht |
⬜ offen · 🔄 in Arbeit · ✅ fertig · ⛔ blockiert | Step-Status in | Steps |
weitere Serienbuchstaben ( | thematische Serien, nicht prioritätsgebunden | fortlaufend, nie wiederverwendet |
Anforderungen & Setup
Node.js ≥ 22.18 — das Repo verteilt TypeScript-Source und nutzt das native Type-Stripping von Node (kein Build-Schritt).
npm install
npm run typecheck # strict, deckt src UND tests ab
npm run test # Vitest, protokollecht gegen die Fixtures
npm run test:watchMCP-Server
Server-Name stepwell (Transport stdio, Entry packages/mcp/src/serve.ts).
Dieses Repo bindet den Server bereits in opencode.json ein (nach Änderungen an
der Config opencode neu starten). Für andere MCP-Clients (Claude Desktop,
Cursor, …) das gleiche Muster:
{
"mcp": {
"stepwell": {
"type": "local",
"command": ["node", "/pfad/zu/stepwell-tool/packages/mcp/src/serve.ts"],
"enabled": true
}
}
}Manuelle Verifikation mit dem Inspector:
npx @modelcontextprotocol/inspector node packages/mcp/src/serve.tsDie Test-Suite deckt denselben Protokoll-Pfad automatisiert ab
(InMemoryTransport + Client, plus ein echter stdio-Handshake-Test).
Distribution (zwei Kanäle)
MCP-Server:
npx stepwell(bzw.serve.ts) — operativ, Tools wie unten. Das veröffentlichte Package shippt kompiliertesdist(seit 10.4/H1) und ist damit direkt ausnode_moduleslauffähig —prepublishOnlybaut vor dem Publish.SKILL.md:
packages/mcp/skills/stepwell/SKILL.md(liegt im npm-Pack) — portabler Wegweiser für Skill-Ökosysteme (Claude Skills, Gemini CLI, …): wann welches Tool, Gates (Freigabe/Content), Test-First, Statuspflege nur via Tools. Er ersetzt weder MCP-Server noch PLAYBOOK.md — beides bleibt bindend.
Tools
Alle Tools nehmen root (absoluter Pfad zum Projekt-Root) pro Call. Alle JSON-Text-Payloads
sind kompakt (ohne Einrückung — Token-Ökonomie, E1). docs_validate,
progress_update und archive_item liefern ihre Daten zusätzlich als
structuredContent nur auf Opt-in mit structured: true (M3/9.7, Dedupe seit E1 —
Default ist nur Text); Fehlerantworten (isError: true, inkl. PROJECT_NOT_INITIALIZED)
tragen kein structuredContent.
Fehler (fehlende Pflichtdatei, unbekannte ID/Phase) liefern isError: true
mit klarer Meldung — der Server stürzt nicht ab.
Lesen
Tool | Parameter | Ergebnis |
|
| Aggregat: offene Items je Priorität, 🔄-Steps + zugeordnete Phasen, ✅-Quote der Tabelle, alle Funde + Warnungen, |
|
| Items der BACKLOG.md ohne |
|
| Merge-Sicht für eine Item-ID über offenes BACKLOG ↔ Erledigt-Index ↔ BACKLOG_ARCHIVE, inkl. |
|
| Zeilen der Fortschrittstabelle |
|
| Detail-Block inkl. |
|
| Validate-Funde (Konsistenzregeln) + eingesammelte Parse-Warnungen, |
Schreiben (Dry-run + Apply)
Tool | Parameter | Verhalten |
|
| Plant die verbatim-Verschiebung eines Items: Block (span-basiert) aus BACKLOG.md entfernen, im Archiv-Exemplar Checkbox → |
|
| Setzt die Statuszelle(n) der Steps (fehlende Zeilen werden ergänzt, Name aus dem Scope-Bullet abgeleitet); legt bei 🔄 ein Detail-Block-Skelett unter „Laufende Phasen" an ( |
|
| Legt ein offenes Item am Ende der Ziel-Sektion an: ID mit Konventionsprüfung ( |
|
| Ändert Titel/Priorität/Text/Sektion im Block-Format (Span-Neuberechnung, Checkbox- und |
|
| Kein Hard-Delete: Block wandert verbatim ins BACKLOG_ARCHIVE (Checkbox bleibt |
|
| Plant eine Phase voraus: Tabellen-Zeilen für alle Steps ( |
Antwortformate: Dry-run liefert den Plan {dryRun, changes:[{file, description, before, after, diff}]}; Apply liefert {written, verification:{ok, messages}}.
Mit detail: "summary" (E1) werden Dry-run-changes auf {file, description, beforeLines, afterLines} + Top-Level-Marker detail: "summary" projiziert —
Default bleibt "diff" mit voller Vorschau (Sicherheitshinweis unangetastet).
Mehrsprachigkeit (Locale-Profile)
Die Doku-Dateien können deutsch oder englisch formatiert sein — gemischt im gleichen Repo ist verboten, pro Projekt gilt eine Sprache. Das Tool trennt dabei:
Lesen: immer sprachtolerant (zero-config). Parser und Validator erkennen die Rollen-Marker beider Sprachen per Union-Matching —
Erledigt-Index|Done Index,Ort|Location,erledigt|done,Ziel|Goal,Abnahme|Acceptance,Verifikation|Verification,Umfang|Scope,Fortschritt|Progress,Laufende Phasen|Active Phases,abgeschlossen|completed,Stand:|As of:.Schreiben:
locale-Option aufarchive_itemundprogress_update/backlog_remove("de" | "en"; Default = Auto-Erkennung aus dem Datei-Kontext, Gleichstand →de). Generierte Texte (Index-Zeile, Erledigt-/Verifikations-/Entfernt-Marker, Skeletons) folgen der Ziel-Sprache; CLI-Äquivalent:--locale de|en.Weitere Sprachen:
packages/core/src/profile.tshält die Rollen-Synonyme — eine neue Sprache ist ein neuer Schlüssel je Rolle, kein Parser-Umbau.
Resources (Resource-Templates)
Der Root wird percent-encoded als URI-Segment eingesetzt (Windows-Pfade
enthalten : und \); der Read-Callback dekodiert ihn. Inhalt jeweils verbatim,
text/markdown:
stepwell://{root}/backlog → BACKLOG.md
stepwell://{root}/progress → PROGRESS.md
stepwell://{root}/archive/{kind} → kind = "backlog" | "progress"
stepwell://{root}/phase/{phase} → Phasen-Kontext: Phase verbatim + Tabellen-Zeilen
+ gemergte Backlog-Item-Bodies in Step-Reihenfolge (G5/12.6)
stepwell://{root}/hashes → SHA256 je Doku-Datei (application/json;
Hash-Kurzschluss, E2/12.5 — Fast-Pfad-Fundament E3)
stepwell://templates/{kind} → Skeletons der vier Pflichtdateien
(kind = "backlog" | "progress" |
"backlog-archive" | "progress-archive")M4-Alternativprüfung (G5): Resource statt Tool — der Phasen-Kontext ist reiner Lese-Pfad, und die Komposition passiert zur Lesezeit statt als Duplikat in den Dateien (Anti-Drift): ein Subagent bekommt Phase + Item-Bodies in einem Read, ohne dass ein neues Tool die Surface vergrößert.
Beispiel: stepwell://D%3A%5Cproj%5Cdemo/backlog
Projekt-Init (M8, Variante A): Bei neu angelegten Projekten liest der Agent die vier
Skeletons aus stepwell://templates/{kind} und legt die Dateien damit selbst an —
bewusst kein init_project-Schreib-Tool (M4-Guardrail: Write-Surface klein halten);
die Skeletons liegen kanonisch in stepwell-core (projectTemplates) und sind an
docs_validate fund-frei. Die Init-Fallback-Anleitung (PROJECT_NOT_INITIALIZED)
verweist auf diesen Weg.
CLI
packages/mcp/src/cli.ts — im Workspace-Repo direkt ausführbar
(node packages/mcp/src/cli.ts …); aus dem installierten Package
(npm i -g stepwell bzw. npx stepwell) unter dem Bin-Namen
stepwell.
Menschliche Ausgabe auf stdout; --json liefert die core-Payloads mit vorangestelltem
Versionsfeld schema (aktuell 2, gebumpt mit N1/13.2 — Resource-URI-Änderung ist MAJOR-Kontrakt). Feldkontrakt je Command:
Command | Felder (neben |
|
|
|
|
|
|
|
|
|
|
|
|
| wie |
Kontrakt-Regel (M6/Decision 16): Breaking-Änderung an diesem Feldbestand ⇒
schema hochzählen (in Lockstep mit dem npm-MAJOR).
Releases (Versionspolitik, L6)
Format:
CHANGELOG.mdnach Keep a Changelog 1.1.0,[Unreleased]oben, kuratierte nutzerrelevante Aggregate. Redundanz-Regel: kein Git-Log-Dump, keine Duplikation von Erledigt-Index/BACKLOG_ARCHIVE — Item-/Commit-Historie bleibt in den STEPWELL-Dateien. DatumsformatJJMMDD/HHMM(Decision 11) statt ISO — dokumentierte Abweichung.Lockstep-SemVer (Decision 16): Root,
stepwellundstepwell-coretragen immer dieselbe Version. MAJOR = Breaking im Tool-/JSON-/Resource-Kontrakt (immer zusammen mit demschema-Feld), MINOR = neue Tools/Features, PATCH = Fixes. 0.x bis zum bestandenen Feldtest;1.0.0= Freigabe-Moment.Publish-Checkliste: (1)
Unreleasedim CHANGELOG kuratieren, (2) Version in allen dreipackage.jsonbumpen (Lockstep), (3) CHANGELOG-Sektion[<version>] - <JJMMDD/HHMM>, (4) Git-Tagv<version>, (5) nurstepwellpublizieren (npm publish --otp, dist-taglatest; core wird als Abhängigkeit mit verteilt), (6) CI-Jobpack-smokemuss grün sein — dynamisch seit 10.5/H1, beweist Handshake gegen das installierte Artefakt (server stepwell).
# Status-Aggregat
node packages/mcp/src/cli.ts status --root <projekt> [--json]
# Backlog listen/filtern — Icons oder ASCII-Aliase (red/kritisch/p1, hoch/p2, mittel/p3, niedrig/p4, blue/test/p5)
node packages/mcp/src/cli.ts backlog --root <projekt> [--priority red,yellow] [--open false] [--section HOCH] [--json]
# Fortschrittstabelle — Status als Icon oder Alias (open, running/wip, done, blocked)
node packages/mcp/src/cli.ts progress --root <projekt> [--status done] [--json]
# Konsistenzprüfung (Exit 1 bei Funden — CI-tauglich)
node packages/mcp/src/cli.ts validate --root <projekt> [--json]
# Erledigtes Item archivieren (Dry-run-Vorschau, dann --apply)
node packages/mcp/src/cli.ts archive --root <projekt> --id H1 [--note "Commit abc1234"] [--locale en] [--apply]
# Step-Status pflegen (Dry-run-Vorschau, dann --apply) — --title benennt den Block-Heading um
node packages/mcp/src/cli.ts progress-update --root <projekt> --phase "Phase 2" --step 2.2 --status running [--title "Neuer Titel"] [--note "…"] [--checkpoint <sha>] [--locale en] [--apply]Ungültige Werte liefern Exit 2 mit der Liste der erlaubten Aliase (z. B.
🔴=red/kritisch/p1, …, ⬜=open, 🔄=running/wip, ✅=done, ⛔=blocked).
Exit-Codes: 0 Erfolg (bzw. keine Validate-Funde) · 1 Fehler bzw.
Validate-Funde · 2 Usage-Fehler (unbekanntes Kommando, fehlende Pflicht-Option).
CI (optional)
Dieses Repo nutzt GitHub Actions (.github/workflows/ci.yml): install → typecheck
→ test (JUnit- + Coverage-Report als Artefakt) → validate --root . (Exit 1 bei
Doku-Funden schlägt den Job um).
Für kleinere Projekte genügt der lokale Lauf — die Pipeline ist Kanonen auf Spatzen, wenn niemand auf sie schaut:
npm install && npm run typecheck && npm run test && node packages/mcp/src/cli.ts validate --root .STEPWELL-Projekte können ci.yml als Vorlage kopieren; die Methode (PLAYBOOK)
verlangt keine CI.
Warnungs-Codes
Parse-Warnungen entstehen beim Parsen einzelner Dateien (Drift-Toleranz),
Validate-Funde prüfen Querkonsistenz über Dateien hinweg (docs_validate
sammelt beides). Konventions-Warnungen betreffen nur offene Dateien — Archive
sind append-only und werden nie beanstandet. Ein UTF-8-BOM (U+FEFF) am Dateianfang
wird still toleriert (deterministisch gestrippt, T5/9.13) — keine Warnung.
Code | Ebene | Bedeutung |
| Parse | Kein Prioritäts-Suffix im Titel — Priorität aus dem Sektions-Emoji übernommen |
| Parse | Mehrere Prioritäts-Marker im Titel — einer wird erfasst |
| Parse | Unbekanntes Prioritäts-Emoji (z. B. 🟣) — |
| Parse | Item ohne |
| Parse | Item-ID ohne Titel nach dem Trenner |
| Parse | Unbekanntes Status-Icon in der Tabelle — |
| Parse | Tabellenzeile ohne Status-Spalte |
| Validate |
|
| Validate | Item-ID kommt doppelt vor |
| Validate | ID verletzt |
| Validate | Erledigt-Index-Eintrag ohne Archiv-Block |
| Validate | Erledigter Archiv-Block ( |
| Validate | 🔄-Zeile ohne passenden Detail-Block |
| Validate | Detail-Block ohne 🔄-Step (verwaist oder via |
| Validate | Step-Nummer kommt doppelt in der Fortschrittstabelle vor — |
| Validate |
|
| Validate | Root ohne STEPWELL-Projekt (alle vier Dateien fehlen) — genau ein Fund mit Anleitung statt Fehler-Wüste; |
Typischer Workflow (Agent + stepwell)
1. docs_status → Wo stehen wir? Welche Prioritäten sind offen?
2. backlog_list --open → Was ist als nächstes dran? (BINDEND: sequenziell nach Prio)
3. (Arbeit am Code, test-first — Prosa editiert der Agent direkt)
4. progress_plan_phase → neue Phase vorausplanen (Zeilen + Scope-Skelett)
5. progress_update (🔄) → Step begonnen: Tabelle + Detail-Block sauber halten
6. progress_update (✅) → Step fertig; ist die Phase komplett, wandert der Block ins Archiv
7. backlog_add/update → Items format-sicher anlegen/ändern (statt Hand-Edit)
8. archive_item → erledigtes Item verbatim archivieren + Erledigt-Index
9. backlog_remove → obsoletes Item ins Archiv verschieben (ohne Erledigt-Marker)
10. docs_validate → muss clean sein, bevor committed wirdDie PLAYBOOK-Regeln (Sequenz, Test-First, Commit-Diskiplin, Archiv-Muster) stehen
in docs/PLAYBOOK.md; die Review-Checkliste in
docs/LESSONS.md.
Architektur
Entwurfs-Regel (M4/Decision 17): Die Tool-Oberfläche bleibt klein — Tools nur für konkrete Struktur-/Lese-Operationen, keine Guide-/Meta-Tools; Methoden-Wissen lebt in PLAYBOOK.md, SKILL.md und den Resources. Jedes neue Tool (oder neue Parameter-Fläche) begründet den Surface-Zuwachs per Alternativprüfung (Parameter an ein existierendes Tool/Resource statt neues Tool) — dokumentiert wie bei der docs_review-Entscheidung (L5).
packages/
├── core/ stepwell-core — Zero-Dependencies, keine MCP-Abhängigkeit
│ ├── src/backlog.ts BACKLOG-Parser (Sektionen, Item-Blöcke, Erledigt-Index)
│ ├── src/progress.ts PROGRESS-Parser (Tabelle, Detail-Blöcke) + scopeSteps
│ ├── src/archive.ts Archiv-Parser (ArchiveItem = BacklogItem + doneLine)
│ ├── src/project.ts loadProject (4-Datei-Pflicht, lazy + memoized), backlogShow
│ ├── src/status.ts docsStatus (Aggregat)
│ ├── src/validate.ts docsValidate (Konsistenzregeln + Parse-Warnungen)
│ ├── src/mutations.ts plan/apply: archive_item, progress_update, backlog-CRUD, planPhase
│ ├── src/aliases.ts ASCII-Aliase für Prioritäts-Emojis und Status-Icons (CLI)
│ ├── src/diff.ts zeilenbasierter Mini-Diff für die Plan-Vorschau
│ ├── src/profile.ts Locale-Profile: Rollen-Synonyme de/en (Lesen union, Schreiben kanonisch)
│ └── tests/fixtures/ project-a (sauber) + project-b-drift (Fälle D1–D15)
│ + project-d-tablefirst (Tabelle vor Detail-Blöcken),
│ README.md dort = arbeitende Spezifikation
└── mcp/ stepwell — dünne Transport-Schicht über core
├── src/server.ts createDocsServer (alle Tools + Resources)
├── src/tools.ts Tool-Registrierung (JSON-Payloads, isError-Kapselung)
├── src/resources.ts Resource-Templates (percent-encoded Root)
├── src/serve.ts stdio-Einstieg
└── src/cli.ts stepwell-KommandozeileStack: TypeScript (strict,
NodeNext,noUncheckedIndexedAccess,exactOptionalPropertyTypes), npm workspaces, Vitest, MCP-SDK v1.x stabil (^1.30.0) + zod v3. Bewusst gegen Build-/Bundle-Schritte entschieden: Node ≥ 22.18 führt die TS-Source direkt aus (Type-Stripping), Import-Specifiers enden deshalb auf.ts.Datenmodell:
ParseResult<T> = { value, warnings[] },Warning = { code, file, line?, message }— Item-Blöcke tragenspan(Zeilen) undraw(verbatim) als Basis der verbatim-Verschiebung.Tests: 188 Tests, Test-First entwickelt (ROT → GRÜN). Mutationen laufen in Tests ausschließlich gegen Temp-Kopien der Fixtures — die Originale sind read-only und werden per Test abgesichert.
Entwicklung
npm install && npm run typecheck && npm run test # Abnahme vor jedem Abschluss
npx vitest run packages/core # nur core
npx vitest run packages/mcp # nur MCP/CLINeue Features folgen der STEPWELL-Methode: Planen → in PROGRESS.md paketieren →
test-first implementieren → Verifikation → Commit → Status pflegen. Details:
AGENTS.md.