Community寫作與編輯github.com

Texarkanine/stockroom

一個本機、忠實且可搜尋的倉庫,記錄你的代理編碼歷史。

stockroom 是什麼?

`sr-query` 技能讓你對 Stockroom 倉庫(一個單一檔案的 DuckDB 資料庫,存放 Cursor 和 Claude Code 的歷史記錄)執行唯讀 SQL 查詢。其設計確保查詢不會損壞資料,因為 DuckDB 會拒絕任何寫入嘗試。此技能適合進行精確查找,例如依 ID 擷取特定行、計算聚合值(如計數、總和)或合併多個表格。它不適合語意搜尋(請改用 `sr-semantic`),且會自動截斷寬欄位(如訊息文字)以防止上下文爆量。輸出格式預設為 TSV,但也可切換為 JSON 或表格格式。如果 `stockroom` 指令不可用,系統會提示使用者先執行 `sr-initialize` 來建置倉庫。

相容平台✓Claude Code~Codex CLI✓Cursor✓Antigravity
npx skills add Texarkanine/stockroom

Installed? Explore more 寫作與編輯 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

sr-query

sr-query 對 stockroom 倉庫執行唯讀 SQL——這個單一檔案的 DuckDB 資料庫儲存了您擷取的 Cursor + Claude Code 歷史記錄。該介面天生是唯讀的:DuckDB 會拒絕任何透過它嘗試的寫入操作,因此您不會因查詢而損壞任何資料。

何時使用 sr-query

當問題具有已知形狀,且答案是對您能命名的欄位進行精確或結構化查詢時,請使用 sr-query:

  • 依 ID 查詢特定行(WHERE message_id = '…'、WHERE session_id = '…')。
  • 篩選、計數和彙總(COUNT(*)、GROUP BY harness、WHERE harness = 'claude'、Token 總和、日期範圍)。
  • 透過 VIEW session_token_usage 進行每場對話的 Token 彙總(優先於在 messages 上手動撰寫 SUM)。
  • 跨 sessions / messages / tool_calls 的聯結。
  • “有多少個”、“哪些對話”、“列出工具呼叫”、“用了哪些模型”——任何你能以 SQL 表達並對應到已命名欄位的內容。

不要將 sr-query 用於基於意義的回憶(例如“尋找關於不穩定測試的對話”)。SQL 的 ILIKE 是字面子字串比對,不是語意搜尋——如需意義搜尋,請使用 sr-semantic 技能。當您不確定該用哪一個時,請由 sr-search 技能來判斷。

如何呼叫引擎

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

您也可以透過標準輸入以 - 傳入 SQL:

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

如果 command -v stockroom 失敗,表示機器尚未設定好:請告知使用者執行 sr-initialize 技能,且不要嘗試其他呼叫方式。

輸出規範:--format 與 --detail

預設值對代理來說已經很安全——單純呼叫即可提供有界、可解析的輸出——因此僅在特定情況需要時才使用這些旗標。

--format——輸出形狀,預設為 tsv

值形狀使用時機
tsv (預設)標題行 + 以 Tab 分隔的行,無計數結尾預設。對您和 Unix 管道(cut、awk、wc -l)都友善。
json單個 {"columns": [...], "rows": [...]} 物件使用者要求結構化/機器輸出,或您想將其傳給 jq。
table欄位對齊的 ASCII 格式,附帶 (N rows) 結尾使用者要求人類可讀的格式 / 一個可複製貼上查看的命令。

優先使用預設的 tsv。當使用者要求人類可讀或結構化輸出時才提供 --format table 或 --format json——“這些其他形狀在您需要時可以使用。”

--detail——每個欄位的寬度,預設為 snippet

寬字串欄位(特別是 messages.text 和 tool_calls.tool_input)會在讀取時被截斷,以避免單一大型欄位充滿您的上下文。截斷僅影響顯示——完整文字隨時可擷取。

值每個欄位的大小使用時機
compact約 40 個字元在選定一行之前,快速掃描多個候選行以節省成本。
snippet (預設)約 120 個字元預設。足以辨識一行,而不必完全傾印它。
full無限制,單行您需要欄位的完整長度,且單行折疊是可接受的(表格/TSV 仍保持安全)。
raw無限制,保留原始空白您需要儲存狀態下的文字——保留換行和內部空白。建議搭配 --format json 使用。

超出預算的欄位會以標記省略,報告隱藏了多少字元,例如 …(+2284)。這個標記是您的信號,表示還有更多內容:如果您確實需要它,請以 --detail full(長度)或 --format json --detail raw(精確空白)僅針對該特定行的該欄位重新擷取——請參閱防護機制。

防護機制

以下是此技能旨在防止的失敗模式:

  • 不要爆掉你的上下文。 永遠不要對多行執行 SELECT *(或寬的 text 欄位)並使用 --detail full/raw。改為:以 --detail compact/snippet 搭配明確的欄位列表和 LIMIT 進行窄範圍掃描,找出您要的那一行,然後用 WHERE 條件依據其 ID 僅重新擷取該行的寬欄位。一個 SELECT text FROM messages WHERE message_id = '…' 是成本低廉的;SELECT * FROM messages --detail full 則是一個上下文炸彈。當您需要精確的空白(Markdown 表格、程式碼區塊)時,請使用 --format json --detail raw。
  • 它是唯讀的——永遠不要嘗試寫入。 INSERT / UPDATE / DELETE / CREATE 都會失敗(query failed: …)。不要透過不同的措辭重試寫入;該介面僅供查詢。
  • tool_input 是異質的 JSON。 其鍵值因工具而異(Shell 有 command、Read 有 path……),因此單純使用 tool_input->>'key' 可能會引發型別轉換錯誤。請透過在子查詢/CTE 中先篩選 tool_name 並使用明確的函式來安全地提取:
stockroom query "SELECT json_extract_string(tool_input, '\$.command') AS cmd
  FROM (SELECT tool_input FROM tool_calls WHERE tool_name = 'Shell') LIMIT 5"

處理錯誤時不要盲目重試

每個失敗都會有一個乾淨的 stderr 訊息 + 退出碼——讀取它並採取對應的行動,不要迴圈重試:

訊息退出碼意義 / 下一步行動
error: empty query (…)2沒有傳入 SQL。請提供一個陳述式。
error: no warehouse found at … — run \stockroom ingest` first`1倉庫尚未建立。告知使用者執行 stockroom ingest(如果機器從未設定過,則執行 sr-initialize);不要重試查詢。
query failed: …1SQL 無效,或寫入被拒絕。修正陳述式(閱讀 DuckDB 的錯誤訊息)——不要重新執行相同的 SQL。

倉庫中有什麼

先探索即時綱要——這樣才能隨著綱要演進保持正確:

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

截至遷移 0001–0008 為止承載主要資料的欄位快速參考(請透過上面的內省查詢進行確認):

  • sessions——每個對話一行。harness('cursor'|'claude')、session_id、project_id(直接取自專案目錄的 slug——分組鍵;對於 Cursor CLI 聊天,這是聊天雜湊目錄)、cwd(真實路徑,可能為 NULL)、workspace_key(跨 harness 的路徑彙總,可能為 NULL)、entrypoint(來自 harness 的表面來源,已知時提供;可能為 NULL——請使用 SELECT DISTINCT entrypoint 而非猜測字面值)、models(VARCHAR[],僅限 Cursor)、title、git_branch、is_subagent、parent_session_id、started_at、ended_at、source_mtime(最後一次擷取時的來源轉錄檔修改時間),以及四個可為 null 的對話層級 Token BIGINT 欄位(input_tokens、output_tokens、cache_creation_tokens、cache_read_tokens——僅當 harness 報告對話層級使用量時才會填入;Claude/Cursor 會將其留為 NULL)。主鍵 (harness, session_id)。
  • messages——每輪對話一行。message_id = '{session_id}#{ordinal}'(在所有 harness 中一致)、parent_id、ordinal、role('user'|'assistant')、text(完整內容;不包含思考過程)、model(每條訊息,僅限 Claude)、ts、first_seen_at(stockroom 首次觀察到該訊息時),以及四個 Token BIGINT 欄位:input_tokens、output_tokens、cache_creation_tokens、cache_read_tokens(Claude 的訊息使用量;Cursor 為 NULL)。主鍵 (harness, session_id, message_id)。
  • session_token_usage——基於 sessions 與訊息 Token 總和的 VIEW。進行對話層級彙總時優先使用此檢視。欄位:*_from_messages(SUM)、*_native(session 欄位)、*_total(COALESCE(native, from_messages))、token_grain('session'|'message'|'none')。總數是倉庫對回報欄位的彙總,並非廠商發票。請勿在 *_total 之上再 SUM 訊息 Token。
  • tool_calls——僅包含工具輸入(絕不包含輸出)。message_id(發出該呼叫的輪次)、ordinal、tool_name、tool_input(異質 JSON,完整儲存——請參閱防護機制)。主鍵 (harness, session_id, message_id, ordinal)。
  • embeddings——用於語意搜尋的每個區塊向量(owner_table、owner_id、chunk_index、embed_model、vector FLOAT[384])。您很少直接查詢此表——請使用 sr-semantic 技能。
  • _sync_state——擷取水印的記帳資訊;查詢時不感興趣。

在撰寫聯結前值得了解一個身分規則:始終在統一的 message_id / (harness, session_id) 上進行聯結,絕不使用 source_* 來源欄位。一個值如果在每個 harness 中只存在於一種粒度,那麼對另一種粒度來說它就是 NULL(例如 messages.model 僅限 Claude;sessions.models 僅限 Cursor;Token 欄位也遵循相同的雙粒度誠實原則)。

工作範例

所有範例均已在真實倉庫中驗證。

# 有哪些 harness 存在?(tsv 預設)
stockroom query "SELECT DISTINCT harness FROM sessions ORDER BY harness"

# 每個 harness 的對話計數,人類可讀格式:
stockroom query --format table "SELECT harness, count(*) AS n FROM sessions GROUP BY harness ORDER BY n DESC"

# 最常用的工具:
stockroom query "SELECT tool_name, count(*) AS calls FROM tool_calls GROUP BY tool_name ORDER BY calls DESC LIMIT 5"

# 低成本掃描候選訊息,然後完整重新擷取目標訊息:
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>'"

# 為使用者/工具提供結構化輸出:
stockroom query --format json "SELECT harness, session_id, title FROM sessions WHERE title IS NOT NULL LIMIT 5"

# 每場對話的 Token 彙總(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"

更多變體(無界工具與活動時間窗、每日/harness Token 彙總、每個 harness 的技能使用 SQL):請參閱食譜。

食譜

進階入門 SQL:references/cookbook/。開啟索引,然後只找您需要的配方。

回報給人類

您是工具的操作者,而非顯示器。執行 SQL,讀取結果,然後以自然語言回答使用者。除非使用者要求,否則不要將原始 tsv 貼給人類。當他們確實想要原始輸出——或一個可自行執行的命令時——提供 --format table(供閱讀)或 --format json(供處理)的變體。

理解系統

想了解為什麼這些合約會是這樣的形式——打包方式、火炬合約、唯讀架構、截斷原則、身分/來源——請閱讀共用的系統模型:../sr-search/references/system-model.md。

相關技能