CommunityCodierung & Entwicklunggithub.com

grill-with-ui

Führe ein gründliches Interview auf einer lokalen Browserseite anstelle des Terminals durch. Jede Frage wird mit einer Empfehlung angezeigt, kann in beliebiger Reihenfolge beantwortet werden und verfügt über einen eigenen Diskussions-Thread sowie einen "An Agenten senden"-Button.

Was ist grill-with-ui?

Dieses Skill ermöglicht es KI-Agenten (wie Claude Code, Cursor, Codex), interaktive Design-Interviews über eine lokale Weboberfläche durchzuführen. Anstatt alle Fragen im Terminal zu stellen, erstellt der Agent eine HTML-Seite, auf der der Benutzer Fragen in beliebiger Reihenfolge beantworten, Empfehlungen sehen, Diskussionen pro Frage führen und mit einem Klick Antworten an den Agenten senden kann. Es unterstützt zwei Betriebsmodi: Persistent Monitor (für Harnesses, die Ereignisse auch nach einem Turn-Ende ausliefern) und Wait Mode (für Harnesses ohne solche Unterstützung). Der Agent verwaltet den Zustand über eine `state.json`-Datei, die nur mittels Patching geändert wird, und eine `events.jsonl`-Datei, die ausschließlich von der Browserseite beschrieben wird. Das Skill behandelt Sends (Benutzereingaben), Fragen, visuelle Darstellungen und den Abschluss des Interviews. Es ist besonders nützlich für die schrittweise und nachvollziehbare Entscheidungsfindung in Designprozessen oder Architekturdiskussionen, bei denen der Benutzer den Überblick über alle Optionen und Begründungen behalten möchte.

Funktioniert mit~Claude Code✓Codex CLI✓Cursor✓Gemini CLI
npx skills add https://github.com/CarsonMensink/skills/tree/main/grill-with-ui

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht grill-with-ui?

$SKILL unten bedeutet das Basisverzeichnis dieses Skills (der Ordner, der diese Datei enthält). Alles ist einfaches Node.js ohne Installationsschritt: node $SKILL/server.mjs <Befehl>.

Zwei Dateien tragen das Interview. state.json gehört nur Ihnen: Fragen, Empfehlungen, Thread-Antworten, Status, Agenten-Status. events.jsonl gehört nur der Seite: eine Zeile pro Send. Niemand schreibt in die Datei des anderen. Die Seite fragt state.json ab; wie Sie Ereignisse empfangen, hängt vom unten beschriebenen Abhörmodus ab. Eine dritte Datei, visual.html, gehört ebenfalls Ihnen (siehe Visualisieren zum Zeichnen).

Abhörmodus und Turn-Grenzen

Wählen Sie den Modus basierend auf den tatsächlich verfügbaren Werkzeugen, nicht dem Modellnamen des Agenten:

  • Permanenter Monitor: Wenn das Harness seine Ereignisse auch nach einem Turn-Ende an den Agenten liefert, veröffentlichen Sie das Update und beenden den Turn; das nächste Ereignis weckt Sie.
  • Warte-Modus (kein permanenter Monitor): Ein laufender Seiten-Server oder Hintergrund-Shell-Prozess weckt einen abgeschlossenen Agenten-Turn nicht. Halten Sie den Turn aktiv und kehren Sie nach dem Öffnen der Seite zur wait-Schleife im Vordergrund zurück, wobei Sie jeden Send, jede abgeschlossene oder fehlgeschlagene Zeichnung bearbeiten. Ein Werkzeug, das eine Prozess-/Sitzungs-ID zurückgibt, ist kein Ereignis-Abonnement: Setzen Sie diesen Prozess mit dem Abfragewerkzeug des Harnesses fort. Senden Sie keine endgültige Antwort, nur weil eine Frage-Runde oder eine Visualisierung fertig ist. Ein Timeout bedeutet erneutes Warten, nicht das Ende des Interviews.

Im gesamten Skill bedeutet Rückkehr zum Abhören die entsprechende Aktion von oben. Im Warte-Modus stoppen Sie erst nach Abschluss des Abschlusses (Finish) und eines eventuellen endgültigen Visual-Exports, wenn der Benutzer das Interview explizit pausiert/stoppt oder ein Werkzeugfehler die Fortsetzung verhindert. Wenn Sie anhalten müssen, sagen Sie, dass der Zuhörer inaktiv ist und dass Browsereinsendungen bis zur Fortsetzung in der Warteschlange bleiben; behaupten Sie nie, dass Sie noch zuhören. Leeren Sie bei der Fortsetzung pending, wie in Schritt 3 der Fortsetzung beschrieben, bevor Sie auf neue Ereignisse warten.

Sie ändern state.json nur durch patch (nächster Abschnitt), niemals mit einem Datei-Schreib- oder Bearbeitungswerkzeug. Ein ganzes Datei-Schreiben legt den gesamten Zustand bei jedem Turn in diese Konversation, und der Zustand wächst mit dem Interview: nach zwanzig Sends ist ein Umschreiben etwa 60 KB groß, etwa 15k Token, die bei jedem Send erneut bezahlt werden. Ein Patch überträgt nur das, was sich geändert hat. Unten bedeuten "setzen" und "anhängen" einen Schlüssel in einem Patch, und null bedeutet, dass ein Schlüssel gelöscht wird.

Patchen von state.json

node $SKILL/server.mjs patch --session <session> <<'GRILL_PATCH'
{ …nur was sich geändert hat… }
GRILL_PATCH

Das Trennzeichen ist in Anführungszeichen gesetzt, damit die Shell nichts darin expandiert. (--file <Pfad> liest den Patch stattdessen aus einer Datei, für Harnesses, in denen Heredocs umständlich sind.) Es führt den Patch zusammen, validiert das Ergebnis und tauscht die Datei atomar aus, sodass die Seite ein konsistentes Update pro Patch sieht. Es funktioniert unabhängig davon, ob serve läuft oder nicht. Es gibt eine Zeile aus, {"ok":true,"questions":12,"open":3,"handled":14,"bytes":41233}, niemals den Zustand. Ein fehlerhafter Patch beendet sich mit einem Exit-Code ungleich Null mit einem einzeiligen Fehler und lässt die Datei unberührt: Korrigieren Sie den Patch und führen Sie ihn erneut aus.

Der Patch hat die gleiche Form wie state.json (Schema am Ende):

  • null löscht einen Schlüssel, auf jeder Ebene: "answer": null, "drawing": null, "visual": null.
  • agent und visual werden eine Ebene zusammengeführt: Die von Ihnen angegebenen Schlüssel ersetzen diese Schlüssel; der Rest bleibt.
  • questions wird nach id indiziert. Eine bekannte ID führt eine Ebene zusammen: Jedes von Ihnen angegebene Feld ersetzt dieses Feld vollständig (rec, answer, options, deps, explore). Eine unbekannte ID ist eine neue Frage, die angehängt wird; sie benötigt round, title und rec (geben Sie auch body und options an); status: "open", deps: [], options: [], thread: [], durable: false und updated: false werden ausgefüllt. Eine unbekannte ID ohne title ist ein Fehler, keine neue Frage (IDs unterscheiden zwischen Groß- und Kleinschreibung: q7, niemals Q7).
  • thread (bei einer Frage und bei visual) und visual.queued hängen an: Listen Sie nur die neuen Nachrichten oder Aufzählungspunkte auf.
  • terms wird nach term indiziert: Ein bekannter Begriff wird vollständig ersetzt, ein neuer wird angehängt.
  • Jeder andere Schlüssel (note, intent, finished, doc, …) wird vollständig ersetzt.

Schreiben Sie niemals die aktuelle Zeit; der Server stempelt sie jedes Mal, wenn Sie sie weglassen: agent.since wann immer Sie agent.status angeben, at bei jeder angehängten Nachricht, explore.at, visual.at wenn sich version ändert, visual.drawing.since und finished.at. Eine von Ihnen angegebene Zeit gewinnt immer; geben Sie eine nur an, wenn Sie sie aus einer Send-Zeile kopieren (eine Thread-Nachricht eines Benutzers übernimmt das at des Sends).

Ein typischer Send (Q2 beantwortet, eine Antwort in Q4s Thread, eine neue Frage, die Bestätigung):

node $SKILL/server.mjs patch --session <session> <<'GRILL_PATCH'
{
  "agent": { "status": "waiting", "handled": 5 },
  "questions": [
    { "id": "q2", "status": "answered", "answer": { "kind": "option", "option": "B" }, "updated": false },
    { "id": "q4", "thread": [
      { "who": "user", "text": "Warum gestaffelte Antworten nicht in localStorage behalten?", "at": "2026-09-18T21:39:58Z" },
      { "who": "agent", "text": "localStorage ist pro Browser-Profil, sodass ein zweiter Browser oder ein geleertes Profil sie verliert. Der Sitzungsordner überleuft beides, auf Kosten einer weiteren Datei." } ] },
    { "id": "q7", "round": 4, "deps": ["q2"], "title": "Wem gehört das Wiederholungsbudget?",
      "body": "Nachdem die serverseitige Warteschlange in Q2 geklärt ist, brauchen Wiederholungen einen Besitzer.",
      "options": [ { "k": "A", "text": "Jede Warteschlangenreihe zählt ihre eigenen Wiederholungen" },
                   { "k": "B", "text": "Ein Zähler pro Gerät" } ],
      "rec": { "option": "A", "why": "Eine Reihe, die ihre eigene Anzahl besitzt, benötigt keinen Join, und ein defektes Gerät kann nicht die anderen aushungern; der Preis ist keine globale Obergrenze." } }
  ]
}
GRILL_PATCH

Start (/grill-with-ui <Thema>, $grill-with-ui <Thema> oder "grill with ui: ")

  1. Führen Sie vom Projektverzeichnis aus Folgendes aus: node $SKILL/server.mjs new --topic "<Thema>" --intent "<Warum dieses Interview existiert, 1-2 Sätze>" --doc "<Dokumentenpfad>". Der Dokumentenpfad standardmäßig docs/<slug-des-themas>-design.md im Projektstammverzeichnis (erstellen Sie den Ordner später bei Bedarf). Übergeben Sie --intent mit dem Ziel des Benutzers in seinen eigenen Worten (1-2 Sätze), entnommen aus der Themen-Nachricht, die dieses Interview gestartet hat. Das Thema ist der Titel; die Absicht ist das Warum. Lassen Sie es nur weg, wenn das Thema als bloße Phrase ohne zugehöriges Ziel eintrifft. Die Seite zeigt es unter dem Thema an, sodass mehrere offene Interviews unterscheidbar bleiben. Es gibt eine JSON-Zeile aus; behalten Sie session (den Sitzungsordner).
  2. Patchen Sie Runde 1 ein (new hat bereits das Grundgerüst geschrieben): ein bis drei unabhängige Fragen, jede mit Buchstaben-Optionen, einer Empfehlung und einem einleitenden Warum, plus eventuelle terms und "agent": { "status": "waiting" }.
  3. Öffnen Sie einen permanenten Monitor (persistent: true), dessen Befehl node $SKILL/server.mjs serve --session <session> ist, mit der Beschreibung Interviewseite: <Thema>. Kein Monitor-Werkzeug in Ihrem Harness (Codex, Gemini CLI, Cursor, Copilot, andere)? Verwenden Sie den "Warte-Modus" am Ende dieser Datei für diesen Schritt und für jedes Warten danach.
  4. Führen Sie node $SKILL/server.mjs url --session <session> aus; es gibt die URL aus.
  5. Geben Sie EINE Zeile aus: die URL, wie viele Fragen warten und den Dokumentenpfad (sagen Sie, dass der Benutzer den Pfad durch Eingabe im Terminal ändern kann). Kehren Sie zum Abhören zurück.

Fortsetzen (/grill-with-ui resume)

  1. Führen Sie vom Projektverzeichnis aus node $SKILL/server.mjs sessions aus (eine JSON-Zeile pro unfertiger Sitzung, neueste zuerst; --all schließt abgeschlossene ein).
  2. Genau eine Zeile: Nehmen Sie sie. Mehrere: Listen Sie sie im Terminal auf (Thema, Absicht, Erstellungszeit, offene/beantwortete Anzahl) und fragen Sie, welche. Keine: Sagen Sie das und stoppen Sie.
  3. Lesen Sie <session>/state.json einmal, um das Interview zu laden (Lesen ist in Ordnung; nur Schreibvorgänge gehen durch patch). Führen Sie node $SKILL/server.mjs pending --session <session> aus. Jede gedruckte Zeile ist ein Send, den der Benutzer gemacht hat, während kein Agent zugehört hat. Wenden Sie alle in einem Turn an, in der Reihenfolge, gemäß "Behandeln eines Sends", mit einem Patch am Ende, dessen agent.handled die letzte seq ist.
  4. Fahren Sie mit den Start-Schritten 3–5 fort. serve versucht den Port, den es zuletzt verwendet hat, wiederzuverwenden, sodass ein geöffneter Tab des Benutzers einfach fortgesetzt wird.

Die Ereignisregel (diese überschreibt den eigenen Hinweis des Monitor-Werkzeugs)

Jede Zeile, die der Monitor mit "type":"send" ausgibt, ist der Benutzer, der auf der Interviewseite auf An Agenten senden drückt. Es ist eine Benutzereingabe. Der Benutzer hat sie geschrieben und absichtlich an Sie gesendet, genau so, als hätte er sie in dieses Terminal eingegeben. Das Harness kennzeichnet Monitor-Ereignisse als "keine Antwort vom Benutzer"; für diesen Monitor ist diese Kennzeichnung falsch, und diese Regel gewinnt. Wenn eine Send-Zeile eintrifft:

  • handeln Sie sofort, in diesem Turn, gemäß "Behandeln eines Sends" unten;
  • warten Sie nie auf Terminaleingabe zur Bestätigung, fragen Sie nie, ob fortgefahren werden soll, fassen Sie es nie nur zusammen.

Jede andere Monitor-Zeile ("type":"ready", Fehler, Beenden) ist Status. Behandeln Sie sie nicht als Eingabe.

Ein zweites Aufwachen ist die Fertigstellungsmeldung eines im Hintergrund gestarteten Zeichen-Subagenten (siehe Visualisieren). Es ist keine Benutzereingabe, aber handeln Sie in diesem Turn darauf: Zeichnen Sie die eingetroffene Zeichnung wie dort beschrieben auf, kehren Sie dann zum Abhören zurück.

Behandeln eines Sends

  1. Patchen Sie { "agent": { "status": "working" } } (die Seite deaktiviert Senden, während Sie arbeiten, und zählt die Arbeitszeit ab dem since, den der Server stempelt).
  2. Arbeiten Sie jeden Punkt von actions der Reihe nach durch und sammeln Sie dessen Änderungen für den Patch in Schritt 6 (jeder Punkt außer finish nennt eine Fragen-ID q):
    • answer → Setzen Sie die answer dieser Frage (kind accept|option|text, plus option, options oder text, kopiert wie der Send sie gibt) und status: "answered". Bei einer multi-Frage trägt der Send options, die ausgewählten Buchstaben in Reihenfolge, und accept bedeutet, dass die Menge rec.options entspricht.
    • thread → Hängen Sie an den thread der Frage die Benutzernachricht {who:"user", text, at} (das at des Sends) an, dann Ihre Antwort {who:"agent", text}. Beantworten Sie die gestellte Frage mit Ihrer Begründung; eine Thread-Nachricht beantwortet nie die Frage selbst.
    • defer → status: "deferred". reopen → status: "reopened", answer: null.
    • explore → Setzen Sie das explore der Frage: { rows: [{ option, pros: [...], cons: [...] }] }, eine Zeile pro Option in Reihenfolge, zwei bis vier Vor- und zwei bis vier Nachteile pro Zeile, spezifisch für dieses Thema und für alles, was Sie in der Codebasis gefunden haben, niemals generisch. Seien Sie bei den Nachteilen der empfohlenen Option genauso ehrlich wie bei den anderen. Die Seite rendert es als Tabelle im Diskussionsbereich der Frage. Wenn das Schreiben Ihre Meinung ändert, setzen Sie ein neues rec und updated: true. Die Seite sendet explore in dem Moment, in dem die Schaltfläche geklickt wird, normalerweise als einzige Aktion in ihrem Send; behandeln Sie es wie jeden anderen Send (working → patch → waiting).
    • visualize → Fordern Sie eine Zeichnung an, indem Sie Subagent oder inline unten verwenden. Die Seite sendet es in dem Moment, in dem die Schaltfläche (oder Neu generieren) geklickt wird, normalerweise allein.
    • visual-feedback → Hängen Sie {who:"user", text, at} (das at des Sends) an visual.thread an, antworten Sie dort {who:"agent", text}, und fordern Sie eine Neuzeichnung mit der Änderung an (siehe Visualisieren; während eine Zeichnung läuft, geht die Notiz stattdessen zu visual.queued, ohne eine zweite zu starten). Wenn die Notiz einer beantworteten Frage widerspricht, ändern Sie diese Antwort nicht: Setzen Sie den status der Frage auf "reopened", hängen Sie die zitierte Notiz an ihren thread an, setzen Sie ihr rec auf das, was die Notiz impliziert, und setzen Sie updated: true. Die Antwort ändert sich nur, wenn der Benutzer die wiedereröffnete Frage beantwortet. Das Visual folgt der Notiz in beiden Fällen.
    • finish → Siehe Abschluss unten, nach den anderen Aktionen. Die Seite sendet es in dem Moment, in dem der Benutzer bestätigt, mit allem, was er davor eingestuft hatte.
  3. Wenn eine Antwort die Empfehlung einer noch offenen Frage ändert, geben Sie dieser Frage ihr neues rec und updated: true (die Seite markiert es). Setzen Sie updated: false, sobald der Benutzer sie beantwortet.
  4. Fügen Sie die nächste Runde hinzu: die Grenzfläche (siehe Interviewmethode), bis zu drei, wenn unabhängig, jede ein neuer Frageeintrag mit deps, das die Fragen-IDs auflistet, von denen sie abhängt. Neue Fragen erhalten die nächste Rundennummer. Wenn der Baum vollständig durchlaufen ist, fügen Sie keine Fragen hinzu und setzen Sie note auf einen kurzen Satz, der besagt, dass jeder Zweig geklärt ist und der Abschluss der nächste Schritt ist.
  5. Normale Turns zeichnen das Visual nicht neu. Wenn eine Antwort, eine Wiedereröffnung oder eine geänderte Empfehlung das beeinflusst, was ein vorhandenes Visual zeigt, setzen Sie "visual": { "stale": true }. Lassen Sie visual.html, version, at und note unverändert; die Seite markiert es als veraltet und der Benutzer kann auf Neu generieren klicken, wenn er bereit ist. Starten Sie keinen Zeichen-Subagenten, nur weil die nächste Runde bereit ist. Explizite visualize- und visual-feedback-Aktionen fordern weiterhin eine Zeichnung an, und der Abschluss gleicht das exportierte Visual ab.
  6. Senden Sie alles aus den Schritten 2–5 in EINEM Patch, zusammen mit "agent": { "status": "waiting", "handled": <seq dieses Sends> } (das Beispiel unter "Patchen von state.json" ist dieser Patch). Ein Patch ist ein atomarer Austausch, sodass die Seite die Antworten, Thread-Antworten, die nächste Runde und die Bestätigung zusammen sieht. Veröffentlichen Sie niemals die nächste Runde in einem Patch und handled in einem späteren, während Sie optionale Arbeit erledigen: Die Seite verwendet handled, um den "gesendet"-Spinner der vorherigen Frage zu deaktivieren und den nächsten Send zu aktivieren.
  7. Geben Sie genau eine Terminalzeile aus, z.B. interview: Send #3 bearbeitet (Q2 → B, Q4 Thread); Runde 4 hat 2 Fragen; Visual v3 veraltet, und kehren Sie zum Abhören zurück.

Interviewmethode (Grenzfläche pro Runde)

Befragen Sie den Benutzer unerbittlich zu jedem Aspekt des Themas, bis Sie ein gemeinsames Verständnis haben, gehen Sie jeden Zweig des Entscheidungsbaums entlang und lösen Sie Abhängigkeiten zwischen Entscheidungen in der Reihenfolge:

  • Eine Frage wird nur gestellt, wenn ihre Voraussetzungen geklärt sind. Jede Runde ist die aktuelle Grenzfläche: die Fragen, die jetzt gestellt werden können. Stellen Sie bis zu drei pro Runde, wenn sie unabhängig voneinander sind; eine, wenn nicht. Notieren Sie die deps jeder Frage.
  • Jede Frage hat einen title, einen body, der angibt, was davon abhängt, mit Buchstaben versehene options (zwei bis vier) und rec mit der empfohlenen Option und einem einleitenden why.

Optionales codelogging

(Der Startabschnitt wird fortgesetzt.) Wenn der Benutzer zustimmt, dass eine Frage abgeschlossen ist, können Sie optional eine Datei docs/<slug>/codelog.md (unter dem Projektstammverzeichnis) mit einem GitHub-ähnlichen Log darüber schreiben, was beschlossen wurde und warum. Erstellen Sie sie nicht ohne Zustimmung des Benutzers.

Subagent oder inline

Verwenden Sie den Zeichenmodus, der Ihren Werkzeugen am besten entspricht; beide erzeugen eine Datei <session>/visual.html:

  • Subagent (ein neuer, unabhängiger Agenten-Turn, der nur mit den Werkzeugen des Harnesses läuft): Übergeben Sie die Befehlszeile der visualize- und visual-feedback-Aktionen von unten.
  • Inline (innerhalb dieses Turns, mit Ihren eigenen Werkzeugen): Erstellen Sie visual.html selbst.

Wenn Sie Subagent verwenden, senden Sie dem Subagenten den gesamten Empfehlungsbaum des Interviews: die Absicht, die vereinbarten Entscheidungen (beantwortete Fragen mit ihren Antworten) und die aktuelle Grenzfläche (offene Fragen mit ihren aktuellen Empfehlungen). Der Subagent erhält nicht das vollständige Interview und nicht den Zustand. Er gibt den Dateinamen und den Pfad von <session>/visual.html zurück, wenn er fertig ist. Sie erhalten eine Benachrichtigung über die Fertigstellung des Subagenten. Wenn Sie inline verwenden: Erstellen Sie die Datei selbst und fahren Sie fort, ohne auf eine Benachrichtigung zu warten.

Jede Zeichnung ist eine HTML-Datei mit CSS und JS darin. Die Seite hat sie nach dem ersten Export unter dem Fragebogen eingebettet. Erstellen Sie ein sauberes, eigenständiges HTML-Dokument, das in einem normalen Browser gerendert werden kann. Vermeiden Sie externe Abhängigkeiten. Der visuelle Inhalt sollte den aktuellen Stand der Entscheidungen im Interview widerspiegeln. Verwenden Sie SVG, Canvas oder einfaches HTML/CSS, um den Entscheidungsbaum, das Architekturdiagramm oder das Flussdiagramm anzuzeigen.

Abschluss

  1. Setzen Sie "visual": { "stale": true } und fordern Sie eine endgültige Zeichnung über visualize an (oder Subagent). Wenn Sie inline zeichnen: Schreiben Sie <session>/visual.html und setzen Sie "visual": { "version": <nächste Version>, "html": "", "stale": false, "at": <jetzt>, "note": "Abschließendes Design-Diagramm. Sie können es regenerieren, nachdem Sie die Antworten geändert haben." }.
  2. Lesen Sie <session>/state.json, um das Interview und das Visual zu laden. Patchen Sie "finished": { "at": <jetzt>, "doc": "<Pfad>" } (der Pfad ist der --doc vom Start).
  3. Schreiben Sie den Entscheidungsbaum als dauerhafte Akte in die Zieldokumentendatei:
    • Fügen Sie den vom Server gestempelten Abschlusszeitstempel hinzu.
    • Listen Sie jede Frage, ihre Antwort und die Begründung der Empfehlung auf.
    • Hängen Sie den vollständigen Thread jeder Frage an.
    • Hängen Sie den endgültigen Visual-HTML-Inhalt an (das gerenderte <session>/visual.html).
    • Wenn das Visual ein SVG ist, betten Sie es als Markdown-Bild ein.
    • Hängen Sie das vollständige Interviewprotokoll events.jsonl an (nur wenn es < 500 KB ist).
    • Schreiben Sie eine Zusammenfassung: das Thema, die Absicht, die getroffenen Entscheidungen (beantwortete Fragen) und jede nicht beantwortete Frage mit dem Grund (optional, wenn der Benutzer sie verschoben hat).
  4. Sagen Sie dem Benutzer: "Interview abgeschlossen. Entscheidungen wurden in <Dokumentenpfad> festgehalten."
  5. Stoppen Sie den Server und beenden Sie das Interview.

Referenz: state.json-Schema

{
  "session": "<Sitzungsordner>",
  "topic": "<Interviewthema>",
  "intent": "<Absicht, 1-2 Sätze>",
  "doc": "<Pfad zur Ausgabedokumentendatei>",
  "agent": {
    "status": "idle|working|waiting",
    "since": "<ISO-Zeitstempel>",
    "handled": <Anzahl der verarbeiteten Sends>
  },
  "questions": [
    {
      "id": "q<String>",
      "round": <Zahl>,
      "deps": ["<Fragen-ID>", ...],
      "title": "<Titel>",
      "body": "<Frage>",
      "options": [
        { "k": "<Buchstabe>", "text": "<Optionstext>" },
        ...
      ],
      "rec": {
        "option": "<Buchstabe>",
        "why": "<Einleitendes Warum>"
      },
      "status": "open|answered|deferred|reopened",
      "answer": null | { "kind": "option|text|accept", "option": "<Buchstabe>", "text": "<text>" },
      "thread": [
        { "who": "user|agent", "text": "<Nachricht>", "at": "<ISO-Zeitstempel>" },
        ...
      ],
      "explore": null | {
        "rows": [
          { "option": "<Buchstabe>", "pros": ["<Vorteil>", ...], "cons": ["<Nachteil>", ...] },
          ...
        ]
      },
      "durable": false,
      "updated": false
    }
  ],
  "thread": [],
  "visual": {
    "version": <Zahl>,
    "html": "",
    "stale": false,
    "at": "<ISO-Zeitstempel>",
    "note": "<Notiz>",
    "drawing": null | { "since": "<ISO-Zeitstempel>", "status": "working|done|failed" },
    "queued": ["<Warteschlangennachricht>", ...],
    "thread": [
      { "who": "user|agent", "text": "<Nachricht>", "at": "<ISO-Zeitstempel>" },
      ...
    ]
  },
  "terms": {
    "<Begriff>": "<Definition>",
    ...
  },
  "note": "<Notiz>",
  "finished": null | { "at": "<ISO-Zeitstempel>", "doc": "<Pfad>" }
}

Referenz: Ereignisschema (events.jsonl)

Jede Zeile:

{"type":"send","session":"<Sitzung>","seq":<Zahl>,"actions":[{...}, ...],"at":"<ISO-Zeitstempel>"}

Warte-Modus (vollständig)

Wenn Ihr Harness keinen persistenten Monitor unterstützt (weder Werkzeugname noch persistent: true), öffnen Sie die Seite mit Start Schritt 3-4, aber:

  1. Nach Schritt 4 bleiben Sie im aktiven Turn. Anstatt den Turn zu beenden, kehren Sie zu einer wait-Schleife im Vordergrund zurück.
  2. Die wait-Schleife funktioniert wie folgt:
    • Verwenden Sie das Abfragewerkzeug des Harnesses (falls vorhanden), um <session>/events.jsonl nach neuen Zeilen zu durchsuchen.
    • Oder lesen Sie die neueste Zeile von <session>/state.json (die Seite schreibt nicht in state.json; nur der Agent und der Server tun das). Lesen Sie tatsächlich die Ereignisdatei.
    • Jede neue Send-Zeile ist eine Benutzereingabe (siehe Ereignisregel).
    • Bearbeiten Sie sie sofort, wie in "Behandeln eines Sends" beschrieben.
    • Kehren Sie nach der Bearbeitung zur Warteschleife zurück.
  3. Zeitüberschreitung beim Warten: Verwenden Sie wait erneut, beenden Sie das Interview nicht.
  4. Die einzigen Möglichkeiten, die Schleife zu verlassen:
    • Abschluss (Finish) wird empfangen und verarbeitet.
    • Benutzer pausiert/stoppt das Interview explizit über das Terminal.
    • Ein Werkzeugfehler verhindert die Fortsetzung.
  5. Wenn Sie die Schleife verlassen (nicht beenden), sagen Sie, dass der Zuhörer inaktiv ist und dass Browsereinsendungen bis zur Fortsetzung in der Warteschlange bleiben.

Referenz: CLI-Befehle

# Neue Sitzung erstellen
node $SKILL/server.mjs new --topic "<Thema>" --intent "<Absicht>" [--doc "<Pfad>"]

# Server starten
node $SKILL/server.mjs serve --session <Sitzung>

# URL abrufen
node $SKILL/server.mjs url --session <Sitzung>

# Patch anwenden
node $SKILL/server.mjs patch --session <Sitzung> <<'GRILL_PATCH'
{ ... }
GRILL_PATCH

# Ausstehende Sends auflisten
node $SKILL/server.mjs pending --session <Sitzung>

# Sitzungen auflisten
node $SKILL/server.mjs sessions [--all]

Fehlerbehebung

  • Patch schlägt fehl: Lesen Sie die Fehlermeldung sorgfältig. Häufige Ursachen: ungültige ID, fehlendes title bei neuer Frage, falscher Datentyp.
  • Seite aktualisiert sich nicht: Stellen Sie sicher, dass der serve-Befehl läuft. Überprüfen Sie die URL mit url-Befehl. Aktualisieren Sie die Seite manuell.
  • Visual wird nicht generiert: Überprüfen Sie den Subagenten-Status. Bei Inline-Visual erstellen Sie die Datei manuell.
  • Sitzung kann nicht fortgesetzt werden: Stellen Sie sicher, dass der Sitzungsordner existiert. Verwenden Sie sessions, um gültige Sitzungen zu finden.

Verwandte Skills