CommunitySchreiben & Editierengithub.com

Texarkanine/stockroom

Ein lokales, zuverlässiges, durchsuchbares Warehouse Ihrer agentischen Programmier-Historie.

Was ist stockroom?

Dieses Skill ermöglicht es, schreibgeschützte SQL-Abfragen gegen die lokale DuckDB-Datenbank auszuführen, die Ihre Agentensitzungen (Cursor und Claude Code) erfasst. Es ist ideal für exakte Lookups, Filter, Aggregationen und Join-Abfragen über Sessions, Nachrichten und Tool-Aufrufe. Das System stellt sicher, dass kein Datenverlust durch Schreibzugriffe möglich ist, da DuckDB alle Schreibversuche ablehnt. Nutzen Sie es, um strukturierte Informationen wie die Anzahl von Sessions pro Tool, die meistgenutzten Tools oder Token-Verbräuche je Session zu ermitteln.

Funktioniert mit✓Claude Code~Codex CLI✓Cursor✓Antigravity
npx skills add Texarkanine/stockroom

Installed? Explore more Schreiben & Editieren skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

In Ihrer bevorzugten KI fragen

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

Dokumentation

sr-query

sr-query führt schreibgeschütztes SQL gegen das Stockroom-Warehouse aus – die Einzeldatei-DuckDB-Datenbank Ihrer aufgezeichneten Cursor- und Claude-Code-Historie. Die Oberfläche ist konstruktionsbedingt schreibgeschützt: DuckDB lehnt jeden Schreibversuch ab, sodass Sie durch Abfragen nichts beschädigen können.

Wann man sr-query verwendet

Greifen Sie zu sr-query, wenn die Frage eine bekannte Form hat und die Antwort eine exakte oder strukturierte Abfrage über benennbare Felder ist:

  • Eine bestimmte Zeile anhand der ID (WHERE message_id = '…', WHERE session_id = '…')
  • Filter, Zählungen und Aggregationen (COUNT(*), GROUP BY harness, WHERE harness = 'claude', Token-Summen, Datumsbereiche)
  • Token-Aggregationen pro Session über die VIEW session_token_usage (bevorzugen Sie dies gegenüber einer manuellen SUM auf messages)
  • Joins über sessions / messages / tool_calls
  • „Wie viele“, „welche Sessions“, „liste die Tool-Aufrufe“, „welche Modelle“ – alles, was Sie als SQL über benannte Spalten ausdrücken können

Verwenden Sie sr-query nicht für bedeutungsbasierte Abfragen („finde Konversationen über flaky Tests“). SQL ILIKE ist ein literaler Substring-Vergleich, keine semantische Suche – für Bedeutung verwenden Sie das sr-semantic-Skill. Wenn Sie sich nicht sicher sind, welches richtig ist, gehört diese Entscheidung zum sr-search-Skill.

Aufruf der Engine

stockroom query "SELECT DISTINCT harness FROM sessions ORDER BY harness"

Sie können SQL auch über stdin mit - übergeben:

echo "SELECT count(*) FROM messages" | stockroom query -

Wenn command -v stockroom fehlschlägt, ist das Rechnersystem nicht eingerichtet: Weisen Sie den Benutzer an, das sr-initialize-Skill auszuführen, und versuchen Sie keinen anderen Aufruf.

Ausgabe-Disziplin: --format und --detail

Die Standardeinstellungen sind bereits sicher für einen Agenten – ein einfacher Aufruf liefert begrenzte, parsbare Ausgabe – greifen Sie also nur dann zu den Flags, wenn die Situation es erfordert.

--format – Ausgabeformat, Standard tsv

WertFormatVerwenden Sie es, wenn
tsv (Standard)Kopfzeile + tabulatorgetrennte Zeilen, kein ZähleranhangStandard. Stream-freundlich für Sie und für Unix-Pipes (cut, awk, wc -l).
jsonEin einzelnes Objekt {"columns": [...], "rows": [...]}Ein Benutzer fragt nach strukturierter/maschineller Ausgabe, oder Sie möchten es an jq übergeben.
tableSpaltenausgerichtetes ASCII mit einem Anhang (N rows)Ein Benutzer fragt nach etwas menschenlesbarem / einem Kopier-Befehl zum Anschauen.

Führen Sie mit dem Standard tsv. Bieten Sie --format table oder --format json an, wenn der Benutzer nach menschenlesbarer oder strukturierter Ausgabe fragt – „diese anderen Formate gibt es, wenn Sie sie möchten.“

--detail – Feldbreite, Standard snippet

Breite Zeichenkettenfelder (insbesondere messages.text und tool_calls.tool_input) werden beim Lesen abgeschnitten, damit eine breite Spalte nicht Ihren Kontext überflutet. Die Kürzung erfolgt nur anzeigeseitig – der vollständige Text ist jederzeit abrufbar.

WertBudget pro FeldVerwenden Sie es, wenn
compact~40 ZeichenSie scannen günstig viele Kandidatenzeilen, bevor Sie eine auswählen.
snippet (Standard)~120 ZeichenStandard. Genug, um eine Zeile zu erkennen, ohne sie auszugeben.
fullunbegrenzt, einzeiligSie benötigen die gesamte Feldlänge, und einzeilige Darstellung ist in Ordnung (Tabellen/TSV bleiben sicher).
rawunbegrenzt, exakte LeerzeichenSie benötigen den Text wie gespeichert – Zeilenumbrüche und interne Leerzeichen intakt. Bevorzugt mit --format json.

Ein über dem Budget liegendes Feld wird mit einem Marker gekürzt, der angibt, wie viele Zeichen verborgen wurden, z. B. …(+2284). Dieser Marker ist Ihr Signal, dass mehr existiert: Wenn Sie es tatsächlich benötigen, rufen Sie nur dieses Feld für die spezifische Zeile mit --detail full (Länge) oder --format json --detail raw (exakte Leerzeichen) erneut ab – siehe Schutzmaßnahmen.

Schutzmaßnahmen

Dies sind die Fehlermodi, die dieses Skill verhindern soll:

  • Blasen Sie nicht Ihren Kontext auf. Verwenden Sie niemals SELECT * (oder eine breite text-Spalte) mit --detail full/raw über viele Zeilen hinweg. Scannen Sie stattdessen eng mit --detail compact/snippet mit einer expliziten Spaltenliste und einem LIMIT, identifizieren Sie die gewünschte Zeile und rufen Sie dann nur das breite Feld dieser Zeile mit einem WHERE auf dessen ID erneut ab. Ein einzelnes SELECT text FROM messages WHERE message_id = '…' ist günstig; SELECT * FROM messages --detail full ist eine Kontextbombe. Wenn Sie exakte Leerzeichen benötigen (Markdown-Tabellen, Codeblöcke), verwenden Sie --format json --detail raw.
  • Es ist schreibgeschützt – versuchen Sie niemals Schreibvorgänge. INSERT / UPDATE / DELETE / CREATE schlagen alle fehl (query failed: …). Wiederholen Sie einen Schreibvorgang nicht mit einer anderen Formulierung; die Oberfläche dient nur der Abfrage.
  • tool_input ist heterogenes JSON. Seine Schlüssel variieren pro Tool (Shell hat command, Read hat path, …), daher kann ein naives tool_input->>'key' einen Cast-Fehler auslösen. Extrahieren Sie sicher, indem Sie zuerst tool_name in einer Unterabfrage/CTE filtern und die explizite Funktion verwenden:
stockroom query "SELECT json_extract_string(tool_input, '\$.command') AS cmd
  FROM (SELECT tool_input FROM tool_calls WHERE tool_name = 'Shell') LIMIT 5"

Fehler behandeln, ohne zu überlasten

Jeder Fehler ist eine saubere stderr-Nachricht + Exit-Code – lesen Sie sie und ergreifen Sie die passende Aktion, wiederholen Sie nicht:

NachrichtExitBedeutung / nächste Aktion
error: empty query (…)2Es wurde kein SQL übergeben. Geben Sie eine Anweisung an.
error: no warehouse found at … — run \stockroom ingest` first`1Das Warehouse wurde nicht erstellt. Weisen Sie den Benutzer an, stockroom ingest auszuführen (oder sr-initialize, wenn das Rechnersystem nie eingerichtet wurde); wiederholen Sie die Abfrage nicht.
query failed: …1Ungültiges SQL oder ein Schreibvorgang wurde abgelehnt. Korrigieren Sie die Anweisung (lesen Sie die DuckDB-Nachricht) – führen Sie dasselbe SQL nicht erneut aus.

Was sich im Warehouse befindet

Ermitteln Sie zuerst das Live-Schema – dies bleibt korrekt, während sich das Schema weiterentwickelt:

stockroom query "SELECT table_name, column_name, data_type
  FROM information_schema.columns ORDER BY table_name, ordinal_position"

Kurzreferenz der tragenden Spalten ab Migrationen 0001–0008 (bestätigen Sie mit der Introspectionsabfrage oben):

  • sessions – eine Zeile pro Konversation. harness ('cursor'|'claude'), session_id, project_id (wörtlicher Projektverzeichnis-Slug – das Gruppierungskriterium; für Cursor-CLI-Chats ist dies das Chats-Hash-Verzeichnis), cwd (echter Pfad, kann NULL sein), workspace_key (Pfad-Zusammenfassung über Harnesses hinweg, kann NULL sein), entrypoint (Oberflächenherkunft vom Harness, wenn bekannt; kann NULL sein – verwenden Sie SELECT DISTINCT entrypoint anstatt Literale zu erraten), models (VARCHAR[], nur Cursor), title, git_branch, is_subagent, parent_session_id, started_at, ended_at, source_mtime (Änderungszeitpunkt des Quelltranskripts beim letzten Import) und vier nullable Session-granulare Token BIGINTs (input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens – nur gefüllt, wenn ein Harness Konversationsnutzung meldet; Claude/Cursor lassen sie NULL). PK (harness, session_id).
  • messages – eine Zeile pro Turn. message_id = '{session_id}#{ordinal}' (einheitlich über Harnesses hinweg), parent_id, ordinal, role ('user'|'assistant'), text (gesamter Text; Thinking wird nicht erfasst), model (pro Nachricht, nur Claude), ts, first_seen_at (wann Stockroom die Nachricht erstmals beobachtet hat) und vier Token BIGINTs: input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens (Claude-Nachrichtennutzung; Cursor NULL). PK (harness, session_id, message_id).
  • session_token_usage – VIEW über Sessions + Nachrichten-Token-Summen. Bevorzugen Sie diese für Konversationszusammenfassungen. Spalten: *_from_messages (SUM), *_native (Session-Spalten), *_total (COALESCE(native, from_messages)), token_grain ('session'|'message'|'none'). Summen sind Warehouse-Aggregationen gemeldeter Felder, keine Rechnungen des Anbieters. Summieren Sie nicht auch noch SUM von Nachrichten-Tokens zusätzlich zu *_total.
  • tool_calls – Tool-Eingaben nur (niemals Ausgaben). message_id (der Turn, der sie ausgelöst hat), ordinal, tool_name, tool_input (heterogenes JSON, vollständig gespeichert – siehe die Schutzmaßnahme). PK (harness, session_id, message_id, ordinal).
  • embeddings – chunkweise Vektoren für semantische Suche (owner_table, owner_id, chunk_index, embed_model, vector FLOAT[384]). Sie fragen dies selten direkt ab – verwenden Sie das sr-semantic-Skill.
  • _sync_state – Import-Wasserzeichen-Buchhaltung; nicht interessant zum Abfragen.

Eine Identitätsregel, die Sie kennen sollten, bevor Sie einen Join schreiben: Joinen Sie immer über die einheitliche message_id / (harness, session_id), niemals über die source_*-Herkunftsspalten. Ein Wert, der nur in einer Granularität pro Harness existiert, ist ehrlicherweise NULL für die andere (z. B. messages.model ist nur Claude; sessions.models ist nur Cursor; dieselbe Dual-Granularitäts-Ehrlichkeit gilt für Tokens).

Ausgearbeitete Beispiele

Alle gegen ein echtes Warehouse verifiziert.

# Welche Harnesses sind vorhanden? (tsv Standard)
stockroom query "SELECT DISTINCT harness FROM sessions ORDER BY harness"

# Session-Zählungen pro Harness, menschenlesbar für einen Benutzer:
stockroom query --format table "SELECT harness, count(*) AS n FROM sessions GROUP BY harness ORDER BY n DESC"

# Meistgenutzte Tools:
stockroom query "SELECT tool_name, count(*) AS calls FROM tool_calls GROUP BY tool_name ORDER BY calls DESC LIMIT 5"

# Kandidaten-Nachrichten günstig scannen, dann die gewünschte vollständig abrufen:
stockroom query --detail compact "SELECT message_id, text FROM messages WHERE text ILIKE '%flaky test%' LIMIT 10"
stockroom query --format json --detail raw \
  "SELECT text FROM messages WHERE message_id = '<id-from-the-scan>'"

# Strukturierte Ausgabe für einen Benutzer/ein Tool zur Weiterverarbeitung:
stockroom query --format json "SELECT harness, session_id, title FROM sessions WHERE title IS NOT NULL LIMIT 5"

# Token-Zusammenfassungen pro Session (VIEW session_token_usage):
stockroom query --format table \
  "SELECT harness, session_id, input_tokens_total, output_tokens_total, token_grain
   FROM session_token_usage
   ORDER BY input_tokens_total DESC NULLS LAST
   LIMIT 10"

Weitere Varianten (unbegrenzte Tools mit Aktivitätsfenster, Tag/Harness-Token-Zusammenfassungen, SQL für Skill-Nutzung pro Harness): siehe das Cookbook.

Kochbuch

Kniffliges Start-SQL: references/cookbook/. Öffnen Sie das Inhaltsverzeichnis, dann nur das Rezept, das Sie benötigen.

Weiterleitung an einen Menschen

Sie sind der Bediener des Tools, nicht dessen Anzeige. Führen Sie das SQL aus, lesen Sie das Ergebnis und antworten Sie dem Benutzer in natürlicher Sprache. Fügen Sie kein rohes TSV bei einem Menschen ein, es sei denn, er hat danach gefragt. Wenn er doch die rohe Ausgabe möchte – oder einen Befehl, den er selbst ausführen kann – reichen Sie ihm eine --format table-Variante (zum Lesen) oder --format json (zum Verarbeiten).

Das System verstehen

Um zu verstehen, warum diese Verträge so aussehen, wie sie aussehen – die Paketierung, der Torch-Vertrag, schreibgeschützt durch Konstruktion, die Kürzungsdoktrin, Identität/Herkunft – lesen Sie das gemeinsame Systemmodell: ../sr-search/references/system-model.md.

Verwandte Skills