marsdawn für Agenten
Eine Referenz für KI-Agenten und Skripte, die das Befehlszeilenwerkzeug marsdawn aufrufen. Jedes Beispiel auf dieser Seite wurde mit dem aus dem aktuellen Quellcode gebauten Werkzeug ausgeführt.
Um eine Markdown-Datei in ein PDF umzuwandeln, führe marsdawn export notes.md --json aus und lies ein JSON-Objekt von stdout. Mermaid-Diagramme und hervorgehobener Code werden genauso gerendert wie in der MarsDawn-App. export braucht die App nicht, open schon.
Was es tut
exportrendert eine Markdown-Datei mit demselben Exporter wie die MarsDawn-App zu einem PDF mit Seitenumbrüchen. Es öffnet sich kein Fenster.openöffnet eine oder mehrere Markdown-Dateien in der MarsDawn-App, damit ein Mensch sie prüfen kann. Es kann für jede Datei die Zeile angeben, bei der sie aufgehen soll, und einen Ordner in der Seitenleiste des Fensters anzeigen.
Was es nicht tut
- Es liest kein Markdown von stdin. Übergib einen Dateipfad.
- Es schreibt das PDF nicht nach stdout. Das PDF landet immer in einer Datei; stdout enthält nur das Ergebnis.
- Es ersetzt keine vorhandene Datei, außer du übergibst
--force. - Es lädt keine Bilder aus dem Web, außer du übergibst
--allow-remote-images, und dann nur über https. openfunktioniert nicht ohne installierte MarsDawn-App und endet mit Code 3.exportbraucht die App nicht. Die App gibt es im Mac App Store.- MarsDawn 1.0 öffnet die Datei in der Zeile, die
openangibt. - Es läuft nur unter macOS.
export
marsdawn export notes.md --json
Schreibt notes.pdf neben notes.md. Optionen:
-o, --output <path>: wohin das PDF geschrieben wird. Standard ist der Eingabepfad mit der Endung.pdf.--theme <dawn|classic|modern|vivid>: die helle Farbpalette des Themas. Standard ist$MARSDAWN_THEME, sonstdawn.--paper <a4|letter>: Papierformat. Standard ista4.--allow-remote-images: lädt beim Rendern https-Bilder aus dem Web.--force: ersetzt die Ausgabedatei, falls sie existiert.--json: gibt statt Text ein JSON-Objekt auf stdout aus.
marsdawn export notes.md -o out.pdf --theme classic --paper letter --force --json
Erfolg, Exit-Code 0:
{"diagramErrors":[],"ok":true,"output":"/path/to/out.pdf","pages":1,"paper":"letter","theme":"classic"}
output: absoluter Pfad des geschriebenen PDFs.pages: Anzahl der Seiten.themeundpaper: die verwendeten Werte.diagramErrors: eine Meldung pro Mermaid-Diagramm, das nicht gerendert werden konnte. Das PDF wird trotzdem geschrieben.
open
marsdawn open notes.md --json
marsdawn open notes.md:120 --json
marsdawn open notes.md --line 120 --json
marsdawn open . --json
marsdawn open notes.md --folder . --background --json
path:linegibt die Zeile an, bei der die Datei aufgehen soll. Eine Spalte dahinter, wie innotes.md:120:8, wird ignoriert. Ein Argument, das eine existierende Datei benennt, gilt immer als ganzer Dateiname, eine Datei namensweird:12öffnet sich also als sie selbst.--line <n>gibt die Zeile für eine einzelne Datei an, auch für einen Pfad, der selbst auf Doppelpunkt und Ziffern endet. Es braucht genau eine Datei.- Zeilen reichen von 1 bis 999999999. Alles andere ist ein Bedienungsfehler.
- Zeilen kamen mit marsdawn 0.3.0 hinzu. MarsDawn 1.0 öffnet die Datei in dieser Zeile.
- Ein Ordner als Argument öffnet sich in der Seitenleiste des Fensters statt als Dokument,
marsdawn open .zeigt also den aktuellen Ordner;--folder <path>tut dasselbe zusätzlich zu Dateien. Die Seitenleiste eines Fensters zeigt einen Ordner: Zwei anzugeben ist ein Bedienungsfehler, ebenso--folderzweimal, selbst für denselben Ordner; derselbe Ordner noch einmal als Argument zählt einmal.--linemit einem Ordner ist ein Bedienungsfehler, da ein Ordner keine Zeile hat. Es gibt kein-a: Wer es übergibt, bekommt einen Bedienungsfehler mit Verweis auf--folder. --backgroundöffnet, ohne MarsDawn in den Vordergrund zu holen, für einen Agenten, der Dateien öffnet, während der Mensch woanders arbeitet. Das JSON ist in beiden Fällen gleich.- Ordner und
--backgroundkamen mit marsdawn 0.5.1 hinzu.
Erfolg, Exit-Code 0:
{"app":"/Applications/MarsDawn.app","ok":true,"opened":[{"line":120,"path":"/path/to/notes.md"}]}
opened: ein Objekt pro Datei, in der angegebenen Reihenfolge.pathist der absolute Pfad der Datei;lineerscheint nur, wenn eine Zeile angefragt wurde.app: Pfad der MarsDawn-App, die sie geöffnet hat.
Mit einem Ordner (marsdawn 0.5.1 und neuer), Exit-Code 0:
{"app":"/Applications/MarsDawn.app","folder":{"path":"/path/to/project","requested":true},"ok":true,"opened":[{"path":"/path/to/project/notes.md"}]}
folder: nur vorhanden, wenn ein Ordner angegeben wurde.pathist sein absoluter Pfad.requestedist immertrue: marsdawn hat MarsDawn gebeten, den Ordner anzuzeigen, und kann nicht wissen, ob die Seitenleiste ihn zeigt, denn die App fragt den Menschen womöglich erst nach Zugriff. Melde es als angefragt, nicht als erledigt.- Mit
--waitüber 0 und MarsDawn 1.0.2 oder neuer enthältfoldernach dem Warten auchstatus:attached,needsUser,declined,failed,attachedDifferentFolder,full,unavailableoderunknown. Nur zusammen mitneedsUserenthält eswaitingFor:confirmationoderfolderChoice. Ohne--waitoder mit einer App ohne Rückmeldung bleibtfolderbei{"path": …, "requested": true}. Ein--waitaußerhalb von 0 bis 30 endet mit Code 64 underror: "wait_out_of_range". (marsdawn 0.5.3 und neuer.) openedist leer, wenn nur ein Ordner angegeben wurde.
marsdawn 0.2.x gab opened als Liste von Pfad-Strings aus. Prüfe marsdawn --version, wenn du beides verarbeiten musst.
Dateien öffnen, während Claude Code sie bearbeitet
Ein optionaler Claude Code Hook: Nachdem Claude eine Markdown-Datei geschrieben oder bearbeitet hat, öffnet er diese Datei im Hintergrund in MarsDawn, einmal pro Datei und Sitzung. Er ist aus, bis du ihn hinzufügst, Projekt für Projekt, denn ein Fenster, um das du nicht gebeten hast, kostet Aufmerksamkeit. Er führt einen Shell-Befehl aus und kostet keine Modell-Tokens.
Er braucht marsdawn 0.5.1 oder neuer, wegen --background, und die MarsDawn-App.
Sichere das als .claude/hooks/marsdawn-open.sh in deinem Projekt und mach es mit chmod +x ausführbar:
#!/bin/sh
# Claude Code PostToolUse hook: open a Markdown file Claude just wrote or edited in MarsDawn,
# in the background, once per file per session. Never blocks Claude: every path exits 0.
input=$(cat)
file=$(printf '%s' "$input" | /usr/bin/jq -r '.tool_input.file_path // empty' 2>/dev/null)
session=$(printf '%s' "$input" | /usr/bin/jq -r '.session_id // "unknown"' 2>/dev/null)
case "$file" in
*.md|*.markdown) ;;
*) exit 0 ;;
esac
[ -f "$file" ] || exit 0
# A hook runs with Claude Code's PATH, which may not include Homebrew's.
marsdawn=$(command -v marsdawn || { [ -x /opt/homebrew/bin/marsdawn ] && echo /opt/homebrew/bin/marsdawn; }) || exit 0
[ -n "$marsdawn" ] || exit 0
# One list per session, so a file opens once however often Claude edits it.
seen="${TMPDIR:-/tmp}/marsdawn-hook/$session"
mkdir -p "$(dirname "$seen")"
grep -qxF "$file" "$seen" 2>/dev/null && exit 0
echo "$file" >> "$seen"
"$marsdawn" open --background "$file" >/dev/null 2>&1 || true
exit 0
Füge den Hook dann zu .claude/settings.json im Projekt hinzu, oder zu .claude/settings.local.json, wenn er nur für dich gelten soll:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/marsdawn-open.sh" }
]
}
]
}
}
- Er läuft nach Claudes Write- und Edit-Werkzeugen. Dateien, die nicht auf
.mdoder.markdownenden, bleiben unberührt. - Jede Datei öffnet sich einmal pro Claude-Code-Sitzung, egal wie oft Claude sie bearbeitet. Die Liste liegt in
$TMPDIR/marsdawn-hook/, eine Datei pro Sitzung, eine neue Sitzung öffnet die Datei also erneut. --backgroundhält MarsDawn im Hintergrund: Das Fenster, in dem du gearbeitet hast, behält den Fokus.- Er kommt Claude nie in die Quere. Jeder Pfad endet mit 0, und wenn marsdawn oder die MarsDawn-App nicht installiert ist, passiert nichts.
- Er liest die Eingabe des Hooks mit
/usr/bin/jq, das bei macOS 26 dabei ist, der Version, die die MarsDawn-App braucht. - Zum Abschalten entferne den Eintrag aus der Einstellungsdatei.
Fehler
Mit --json gibt ein Fehler ein JSON-Objekt auf stdout aus und endet mit seinem Code:
{"error":"output_exists","message":"/path/to/notes.pdf already exists. Pass --force to replace it.","ok":false}
2,input_not_found: Die Eingabe existiert nicht, ist ein Ordner oder ist kein UTF-8-Text; oder ein--folder-Pfad existiert nicht oder ist kein Ordner.3,app_not_installed: MarsDawn ist nicht installiert. Nuropenliefert das.4,output_exists: Die Ausgabedatei existiert. Übergib--force.5,export_failed: Der Export selbst ist fehlgeschlagen.6,app_cannot_open_folders: Dieses MarsDawn kann keinen Ordner anzeigen, also wurde nichts geöffnet. Nuropenliefert das.64: Bedienungsfehler, etwa eine unbekannte Option, ein ungültiger Wert, eine Zeile außerhalb des Bereichs,--linemit mehr als einer Datei oder mit einem Ordner, mehr als ein Ordner oder-a. Dieser wird als Text auf stderr ausgegeben, auch mit--json.
JSON-Schemas
JSON Schema (Draft 2020-12) für jedes --json-Ergebnis:
- export.v1.json: export erfolgreich
- open.v4.json: open erfolgreich, marsdawn 0.5.3 und neuer, mit
statusundwaitingFordes Ordners - open.v3.json: open erfolgreich, marsdawn 0.5.1 und 0.5.2, einschließlich eines in der Seitenleiste angezeigten Ordners
- error.v3.json: Fehler, alle Befehle, marsdawn 0.7.1 und neuer, mit
input_too_large(Code 5) undskill_install_failed(Code 7) - error.v2.json: Fehler, beide Befehle, marsdawn 0.5.2 bis 0.7.0
- open.v2.json: open erfolgreich, marsdawn 0.3.0 bis 0.5.0
- open.v1.json: open erfolgreich, marsdawn 0.2.x, wo
openedeine Liste von Pfaden war - error.v1.json: Fehler, beide Befehle, marsdawn 0.5.1 und älter
Umgebungsvariablen
MARSDAWN_THEME: das Thema, dasexportverwendet, wenn--themenicht übergeben wird. Ein unbekannter Wert fällt ohne Fehler aufdawnzurück.
Voraussetzungen
- Das Werkzeug läuft unter macOS 15 oder neuer. Auf Apple Chips installiert Homebrew eine fertig gebaute Bottle, und sonst wird nichts gebraucht. Selbst bauen, auf einem Intel-Mac oder aus dem Quellcode, erfordert Swift 6.2 oder neuer, das mit Xcode 26 oder neuer kommt.
- Die MarsDawn-App erfordert macOS 26 oder neuer.
Installieren
Mit Homebrew. Auf Apple Chips installiert es in Sekunden eine fertig gebaute Bottle, ganz ohne Xcode. Auf einem Intel-Mac kompiliert es marsdawn aus dem Quellcode, was ein paar Minuten dauert und Xcode 26 oder neuer erfordert.
brew tap redtear1115/tap && brew install marsdawn
marsdawn --version
Oder bau es aus dem Quellcode. Der erste Build lädt Abhängigkeiten und kompiliert, was ebenfalls ein paar Minuten dauert.
git clone https://github.com/redtear1115/mars-dawn-kit.git
cd mars-dawn-kit
swift build -c release --product marsdawn
.build/release/marsdawn export notes.md --json
marsdawn --version gibt die Versionsnummer aus, etwa 0.3.0, und endet mit Code 0.
Weiter
- Ein Skill in einer Datei für Agenten, die Anweisungen lesen statt eine Shell zu benutzen: der marsdawn-Skill.
- Ein MCP-Server, der genau dieses
exportumschließt: marsdawn-mcp. - Warum dieses JSON-Ergebnis für den eigenen Kontext eines Agenten günstig bleibt: Token-sparsames Prüfen.
- Ein MarsDawn-Thema mit einem Agenten erstellen: Mit deinem Agenten ein Thema erstellen.