Skip to content

@roasted/cli

Vollständige CLI-Referenz

Ein nicht-interaktives Jobsuche-Harness für Menschen und Agenten. Beginne mit einem Quell-Lebenslauf, erstelle für jeden Job ein maßgeschneidertes Kit, rendere das PDF und erfasse die Bewerbung.

Installieren und starten

Installiere das globale Paket und folge dem goldenen Pfad unten. Die ausführbare Datei ist roasted. Sie enthält die Produktions-Verbindungseinstellungen, sodass keine Umgebungseinrichtung erforderlich ist.

Terminal
npm i -g @roasted/cli
roasted login
roasted cv push ./resume.yaml --name "Backend Engineer"
roasted apply plan
roasted apply create --cv "Backend Engineer" --jd-file ./jd.txt
roasted apply pdf <applyKitId> --out resume.pdf
roasted app add --from-kit <applyKitId>

Agenten-Orientierung

Jeder Befehl akzeptiert --json, jede Eingabe kann über Flags oder stdin erfolgen, und nach dem Aufruf gibt es keine Eingabeaufforderungen. Agenten sollten stdout parsen und anhand stabiler Fehler-Codes verzweigen statt anhand des Nachrichtentexts.

  • Erfolg endet mit 0. Jeder Fehler endet mit 1 und gibt im JSON-Modus ein Fehlerobjekt zurück.
  • apply create --no-wait gibt die Bewerbungs-Kit-ID sofort für Fan-out und späteres Polling zurück.
  • apply create --watch streamt eine NDJSON-Zeile pro Phase vor dem Endergebnis.
  • ROASTED_API_KEY überschreibt gespeicherte Profile für kurzlebige Headless-Läufe.
  • --profile oder ROASTED_PROFILE wählt ein benanntes Konto, ohne den globalen Zustand zu wechseln.

Authentifizierung und Profile

Der Browser-Login nutzt PKCE. Sitzungen liegen in ~/.roasted/profiles.json mit Berechtigungen nur für den Eigentümer, wo unterstützt. Die Auswahlreihenfolge ist ROASTED_API_KEY, --profile, ROASTED_PROFILE, dann das aktive Profil. OAuth-Sitzungen werden automatisch erneuert. API-Schlüssel-Profile tauschen ihren gespeicherten Schlüssel erneut aus, wenn eine Sitzung abläuft.

Terminal
roasted login --profile primary
roasted login --profile second --api-key -
roasted accounts
roasted switch second
roasted cv list --profile primary

API-Schlüssel

Persönliche Schlüssel beginnen mit rmt_pat_ und werden einmal angezeigt. Nur ihr Hash wird vom Server gespeichert. Nutze --api-key -, um einen Schlüssel aus stdin zu lesen und ihn aus der Shell-Historie herauszuhalten.

Terminal
roasted keys create ci-runner --ttl never
roasted login --api-key rmt_pat_...
ROASTED_API_KEY=rmt_pat_... roasted cv list

Befehlsreferenz

Auth und Konten

BefehlZweck
roasted login [--api-key <key|->]Melde dich über Browser-PKCE oder einen API-Schlüssel an.
roasted accountsListe Profile auf und zeige das aktive an.
roasted switch <name>Mache ein benanntes Profil aktiv.
roasted whoamiZeige die aktuelle Identität, Rolle, den Empfehlungscode und das Profil an.
roasted logout [--all]Entferne das ausgewählte Profil oder alle Profile.
roasted keys create <name> [--ttl <ttl>]Erstelle einen persönlichen API-Schlüssel mit einer Gültigkeit von 30d, 90d, 1y oder never.
roasted keys listListe Schlüssel mit Status und letzter Nutzung auf.
roasted keys revoke <id|name>Widerrufe einen Schlüssel per ID oder Namen.

Lebensläufe

BefehlZweck
roasted cv listListe Konto-Lebensläufe auf, neueste zuerst.
roasted cv search <query>Filtere Lebensläufe nach Namen.
roasted cv pull <id|name> [--out file]Lade Lebenslauf-YAML nach stdout oder in eine Datei herunter.
roasted cv push <file> [--id <id>] [--name <name>]Erstelle oder aktualisiere einen Lebenslauf aus validiertem YAML oder JSON.

Bewerbungs-Kits

BefehlZweck
roasted apply planZeige den Plan, den Credit-Stand und die Kit-Kosten an.
roasted apply create --cv <id|name>Generiere einen maßgeschneiderten Lebenslauf und ein Anschreiben. Dies verbraucht Credits.
roasted apply listListe Bewerbungs-Kits auf, neueste zuerst.
roasted apply get <id>Lies Status und Ergebnisse. Füge --pages hinzu, um Seiten zu rendern und zu zählen.
roasted apply cv <kitId> [--out file]Lade das maßgeschneiderte Lebenslauf-YAML herunter.
roasted apply push <kitId> <file.yaml>Validiere und lade einen von Hand bearbeiteten maßgeschneiderten Lebenslauf hoch.
roasted apply pdf <id>Rendere die Serverkopie des maßgeschneiderten Lebenslaufs lokal.
roasted apply shrink <id>Passe den maßgeschneiderten Lebenslauf auf eine Seite an. Dies kann einen Credit verbrauchen.

Bewerbungs-Tracker

BefehlZweck
roasted app list [--status <status>]Liste Bewerbungen auf, optional gefiltert nach Status.
roasted app get <id>Lies einen vollständigen Bewerbungseintrag.
roasted app addErstelle eine Bewerbung manuell oder aus einem fertigen Bewerbungs-Kit.
roasted app status <id> <status>Bewege den Status und setze optional ein abgeschlossenes Ergebnis oder eine Notiz.
roasted app note <id> <text>Setze Notizen. Ein leerer Wert löscht sie.
roasted app rm <id>Lösche eine Bewerbung.

Bewerbungs-Kit-Ablauf

Der create-Befehl wartet standardmäßig, dann gibt er das Ergebnis und die Dashboard-URL aus. Nutze get für günstiges Polling und füge --pages nur hinzu, wenn die Seitenzahl benötigt wird. Lebenslauf-Referenzen werden über die exakte ID aufgelöst, dann über eine eindeutige, groß-/kleinschreibungsunabhängige Namensübereinstimmung.

Terminal
roasted cv list
roasted apply plan
roasted apply create --cv "Backend Engineer" --jd-file ./jd.txt \
  --intensity smart --tone professional --length concise
roasted apply get <id> --pages --json
roasted apply cv <id> --out tailored.yaml
roasted apply push <id> tailored.yaml
roasted apply pdf <id> --out resume.pdf
roasted apply shrink <id>

Stellenbeschreibung und Gestaltungs-Flags

Gib genau eines von --jd-file, --jd oder --jd-stdin an. Text kürzer als 50 Zeichen wird abgelehnt. Gestalte das Ergebnis mit intensity safe|smart|bold, tone auto|professional|confident|conversational, length concise|standard|detailed, formality formal|neutral|casual, Sprach- und Anweisungs-Flags, --premium und dem Anschreiben-Umschalter. Ungültige Werte schlagen fehl, bevor Credits verbraucht werden.

Den maßgeschneiderten Lebenslauf sicher bearbeiten

Lade mit apply cv herunter, bearbeite lokal, dann lade mit apply push vor dem Rendern hoch. Die Serverkopie ist maßgeblich. Wenn du das Push überspringst, rendert apply pdf die alte Serverversion erneut und ignoriert lokale Änderungen.

PDF und Einseitigkeit-Anpassung

apply pdf nutzt die lokale typst-Binärdatei. Ohne sie endet der Befehl erfolgreich mit einem Dashboard-Link und einem Installationshinweis. apply shrink prüft die Seitenzahl, wenn ein Renderer verfügbar ist, stoppt ohne Verbrauch, wenn der Lebenslauf bereits passt, und speichert das überarbeitete YAML zurück in das Kit.

Was Geld kostet

  • Kostenlos: Login, Konto- und Schlüsselverwaltung, Lebenslauf-Befehle, Planprüfungen und Tracker-Lesevorgänge.
  • Hunter Pass plus Credits: apply create und apply shrink. Eine Vorabprüfung lehnt kostenlose Pläne oder unzureichende Guthaben vor der Generierung ab.
  • Hunter Pass: das Erstellen von Tracker-Einträgen, einschließlich Einträgen, die aus einem Bewerbungs-Kit gebrückt wurden. Status, Notizen, Löschung und Lesevorgänge sind nicht eingeschränkt.
  • Generierungsfehler werden vom Backend erstattet. Die CLI verändert Guthaben niemals selbst.

End-to-End-Playbooks

Batch-Pipeline

Pushe einen Quell-Lebenslauf, starte ein Kit pro gespeicherter Stellenbeschreibung ohne zu warten, polle jede ID, rendere die PDFs und erfasse Bewerbungen, die tatsächlich eingereicht wurden.

Shell
roasted cv push ./canon-resume.yaml --name "Backend Engineer" --json
CV=$(roasted cv list --json | jq -r '.cvs[] | select(.name=="Backend Engineer") | .id')
for jd in jds/*.txt; do
  roasted apply create --cv "$CV" --jd-file "$jd" --no-wait --json
done > kits.ndjson
jq -r '.applyKitId' kits.ndjson | while read -r id; do
  while :; do
    kit=$(roasted apply get "$id" --json) || { printf 'Retrying kit %s
' "$id" >&2; sleep 2; continue; }
    status=$(printf '%s' "$kit" | jq -r '.status')
    case "$status" in
      ready) break ;;
      generating) sleep 2 ;;
      *) printf 'Kit %s stopped with status: %s
' "$id" "$status" >&2; continue 2 ;;
    esac
  done
  roasted apply pdf "$id" --out "out/$id.pdf" --json
  roasted app add --from-kit "$id" --status applied --json
done

Agentengesteuerte Bewerbung

Für die Bearbeitung einzeln nacheinander lass den Agenten das Kit erstellen und prüfen, das Anschreiben kopieren und den Tracker-Eintrag durch den echten Bewerbungsstatus-Ablauf bewegen.

Shell
roasted apply create --cv "QA Engineer" --jd-file ./jd.txt \
  --cv-lang en --cl-lang en --intensity smart --json
ID=<applyKitId>
roasted apply get "$ID" --pages --json
roasted apply shrink "$ID" --json
roasted apply get "$ID" --json | jq -r '.coverLetter' > cover-letter.txt
roasted app add --from-kit "$ID" --status saved --json
roasted app status <appId> applied --json
roasted app status <appId> interviewing --json
roasted app status <appId> closed --outcome offer --json

JSON-Ausgabeschemata

Die folgenden Beispiele zeigen die orchestrierungskritischen Strukturen. Nullable-Felder bleiben vorhanden. Im Watch-Modus werden Fortschrittsobjekte eines pro Zeile vor dem Endergebnis ausgegeben.

whoami
{ "email": string|null, "role": string|null, "refCode": string|null,
  "userId": string, "profile": string|null,
  "auth": "oauth"|"api_key"|"env_api_key" }
accounts
{ "active": string|null, "activeSource": string, "envApiKey": boolean,
  "accounts": [{ "name": string, "type": "oauth"|"api_key",
    "email": string|null, "apiKeyMasked": string|null, "active": boolean }] }
keys create
{ "id": string, "name": string, "key": string, "masked": string,
  "status": "active", "createdAt": string, "expiresAt": string|null,
  "lastUsedAt": null, "revokedAt": null }
keys list
{ "keys": [{ "id": string, "name": string, "masked": string,
  "status": "active"|"revoked"|"expired", "createdAt": string,
  "expiresAt": string|null, "lastUsedAt": string|null,
  "revokedAt": string|null }] }
cv list / cv search
{ "cvs": [{ "id": string, "name": string|null, "updatedAt": string }] }
cv pull
{ "id": string, "name": string|null, "yaml": string }
cv push
{ "id": string, "name": string|null, "created": boolean,
  "warnings": string[], "dashboardUrl": string }
apply plan
{ "plan": string, "credits": number, "cost": number,
  "premiumCost": number, "canAfford": boolean }
apply create --no-wait
{ "applyKitId": string }
apply create --watch
{ "phase": string, "at": string }
apply create / apply get
{ "id": string, "createdAt": string,
  "status": "generating"|"ready"|"failed", "progressStep": string|null,
  "jobTitle": string|null, "company": string|null, "location": string|null,
  "seniority": string|null, "salaryRange": string|null, "techStack": string[],
  "keyRequirements": string[], "niceToHave": string[], "deadline": string|null,
  "intensity": string|null, "tone": string|null, "length": string|null,
  "coverLetter": string|null, "includeCoverLetter": boolean, "premium": boolean,
  "sourceCvFileId": string|null, "tailoredFileId": string|null,
  "failureReason": string|null, "generatedAt": string|null,
  "dashboardUrl": string, "pageCount": number|null }
apply list
{ "kits": [{ "id": string, "createdAt": string, "status": string|null,
  "jobTitle": string|null, "company": string|null, "intensity": string|null,
  "tone": string|null, "length": string|null }] }
apply pdf
{ "applyKitId": string, "pageCount": number|null, "out": string|null,
  "dashboardUrl": string, "hint"?: string }
apply shrink
{ "applyKitId": string, "tailoredFileId"?: string,
  "pageCountBefore": number|null, "pageCountAfter": number|null,
  "changed": boolean, "dashboardUrl": string }
app list
{ "applications": [{ "id": string, "status": string|null,
  "outcome": string|null, "company": string|null, "position": string|null,
  "location": string|null, "source": string|null, "appliedAt": string|null,
  "createdAt": string, "updatedAt": string }] }
app get / add / save / status / note
{ "id": string, "status": string|null, "outcome": string|null,
  "company": string|null, "position": string|null, "location": string|null,
  "salaryRange": string|null, "seniority": string|null, "sourceUrl": string|null,
  "contactPerson": string|null, "contactEmail": string|null, "deadline": string|null,
  "cvFileId": string|null, "applyKitId": string|null, "appliedAt": string|null,
  "source": string|null, "jdText": string|null, "coverLetter": string|null,
  "notes": string|null, "techStack": string[], "keyRequirements": string[],
  "niceToHave": string[], "createdAt": string, "updatedAt": string,
  "dashboardUrl": string }
app rm
{ "id": string, "deleted": true }
error
{ "error": { "code": string, "message": string } }

Listenbefehle verpacken Zeilen in cvs-, kits-, applications- oder keys-Arrays. Detailbefehle geben den vollständigen Eintrag zurück, einschließlich Nullable-Job-Metadaten, Zeitstempeln, verknüpften Datei-IDs, Quellinhalt und der Dashboard-URL.

Exit-Codes und Fehlerkatalog

Alle Befehle enden mit 0 bei Erfolg und mit 1 bei jedem Fehler. Prüfe im JSON-Modus error.code. Backend-Fehler-Codes aus Generierung und Verkleinerung werden unverändert durchgereicht. PAID_PLAN_REQUIRED auf einem kostenlosen Konto ist erwartetes Verhalten, keine Störung: Bewerbungs-Kits und neue Tracker-Einträge brauchen einen aktiven Hunter Pass, und ein Abo behebt den Code.

  • Auth und Profile: NO_SESSION, SESSION_EXPIRED, AUTH_UNAVAILABLE, BAD_PROFILE, PROFILE_NOT_FOUND, PROFILE_STORE_CORRUPT, API_KEY_INVALID, API_KEY_EXCHANGE_FAILED, BAD_KEY_NAME, BAD_TTL, KEY_NOT_FOUND, KEY_AMBIGUOUS.
  • Lebensläufe und Bewerbungs-Kits: CV_NOT_FOUND, CV_AMBIGUOUS, BAD_CV_YAML, FILE_NOT_FOUND, JD_MISSING, JD_CONFLICT, JD_TOO_SHORT, BAD_INTENSITY, BAD_TONE, BAD_LENGTH, BAD_FORMALITY, PAID_PLAN_REQUIRED, INSUFFICIENT_CREDITS, NOT_FOUND, NO_TAILORED_FILE, NO_YAML, NO_CV_CONTENT, TYPST_COMPILE_FAILED, KIT_TIMEOUT.
  • Tracker: BAD_STATUS, BAD_OUTCOME, OUTCOME_REQUIRES_CLOSED, APP_EMPTY, APP_ARG_CONFLICT, PAID_PLAN_REQUIRED, KIT_NOT_READY, NOT_FOUND.