マキモノ
開発プロセス無料✅ 公式検証済みv1.0.0 / 更新

Claude Code の会話ログを自動退避しても VSCode のタブを壊さない(state.vscdb で開いているセッションを検出)

セッション一覧の自動整理で jsonl を動かすと VSCode 拡張のタブが「Couldn't load this conversation's saved history」になる。拡張が state.vscdb に平文で持つセッション ID をバイト検索して、参照中のログは理由を問わず動かさないガードの実装・テスト・復旧手順。

出品者: nishi@orgiast.jp📖 読込 約2,537トークン (約4円)💰 コスパ 32倍
トークン節約メーター91%節約
ゼロからAIに作らせた場合約9万トークン
このMDを読ませた場合約8,000トークン

約8.2万トークンの節約 (API料金換算で約120円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

「Claude Code の会話ログを自動退避しても VSCode のタブを壊さない(state.vscdb で開いているセッションを検出)」は、開発プロセスカテゴリのAI指示書(MDファイル)です。セッション一覧の自動整理で jsonl を動かすと VSCode 拡張のタブが「Couldn't load this conversation's saved history」になる。拡張が state.vscdb に平文で持つセッション ID をバイト検索して、参照中のログは理由を問わず動かさないガードの実装・テスト・復旧手順。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約8.2万トークン(API料金換算で約120円)・91%のトークンを節約できます。

カテゴリ
開発プロセス
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約9万トークン
この巻物使用時
約8,000トークン
節約量
約8.2万トークン (約120円)
更新日
2026-10-10

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/claude-code-vscode-state-vscdb/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

Claude Code の会話ログを自動退避しても VSCode のタブを壊さない(state.vscdb で「まだ開いているセッション」を検出する)

この指示書が解く問題

Claude Code のセッション一覧を自動で整理するために ~/.claude/projects/<project>/<sessionId>.jsonl を別フォルダへ移動する仕組みを入れると、 VSCode 拡張(Claude Code for VS Code)で開いたままのタブを次に触った瞬間に次の赤い帯が出て、会話を続けられなくなる。

Couldn't load this conversation's saved history, so it can't be continued.
Start a new conversation · View output logs · Troubleshooting resources

症状の正体は --resume <sessionId> の not_found。拡張はタブ・ブックマーク・UI でアーカイブしたセッションの ID を VSCode の状態DB(SQLite)に平文で持ち続けるので、ファイルだけ動かすと「一覧には残るのに中身が無い」状態になる。

拡張自身の自動アーカイブ設定 claudeCode.archiveInactiveSessions は「開いている・実行中・入力待ち・未読のセッションは絶対に対象にしない」と明記している。 自作の退避スクリプトも同じ原則に揃えればよい。

拡張がセッション ID を持っている場所(実測: 拡張 2.1.x)

ファイルキー中身
<User>/workspaceStorage/<hash>/state.vscdbmemento/workbench.parts.editor開いているエディタ(タブ)のシリアライズ。セッション ID を含む
同上Anthropic.claude-codepanelTabSessions[].sessionId(パネルのタブ)、bookmarkedSessions[]
<User>/globalStorage/state.vscdbAnthropic.claude-codehiddenSessionIds[](UI でアーカイブ済み。「Archived sessions」から再開できる)

<User> は win32 %APPDATA%\Code\User、macOS ~/Library/Application Support/Code/User、Linux ~/.config/Code/User(Insiders は Code - Insiders)。

ID は UTF-8 の平文で入っているので、SQLite を解釈せずバイト列の部分一致で判定できる。読むだけで、書き込みは絶対にしない(VSCode が開いている DB を書き換えると壊れる)。

退避スクリプトに入れるガード(Node.js)

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';

function entries(dir) { try { return fs.readdirSync(dir, { withFileTypes: true }); } catch (e) { if (e.code === 'ENOENT') return []; throw e; } }

// VSCode の状態DBのパス一覧。ORGIAST_VSCODE_USER_DIRS はテスト用の上書き(path.delimiter 区切り)。
function vscodeStateFiles() {
  const override = process.env.VSCODE_USER_DIRS;
  const dirs = override !== undefined ? override.split(path.delimiter).filter(Boolean)
    : ['Code', 'Code - Insiders'].map(product => {
      if (process.platform === 'win32') return path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), product, 'User');
      if (process.platform === 'darwin') return path.join(os.homedir(), 'Library', 'Application Support', product, 'User');
      return path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), product, 'User');
    });
  const files = [];
  for (const dir of dirs) {
    files.push(path.join(dir, 'globalStorage', 'state.vscdb'));
    for (const entry of entries(path.join(dir, 'workspaceStorage'))) {
      if (entry.isDirectory()) files.push(path.join(dir, 'workspaceStorage', entry.name, 'state.vscdb'));
    }
  }
  return files;
}

// 1 パスで 1 回だけ読む。読めない DB があれば「全件見送り」に倒す(フェイルセーフ)。
function vscodeReferences() {
  const buffers = []; let unreadable = false, files;
  try { files = vscodeStateFiles(); } catch { return { buffers, unreadable: true }; }
  for (const file of files) {
    try { buffers.push(fs.readFileSync(file)); }
    catch (error) { if (error.code !== 'ENOENT') unreadable = true; }
  }
  return { buffers, unreadable };
}

// 退避ループの中(transcript を読む前)で:
//   const refs = vscodeRefs ??= vscodeReferences();
//   if (refs.unreadable) { result.vscodeState = 'unreadable'; continue; }
//   if (refs.buffers.some(b => b.includes(sessionId))) { result.protected++; continue; }

ポイント:

  • 判定は 退避理由を問わず(明示クローズも含めて)かける。ユーザーがタブを ✕ で閉じれば DB から ID が消え、次のパスで通常どおり退避される。
  • hiddenSessionIds も保護対象にする。UI でアーカイブ済みのセッションは「Archived sessions」から再開できるので、ファイルを動かすとそこでも同じ赤い帯が出る。
  • 判定を transcript の読み込みより前に置くと、走査予算も節約できる。

テストの書き方(node:test)

本物の SQLite を作る必要はない。バイト列の部分一致だけが判定なので、ヘッダ風のバイト + "sessionId":"<id>" を含む Buffer を state.vscdb として置けばよい。

fs.writeFileSync(db, Buffer.concat([
  Buffer.from('SQLite format 3\0', 'utf8'), Buffer.alloc(48, 7),
  Buffer.from('"sessionId":"tab-open"', 'utf8'),
]));
  • 参照ありの tab-* は全理由で残り、参照なしの free-* は退避される、を --dry-run と実走の両方で assert する。
  • globalStorage/state.vscdb をディレクトリとして作ると readFileSync が EISDIR になるので、「読めない DB → 全件見送り」の分岐もテストできる。
  • テストの環境変数で DB の探索先を一時ディレクトリに向けること(向けないと実機の DB を読んで flaky になる)。

既に壊れたタブの復旧

  1. 退避先から元の場所へ戻す(ファイル名はそのまま。サイドカーのディレクトリ <sessionId>/ があれば一緒に戻す)。
  2. 戻した直後に次の退避パスで再び対象にならないよう、復元した ID を一定時間「稼働中」扱いにするか、上のガードを先に入れてから戻す。
  3. VSCode 側はタブを一度 ✕ で閉じ、左のセッション一覧から開き直す。赤い帯が出た時に送った最後のメッセージは保存されていないので送り直す。

「退避済みなのに VSCode がまだ参照している ID」の一覧は、退避フォルダの *.jsonl の ID を state.vscdb 群に bytes.find するだけで作れる(Python 10 行)。

副作用と割り切り

  • 開きっぱなしのタブは自動では一覧から消えなくなる。一覧の整理は拡張の claudeCode.archiveInactiveSessions に任せるのが筋(開いているものは触らず、再開可能なまま隠す)。
  • lastActivationSessionId やターミナル履歴に残る ID も保護されるが、せいぜい数件で実害はない。保護側に倒す方が「再開不能」より安い。

よくある質問

+「Claude Code の会話ログを自動退避しても VSCode のタブを壊さない(state.vscdb で開いているセッションを検出)」とは何ですか?

セッション一覧の自動整理で jsonl を動かすと VSCode 拡張のタブが「Couldn't load this conversation's saved history」になる。拡張が state.vscdb に平文で持つセッション ID をバイト検索して、参照中のログは理由を問わず動かさないガードの実装・テスト・復旧手順。

+どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約9万トークンかかりますが、この巻物を使えば約8,000トークンで済みます。差し引き約8.2万トークン(API料金換算で約120円)・91%の節約です。

+どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

+どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

+商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア