markpact - + GitOps meets AI Agents — all in one README.
AI Cost Tracking
- 🤖 LLM usage: $6.9000 (46 commits)
- 👤 Human dev: ~$2746 (27.5h @ $100/h, 30min dedup)
Generated on 2026-04-23 using openrouter/qwen/qwen3-coder-next
Markpact to minimalny runtime, który pozwala trzymać cały projekt w jednym README.md.
Runtime ignoruje zwykły Markdown, a wykonuje wyłącznie codeblocki markpact:*.
💡 Czym jest Markpact?
Markpact to narzędzie, które zamienia plik README.md w wykonywalny kontrakt projektu. Zamiast utrzymywać osobno dokumentację i kod źródłowy, wszystko znajduje się w jednym miejscu.
Kluczowe możliwości:
| Funkcja | Opis |
|---|---|
| Executable README | Uruchom cały projekt z jednego pliku README.md |
| LLM Generation | Wygeneruj projekt z opisu tekstowego: markpact -p "REST API" |
| Live Demo | Interaktywne demo z generowaniem PDF: python examples/demo_live_markpact.py |
| PDF Generation | Automatyczne tworzenie PDF dokumentacji (7 stron) |
| Multi-language | Python, Node.js, Go, Rust, PHP, TypeScript, React |
| Publishing | Publikuj do PyPI, npm, Docker Hub jedną komendą |
| Docker Sandbox | Uruchom w izolowanym kontenerze: --docker |
| HTTP Testing | Definiuj testy HTTP w markpact:test http |
| Auto-fix | Automatyczne naprawianie błędów runtime |
| Sync & Rollback | Synchronizuj pliki źródłowe z README: markpact sync |
Dla kogo?
- Deweloperzy – szybkie prototypowanie i uruchamianie projektów
- DevOps – CI/CD z README jako single source of truth
- Edukatorzy – interaktywne tutoriale z wykonywalnym kodem
- LLM/AI – generowanie i modyfikacja projektów przez AI
🚀 Szybki start
git clone https://github.com/wronai/markpact.git
# Instalacja
pip install markpact[llm]
# Konfiguracja LLM (wybierz jeden)
markpact config --provider ollama # lokalny
markpact config --provider openrouter --api-key sk-or-v1-xxx # chmura
# Generuj i uruchom jedną komendą!
markpact -p "REST API do zarządzania zadaniami z SQLite" -o todo/README.md --run
markpact -p "URL shortener with FastAPI and SQLite" -o url-test/README.md --run
# Lub z gotowego przykładu
markpact -e todo-api -o todo/README.md --run
🎬 Demo Live - Generowanie z LLM w czasie rzeczywistym
Spróbuj interaktywnego demo, które generuje kompletny projekt z promptu i tworzy PDF dokumentacji:
# Wejdź do katalogu markpact
cd /home/tom/github/wronai/markpact
# Uruchom demo z własnym promptem
python examples/demo_live_markpact.py --prompt "Build a chat API with WebSocket"
# Lub użyj gotowego przykładu
python examples/demo_live_markpact.py --example todo-api
# Lista dostępnych przykładów
python examples/demo_live_markpact.py --list
Co robi demo:
- Generuje kontrakt z LLM (Ollama/OpenRouter/OpenAI)
- Parsuje bloki
markpact:*z wygenerowanego README - Waliduje wszystkie wymagane bloki
- Tworzy PDF z pełną dokumentacją (7 stron)
- Zapisuje wyniki do
generated/live/
Wymagania:
pip install markpact[llm] fpdf2
Przykład wyjścia:
[PASS] LLM wygenerował kontrakt 81.1s, 2177 znaków
[PASS] Znaleziono 4 bloków 0.0ms
[PASS] Zaleznosci: 3 pakietów fastapi, uvicorn, websockets
[PASS] Plik: app/main.py 36 linii
[PASS] PDF zapisany: generated/live/markpact_live_custom.pdf 13 KB, 7 stron
🤖 Generowanie z LLM
Wygeneruj kompletny projekt z opisu tekstowego:
# Lista 16 gotowych przykładów
markpact --list-examples
# Generuj z promptu
markpact -p "URL shortener z FastAPI i SQLite" -o url/README.md
# Generuj i uruchom natychmiast (one-liner)
markpact -p "Chat WebSocket z FastAPI" -o chat/README.md --run
# Uruchom w izolowanym Docker
markpact -p "Blog API z komentarzami" -o blog/README.md --run --docker
Obsługiwane providery: Ollama (lokalny), OpenRouter, OpenAI, Anthropic, Groq
Szczegóły: docs/generator.md
📦 Publikacja do rejestrów
Publikuj artefakty bezpośrednio z README:
# PyPI
markpact README.md --publish --bump patch
# npm
markpact README.md --publish --registry npm
# Docker Hub
markpact README.md --publish --registry docker
# GitHub Container Registry
markpact README.md --publish --registry ghcr
Obsługiwane rejestry: PyPI, npm, Docker Hub, GitHub Packages, GHCR
📓 Konwersja Notebooków
Konwertuj notebooki do formatu markpact:
# Lista obsługiwanych formatów
markpact --list-notebook-formats
# Konwersja Jupyter Notebook
markpact --from-notebook notebook.ipynb -o project/README.md
# Konwersja i uruchomienie
markpact --from-notebook notebook.ipynb -o project/README.md --run
# Podgląd konwersji
markpact --from-notebook notebook.ipynb --convert-only
Obsługiwane formaty:
| Format | Rozszerzenie | Opis |
|---|---|---|
| Jupyter Notebook | .ipynb |
Python, R, Julia |
| R Markdown | .Rmd |
R z markdown |
| Quarto | .qmd |
Wielojęzyczny |
| Databricks | .dib |
Python, Scala, R |
| Zeppelin | .zpln |
Python, Scala, SQL |
📚 Dokumentacja
- Pełna dokumentacja
- Demo Live Guide ⭐ NEW - Interaktywne demo z PDF
- Generowanie z LLM ⭐ NEW
- Kontrakt markpact:*
- CI/CD Integration
- Współpraca z LLM
🎯 Przykłady
| Przykład | Opis | Uruchomienie |
|---|---|---|
| Demo Live | Interaktywne generowanie z LLM + PDF | python examples/demo_live_markpact.py --prompt "Chat API" |
| FastAPI Todo | REST API z bazą danych | markpact examples/fastapi-todo/README.md |
| Flask Blog | Aplikacja webowa z szablonami | markpact examples/flask-blog/README.md |
| CLI Tool | Narzędzie linii poleceń | markpact examples/cli-tool/README.md |
| Streamlit Dashboard | Dashboard danych | markpact examples/streamlit-dashboard/README.md |
| Kivy Mobile | Aplikacja mobilna | markpact examples/kivy-mobile/README.md |
| Electron Desktop | Aplikacja desktopowa | markpact examples/electron-desktop/README.md |
| Markdown Converter | Konwersja zwykłego MD | markpact examples/markdown-converter/sample.md --convert |
| Go HTTP API | REST API w Go | markpact examples/go-http-api/README.md |
| Node Express API | REST API w Node.js | markpact examples/node-express-api/README.md |
| Static Frontend | Statyczny HTML/CSS/JS | markpact examples/static-frontend/README.md |
| Python Typer CLI | CLI w Python (Typer) | markpact examples/python-typer-cli/README.md |
| Rust Axum API | REST API w Rust | markpact examples/rust-axum-api/README.md |
| PHP CLI | CLI w PHP | markpact examples/php-cli/README.md |
| React TypeScript SPA | SPA React + TS | markpact examples/react-typescript-spa/README.md |
| TypeScript Node API | REST API w TS (Node) | markpact examples/typescript-node-api/README.md |
| PyPI Publish | Publikacja do PyPI | markpact examples/pypi-publish/README.md --publish |
| npm Publish | Publikacja do npm | markpact examples/npm-publish/README.md --publish |
| Docker Publish | Publikacja do Docker | markpact examples/docker-publish/README.md --publish |
| Notebook Converter | Konwersja .ipynb do markpact | markpact --from-notebook examples/notebook-converter/sample.ipynb --convert-only |
🧪 Testowanie przykładów
Uruchom automatyczne testy wszystkich przykładów:
# Dry-run (tylko parsowanie)
./scripts/test_examples.sh
# Pełne uruchomienie
./scripts/test_examples.sh --run
# Verbose output
./scripts/test_examples.sh --verbose
🔄 Sync — synchronizacja plików z README
Komenda sync aktualizuje bloki markpact:file w README.md na podstawie rzeczywistych plików w katalogu źródłowym (np. sandbox/). Odwrotność markpact pack.
# Synchronizacja (auto-detect sandbox/ obok README)
markpact sync README.md
# Z własnym katalogiem źródłowym
markpact sync README.md --source ./my-project
# Podgląd zmian bez zapisu
markpact sync README.md --dry-run --diff
# CI check — exit 1 jeśli pliki nie są zsynchronizowane
markpact sync README.md --check
# Lista śledzonych plików
markpact sync README.md --list
# Pliki w katalogu źródłowym nie śledzone w README
markpact sync README.md --missing
# Wyklucz wrażliwe pliki
markpact sync README.md --exclude .env --exclude .env.prod
Rollback — przywracanie poprzedniej wersji
Każdy sync automatycznie tworzy backup README w .markpact/ (max 10).
# Przywróć ostatni backup
markpact sync README.md --rollback
# Lista dostępnych backupów
markpact sync README.md --backups
# Przywróć konkretny backup
markpact sync README.md --rollback-to .markpact/README.md.bak.20240301_143022
Opcje markpact sync
| Flaga | Opis |
|---|---|
-n, --dry-run |
Podgląd bez zapisu |
-d, --diff |
Pokaż unified diff |
-c, --check |
CI: exit 1 jeśli out-of-sync |
-l, --list |
Lista śledzonych plików |
-m, --missing |
Pliki źródłowe bez bloku w README |
--exclude PATH |
Wyklucz plik (powtarzalne) |
--rollback |
Przywróć z ostatniego backup |
--rollback-to FILE |
Przywróć z konkretnego backup |
--backups |
Lista dostępnych backupów |
-s, --source DIR |
Katalog źródłowy (domyślnie: sandbox/) |
🔄 Konwersja zwykłego Markdown
Markpact może automatycznie konwertować zwykłe pliki Markdown (bez tagów markpact:*) do formatu wykonywalnego:
# Podgląd konwersji
markpact README.md --convert-only
# Konwersja i uruchomienie
markpact README.md --convert
# Auto-detekcja (konwertuj jeśli brak markpact blocks)
markpact README.md --auto
# Zapisz skonwertowany plik
markpact README.md --convert-only --save-converted output.md
Konwerter analizuje code blocks i na podstawie heurystyk wykrywa:
- Zależności →
markpact:deps(pakiety Python/Node) - Pliki źródłowe →
markpact:file(importy, klasy, funkcje) - Komendy →
markpact:run(python, uvicorn, npm, etc.)
1️⃣ Cel projektu
- Jedno README jako źródło prawdy
- Możliwość uruchomienia projektu bez ręcznego tworzenia struktury plików
- Automatyzacja Bootstrap tworzy pliki w sandboxie, instaluje zależności i uruchamia komendę startową.
2️⃣ Kontrakt README (codeblocki markpact:*)
markpact:bootstrap <lang>Dokładnie jeden bootstrap na README. Odpowiada za parsowanie codeblocków i uruchomienie.markpact:deps <scope>Lista zależności dla danego scope (np.python).markpact:file <lang> path=...Zapisuje plik do sandboxu pod ścieżkąpath=....markpact:run <lang>Jedna komenda uruchomieniowa wykonywana w sandboxie.
#!/usr/bin/env python3
"""MARKPACT v0.1 – Executable Markdown Runtime"""
import os, re, subprocess, sys
from pathlib import Path
README = Path(sys.argv[1] if len(sys.argv) > 1 else "README.md")
SANDBOX = Path(os.environ.get("MARKPACT_SANDBOX", "./sandbox"))
SANDBOX.mkdir(parents=True, exist_ok=True)
RE = re.compile(r"^```(?P<lang>\w+)\s+markpact:(?P<kind>\w+)(?:\s+(?P<meta>[^\n]+))?\n(?P<body>.*?)\n^```[ \t]*$", re.DOTALL | re.MULTILINE)
def run(cmd):
print(f"[markpact] RUN: {cmd}")
env = os.environ.copy()
venv = SANDBOX / ".venv" / "bin"
if venv.exists():
env.update(VIRTUAL_ENV=str(venv.parent), PATH=f"{venv}:{env.get('PATH','')}")
subprocess.check_call(cmd, shell=True, cwd=SANDBOX, env=env)
def main():
deps, run_cmd = [], None
for m in RE.finditer(README.read_text()):
kind, meta, body = m.group("kind"), (m.group("meta") or "").strip(), m.group("body").strip()
if kind == "file":
p = re.search(r"\bpath=(\S+)", meta)
if not p: raise ValueError(f"markpact:file requires path=..., got {meta!r}")
f = SANDBOX / p[1]
f.parent.mkdir(parents=True, exist_ok=True)
f.write_text(body)
print(f"[markpact] wrote {f}")
elif kind == "deps" and meta == "python":
deps.extend(line.strip() for line in body.splitlines() if line.strip())
elif kind == "run":
run_cmd = body
if deps:
venv_pip = SANDBOX / ".venv" / "bin" / "pip"
if os.environ.get("MARKPACT_NO_VENV") != "1" and not venv_pip.exists():
run(f"{sys.executable} -m venv .venv")
(SANDBOX / "requirements.txt").write_text("\n".join(deps))
run(f"{'.venv/bin/pip' if venv_pip.exists() else 'pip'} install -r requirements.txt")
if run_cmd:
run(run_cmd)
else:
print("[markpact] No run command defined")
if __name__ == "__main__":
main()
3️⃣ Instalacja
Opcja A: Pakiet pip (zalecane)
# Podstawowa instalacja
pip install markpact
# Z LLM i PDF generation (dla demo)
pip install markpact[llm] fpdf2
# Z integracją fixop (auto-fix, diagnostyka portów)
pip install markpact[ops]
Użycie:
markpact README.md # uruchom projekt
markpact README.md --dry-run # podgląd bez wykonywania
markpact README.md -s ./my-sandbox # własny katalog sandbox
# Demo live z LLM
python examples/demo_live_markpact.py --prompt "Twój prompt"
Opcja B: Instalacja lokalna (dev)
git clone https://github.com/wronai/markpact.git
cd markpact
make install # lub: pip install -e .
Opcja C: Ekstrakcja bootstrapu (zero dependencies)
-
Ekstrakcja bootstrapu do pliku
Ten wariant jest odporny na przypadek, gdy w samym bootstrapie występują znaki ``` (np. w regexie):
sed -n '/^```markpact:bootstrap/,/^```[[:space:]]*$/p' README.md | sed '1d;$d' > markpact.py
-
Uruchomienie
python3 markpact.py -
Konfiguracja (env vars)
MARKPACT_PORT=8001 MARKPACT_SANDBOX=./.markpact-sandbox python3 markpact.py
4️⃣ Sandbox i środowisko
MARKPACT_SANDBOXZmienia katalog sandboxu (domyślnie./sandbox).MARKPACT_NO_VENV=1Wyłącza tworzenie.venvw sandboxie (przydatne, jeśli CI/Conda zarządza środowiskiem).- Port zajęty (
[Errno 98] address already in use) UstawMARKPACT_PORTna inny port lub zatrzymaj proces, który używa8000.
5️⃣ Dependency management
- Python
Bootstrap zbiera
markpact:deps python, zapisujerequirements.txtw sandboxie i instaluje zależności.
6️⃣ Uruchamianie i workflow
- Wejście
python3 markpact.py [README.md] - Kolejność
Bootstrap parsuje wszystkie codeblocki, zapisuje pliki i dopiero na końcu uruchamia
markpact:run.
6.1 Konwencje i format metadanych
-
Nagłówek codeblocka
```<lang> markpact:<kind> <meta>Minimalnie wymagane jest
markpact:<kind>.langjest opcjonalny i pełni rolę informacyjną (bootstrap może go ignorować). -
Metadane Dla
markpact:filewymagane jestpath=.... Metadane mogą zawierać dodatkowe tokeny (np. w przyszłościmode=...,chmod=...).
6.2 CI/CD
-
Rekomendacja Uruchamiaj bootstrap w czystym środowisku (np. job CI) i ustaw sandbox na katalog roboczy joba.
-
Przykład (shell)
export MARKPACT_SANDBOX=./.markpact-sandbox export MARKPACT_PORT=8001 python3 markpact.py README.md
-
Wskazówki
- Deterministyczność
Pinuj wersje w
markpact:deps(np.fastapi==...). - Bezpieczeństwo
Traktuj
markpact:runjak skrypt uruchomieniowy repo: w CI odpalaj tylko zaufane README. - Cache
Jeśli CI wspiera cache, cache’uj katalog
MARKPACT_SANDBOX/.venv.
- Deterministyczność
Pinuj wersje w
6.3 Współpraca z LLM
- Zasada
LLM może generować/edytować projekt poprzez modyfikacje README (codeblocki
markpact:file,markpact:deps,markpact:run). - Oczekiwania
markpact:filezawsze zawiera pełną zawartość pliku.- Każda zmiana zależności idzie przez
markpact:deps. - Jedna komenda startowa w
markpact:run.
7️⃣ Najlepsze praktyki
- Bootstrap jako pierwszy fenced codeblock w README
- Każdy plik w osobnym
markpact:file - Zależności tylko w
markpact:deps - Jedna komenda startowa w
markpact:run - Ekstrakcja bootstrapu
Nie używaj zakresu
/,/```/(bomoże wystąpić w treści, np. w regexie). Używaj `^$` na końcu.
Plik konfiguracyjny (~/.markpact/.env)
# Markpact LLM Configuration
MARKPACT_MODEL="openrouter/nvidia/nemotron-3-nano-30b-a3b:free"
MARKPACT_API_BASE="https://openrouter.ai/api/v1"
MARKPACT_API_KEY="sk-or-v1-xxxxx"
MARKPACT_TEMPERATURE="0.7"
MARKPACT_MAX_TOKENS="4096"
Obsługiwani providerzy LLM
Ollama (lokalny, domyślny)
markpact config --provider ollama
markpact config --model ollama/qwen2.5-coder:14b
markpact -p "REST API dla książek"
OpenRouter (darmowe modele!)
markpact config --provider openrouter --api-key sk-or-v1-xxxxx
markpact config --model openrouter/nvidia/nemotron-3-nano-30b-a3b:free
markpact -p "REST API dla książek"
Działający przykład (FastAPI)
1️⃣ Dependencies
markpact:deps python
fastapi
uvicorn
2️⃣ Application Files
markpact:file python path=app/main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello from Executable Markdown"}
3️⃣ Run Command
markpact:run python
uvicorn app.main:app --host 0.0.0.0 --port ${MARKPACT_PORT:-8088}
🏗️ Architektura modułów
Markpact jest podzielony na małe, niezależne moduły:
src/markpact/
├── cli/ # CLI dispatch + subcommands
│ ├── __init__.py # main() — thin dispatch (CC≤5)
│ ├── sync_cmd.py # markpact sync
│ ├── pack_cmd.py # markpact pack
│ ├── config_cmd.py # markpact config
│ ├── publish_cmd.py # --publish mode
│ ├── run_cmd.py # normal run, Docker, test
│ ├── convert_cmd.py # notebook/markdown conversion
│ └── helpers.py # shared CLI utilities
├── publish/ # Multi-registry publisher
│ ├── models.py # PublishConfig, PublishResult
│ ├── helpers.py # inference, interactive config
│ ├── version.py # semver bump, extract, update
│ ├── llm_config.py # LLM-based config generation
│ ├── pypi.py # PyPI publisher
│ ├── npm.py # npm publisher
│ ├── docker_pub.py # Docker publisher
│ ├── github.py # GitHub Packages publisher
│ └── main.py # parse_publish_block, dispatch
├── auto_fix.py # Runtime error auto-fix (fixop integration)
├── parser.py # markpact:* block parser
├── syncer.py # README ↔ source sync
├── packer.py # Directory → README packer
├── sandbox.py # Isolated sandbox management
├── runner.py # Command execution
└── generator.py # LLM contract generation
Opcjonalne zależności
| Extra | Pakiet | Opis |
|---|---|---|
[llm] |
litellm | Generowanie kontraktów przez LLM |
[ops] |
fixop | Diagnostyka portów, klasyfikacja błędów |
[dev] |
pytest, ruff, build, twine | Narzędzia deweloperskie |
Test Performance
- Markpact tests: ~6s for 255 tests (fast)
- Test suite: Uses pytest with coverage reporting
Recent Fixes
- v0.1.36: Fixed pip fallback bug in
runner.py- now always uses.venv/bin/pipafter venv creation to avoid PEP 668 errors on externally-managed Python environments - v0.1.30: Major refactoring - cli.py → cli/ package, publisher.py → publish/ package, syncer.py refactoring for better maintainability
License
Licensed under Apache-2.0.
Author
Tom Sapletta
Metadata
Release files for markpact 0.1.42
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| markpact-0.1.42.tar.gz | 117.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| markpact-0.1.42-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 232.0 kB
Release files / markpact-0.1.42.tar.gz
| Download URL | markpact-0.1.42.tar.gz |
|---|---|
| Size | 117.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b82891e84538cabc74da15593763374c6f462b8c7ae69727d5c8c716f00a68d8
|
|
BLAKE2b-256 checksum How to use checksums |
eb332fb2832c119a6940a5566139ae4d81afd797b0f85f3b5953d11e3d741999
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / markpact-0.1.42-py3-none-any.whl
| Download URL | markpact-0.1.42-py3-none-any.whl |
|---|---|
| Size | 114.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c27f09761b58d8b4004ee3e4a9b095dfd4d21f7b3c057273326fc26688f4aa67
|
|
BLAKE2b-256 checksum How to use checksums |
d041125f1705cf49fdcb5f2800a4d7cf11bdc9f17f7b8719c6fc15a59fc325ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|