跳轉到

SpecStory 內部機制——檔名演算法、反向查找、markdown 結構

Terminology rule (zh-TW pages)

技術名詞首次出現以「中文 (English original)」格式呈現,例:依賴注入 (dependency injection)。不自創翻譯——若無公認譯名直接保留英文 (如 embeddingtokenizer)。代碼、API 名、CLI flag、套件名、檔名一律不翻。

關於 SpecStory 寫入 .specstory/history/*.md 的內容,以及本 repo 的 tv agent-sessions 通道如何將即時編碼代理 (coding agent) 工作階段 (session) 連回那些檔案的參考。安裝 / 設定 / provider 請參閱 SpecStory CLI

本頁說明的是輸出格式,而非執行期。當您想做以下事情時可閱讀:

  • 將即時 session id(來自 claude --resume / codex resume / cursor-agent --resume)對應回其 .specstory/history/*.md
  • 程式化地 grep SpecStory 轉譯 (transcript)(agent、模型、時間戳全為純文字標記)。
  • 在他處重新渲染 SpecStory 轉譯(其結構刻意保持簡單)。

SpecStory CLI 為 Go、BSD 3-Clause,原始碼在 https://github.com/specstoryai/getspecstory。DeepWiki 在 https://deepwiki.com/specstoryai/getspecstory 有產生的技術參考,對熟悉架構也很有用。

檔名演算法

格式YYYY-MM-DD_HH-MM-SS[Z|±HHMM]-<slug>.md

對本 repo .specstory/history/ 中的檔案實證驗證:

範例 備註
2026-04-24_09-09-09Z-commit-commit-backup-e.md 目前預設(UTC、含秒數)
2026-03-30_11-20-14+0800-utility-function-bash-hash.md --local-time-zone 模式(非 UTC 偏移量)
2026-02-10_10-41Z-git-commit-history-modification.md 較舊格式(UTC、無秒數)——較舊 CLI 版本,並未追溯重新命名
2026-04-24_06-54-14Z.md 空 slug——沒有合格的首則使用者訊息

時間戳來源:對 session 的 CreatedAt 進行 RFC3339 解析——SpecStory 看到的第一筆 JSONL / SQLite 記錄的時間戳,通常即為首則使用者訊息。預設為 UTC;--local-time-zone 切換為數值偏移量。

Slug:首則真實(非合成)使用者訊息的前 4 個詞,經過:

  1. 剝除 IDE 注入的 XML context 標籤(<ide_opened_file><environment_context> 等)。
  2. Unicode NFD 正規化 + 剝除重音;轉小寫。
  3. @at&and#hash
  4. 剝除剩餘的標點;以空白分割。
  5. 取前 4 個詞,以 - 連接。

空 slug(尚無合格的使用者訊息)會產生只有時間戳的檔名。

Session id 不在檔名中。 它以 HTML 註解形式嵌入內文第 5 行——見下一節。

原始碼指標(截至目前 dev 分支):

職責 Package / function
檔名時間戳格式 pkg/session/session.goFormatFilenameTimestamp
最終路徑組裝 pkg/session/session.goBuildSessionFilePath
從首則使用者訊息產生 slug pkg/spi/path_utils.goGenerateFilenameFromUserMessage
Claude 專屬的 slug 取法 pkg/providers/claudecode/provider.goFileSlugFromRootRecord
Markdown 內文產生 pkg/outputgen/GenerateMarkdown / writeMarkdownToFile

碰撞處理

  • 磁碟上 byte-identical 內容 → 寫入會被略過("up to date")。
  • 時間戳 + slug 相同但內容不同 → 第二次寫入會覆寫。未文件化;實務上罕見(需要兩個 session 在同一秒內以相同前 4 個詞開始)。

歷史檔案不會被遷移。 若格式演進(例如某時點起新增了秒數),既有的 .specstory/history/*.md 維持原樣。

反向查找——session id → markdown 檔

每個檔案以固定的前置序言開頭(第 5 行為關鍵行):

<!-- Generated by SpecStory, Markdown v2.1.0 -->

# YYYY-MM-DD HH:MM:SSZ

<!-- <Provider-display-name> Session <uuid> (YYYY-MM-DD HH:MM:SSZ) -->

本 repo .specstory/history/ 中觀察到的 provider 顯示名稱:

HTML 註解中的字串 用於 specstory run <id> 的 Provider ID
Claude Code claudecode
cursoride(Cursor IDE composer chat) —(由 Cursor IDE 擴充寫入,非 CLI)
Codex codexcli
OpenCode (尚未——見 backlog/specstory-opencode-support.md)
Gemini geminicli
(此處未見) Droid droidcli
(此處未見) Cursor CLI cursorcli

<!-- ... Session <uuid> ... --> 行中的 UUID 與代理 resume flag 使用的 session id 完全相同claude --resume <uuid>codex resume <uuid>cursor-agent --resume <uuid>opencode --session <uuid>)。這使得 session id → 轉譯檔的對應變成跨 provider 一致的單行 grep:

grep -l "Session ${sid}" .specstory/history/*.md

SpecStory CLI 沒有內建的 resolve <sid> → path 子命令。 已記載的命令是 specstory run / specstory sync / specstory watch。上面的 grep 配方就是受支援的路徑。

關於 tv agent-sessions 通道的整合,見 dot_config/television/executable_agent-sessions.py——它在啟動時會從 ~/.local/share/chezmoi/.specstory/history/ 快取對應表,並將比對到的路徑作為 TSV 第 5 欄(綁定 Alt+S 以複製)暴露出來。

Markdown 內文結構

SpecStory(pkg/outputgen/)寫出的概略骨架:

<!-- Generated by SpecStory, Markdown v2.1.0 -->

# 2026-04-24 09:09:09Z

<!-- Claude Code Session <uuid> (2026-04-24 09:09:09Z) -->

_**User (2026-04-24 09:09:09Z)**_

<first user prompt>

---

_**Agent (claude-opus-4-7 2026-04-24 09:09:13Z)**_

<think><details><summary>Thought Process</summary>
<thinking-block text>
</details></think>

<assistant reply prose>

<tool-use data-tool-type="shell" data-tool-name="Bash"><details>
<summary>Tool use: **Bash**</summary>
<tool invocation JSON + output>
</details></tool-use>

---

_**User**_

關鍵元素:

  • 角色標頭為斜體粗體,可選地附帶模型 + 時間戳:_**User (ts)**__**Agent (<model> <ts>)**_
  • --- 分隔對談的不同回合。
  • Thinking 區塊為摺疊的 <details>,外層用 <think> 標籤包起來。
  • Tool use 為摺疊的 <details>,置於帶 data-tool-typedata-tool-name 屬性的 <tool-use> 標籤內。
  • Tool I/O 周圍沒有 fenced code block——<details> 載荷為原始文字 / JSON。

glowbat 都能乾淨渲染。<think><tool-use> 是非標準 HTML 元素;在 glow 的 HTML 直通模式下會以可摺疊區段呈現。

注意事項

  • 雲端同步失敗永不影響本機檔案。 SpecStory 先寫入本機 markdown;雲端同步失敗只會中止上傳。
  • --only-cloud-sync 完全略過本機寫入。 若使用該 flag,.specstory/history/ 不會增長——反向查找表會是空的。
  • --no-cloud-sync 則相反——本機寫入照常,雲端同步停用。
  • --debug-raw 將原始 session 記錄傾印.specstory/debug/,與 markdown 並列——當轉譯看起來不對勁、想看 SpecStory 究竟看到什麼時很有用。
  • Provider ID 與顯示名稱不是同一字串。 specstory run claudecode 是 CLI ID;產生的 markdown 中 HTML 註解寫的是 Claude Code(含空格)。若您要對其中一個字串寫腳本,請挑對的——HTML 註解才是反向查找 grep 比對的對象。

參考資料