throughline 0.3.24 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.claude/commands/tl.md +6 -21
  2. package/.codex-sidecar.yml +62 -0
  3. package/CHANGELOG.md +632 -0
  4. package/README.ja.md +71 -46
  5. package/README.md +420 -76
  6. package/bin/throughline.mjs +169 -7
  7. package/codex/skills/throughline/SKILL.md +157 -0
  8. package/codex/skills/throughline/agents/openai.yaml +7 -0
  9. package/docs/INHERITANCE_ON_CLEAR_ONLY.md +159 -0
  10. package/docs/L1_L2_L3_REDESIGN.md +415 -0
  11. package/docs/PUBLIC_RELEASE_PLAN.md +185 -0
  12. package/docs/THROUGHLINE_CLEAR_AUTO_HANDOFF_PLAN.md +286 -0
  13. package/docs/THROUGHLINE_CODEX_DUAL_SUPPORT.md +249 -0
  14. package/docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md +555 -0
  15. package/docs/THROUGHLINE_CODEX_MONITOR_IMPLEMENTATION_PLAN.md +220 -0
  16. package/docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md +528 -0
  17. package/docs/THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md +672 -0
  18. package/docs/archive/CONCEPT.md +476 -0
  19. package/docs/archive/EXPERIMENT.md +371 -0
  20. package/docs/archive/README.md +22 -0
  21. package/docs/archive/SESSION_LINKING_DESIGN.md +231 -0
  22. package/docs/archive/THROUGHLINE_NEXT_STEPS.md +134 -0
  23. package/docs/throughline-codex-trim-rollback-incident-report.md +306 -0
  24. package/docs/throughline-handoff-context.example.json +57 -0
  25. package/docs/throughline-rollback-context-trim-insight.md +455 -0
  26. package/package.json +6 -2
  27. package/src/baton.mjs +17 -45
  28. package/src/baton.test.mjs +4 -41
  29. package/src/cli/codex-capture.mjs +95 -0
  30. package/src/cli/codex-handoff-model-smoke.mjs +292 -0
  31. package/src/cli/codex-handoff-model-smoke.test.mjs +262 -0
  32. package/src/cli/codex-handoff-smoke.mjs +163 -0
  33. package/src/cli/codex-handoff-smoke.test.mjs +149 -0
  34. package/src/cli/codex-handoff-start.mjs +291 -0
  35. package/src/cli/codex-handoff-start.test.mjs +194 -0
  36. package/src/cli/codex-hook.mjs +276 -0
  37. package/src/cli/codex-hook.test.mjs +293 -0
  38. package/src/cli/codex-host-primitive-audit.mjs +110 -0
  39. package/src/cli/codex-host-primitive-audit.test.mjs +75 -0
  40. package/src/cli/codex-restore-smoke.mjs +357 -0
  41. package/src/cli/codex-restore-source-audit.mjs +304 -0
  42. package/src/cli/codex-resume.mjs +138 -0
  43. package/src/cli/codex-rollback-model-visible-smoke.mjs +373 -0
  44. package/src/cli/codex-rollback-model-visible-smoke.test.mjs +255 -0
  45. package/src/cli/codex-sidecar-diagnostics.mjs +48 -0
  46. package/src/cli/codex-sidecar-dry-run.mjs +85 -0
  47. package/src/cli/codex-summarize.mjs +224 -0
  48. package/src/cli/codex-threads.mjs +89 -0
  49. package/src/cli/codex-visibility-smoke.mjs +196 -0
  50. package/src/cli/codex-vscode-restore-smoke.mjs +226 -0
  51. package/src/cli/codex-vscode-rollback-smoke.mjs +114 -0
  52. package/src/cli/doctor.mjs +503 -1
  53. package/src/cli/doctor.test.mjs +542 -3
  54. package/src/cli/handoff-preview.mjs +78 -0
  55. package/src/cli/help.test.mjs +64 -0
  56. package/src/cli/install.mjs +226 -3
  57. package/src/cli/install.test.mjs +205 -4
  58. package/src/cli/trim.mjs +564 -0
  59. package/src/codex-app-server.mjs +1816 -0
  60. package/src/codex-app-server.test.mjs +512 -0
  61. package/src/codex-auto-refresh.mjs +194 -0
  62. package/src/codex-auto-refresh.test.mjs +182 -0
  63. package/src/codex-capture.mjs +235 -0
  64. package/src/codex-capture.test.mjs +393 -0
  65. package/src/codex-handoff-model-smoke.mjs +114 -0
  66. package/src/codex-handoff-model-smoke.test.mjs +89 -0
  67. package/src/codex-handoff-smoke.mjs +124 -0
  68. package/src/codex-handoff-smoke.test.mjs +103 -0
  69. package/src/codex-handoff.mjs +331 -0
  70. package/src/codex-handoff.test.mjs +220 -0
  71. package/src/codex-host-primitive-audit.mjs +374 -0
  72. package/src/codex-host-primitive-audit.test.mjs +208 -0
  73. package/src/codex-restore-smoke.test.mjs +639 -0
  74. package/src/codex-restore-source-audit.mjs +1348 -0
  75. package/src/codex-restore-source-audit.test.mjs +623 -0
  76. package/src/codex-resume.test.mjs +242 -0
  77. package/src/codex-rollout-memory.mjs +711 -0
  78. package/src/codex-rollout-memory.test.mjs +610 -0
  79. package/src/codex-sidecar-cli.test.mjs +75 -0
  80. package/src/codex-sidecar.mjs +246 -0
  81. package/src/codex-sidecar.test.mjs +172 -0
  82. package/src/codex-summarize.test.mjs +143 -0
  83. package/src/codex-thread-identity.mjs +23 -0
  84. package/src/codex-thread-index.mjs +173 -0
  85. package/src/codex-thread-index.test.mjs +164 -0
  86. package/src/codex-usage.mjs +110 -0
  87. package/src/codex-usage.test.mjs +140 -0
  88. package/src/codex-visibility-smoke.test.mjs +222 -0
  89. package/src/codex-vscode-restore-smoke.mjs +206 -0
  90. package/src/codex-vscode-restore-smoke.test.mjs +325 -0
  91. package/src/codex-vscode-rollback-smoke.mjs +90 -0
  92. package/src/codex-vscode-rollback-smoke.test.mjs +290 -0
  93. package/src/db-schema.test.mjs +96 -0
  94. package/src/db.mjs +14 -1
  95. package/src/haiku-summarizer.mjs +267 -26
  96. package/src/haiku-summarizer.test.mjs +282 -0
  97. package/src/handoff-preview.test.mjs +108 -0
  98. package/src/handoff-record.mjs +294 -0
  99. package/src/handoff-record.test.mjs +226 -0
  100. package/src/hook-entrypoints.test.mjs +286 -0
  101. package/src/package-files.test.mjs +19 -0
  102. package/src/prompt-submit.mjs +9 -6
  103. package/src/resume-context.mjs +58 -171
  104. package/src/resume-context.test.mjs +177 -0
  105. package/src/session-start.mjs +85 -26
  106. package/src/state-file.mjs +50 -6
  107. package/src/state-file.test.mjs +50 -0
  108. package/src/token-monitor.mjs +14 -10
  109. package/src/token-monitor.test.mjs +27 -0
  110. package/src/trim-cli.test.mjs +1584 -0
  111. package/src/trim-model.mjs +584 -0
  112. package/src/trim-model.test.mjs +568 -0
  113. package/src/turn-processor.mjs +17 -10
  114. package/src/vscode-task.mjs +33 -10
  115. package/src/vscode-task.test.mjs +19 -9
  116. package/src/cli/save-inflight.mjs +0 -81
@@ -0,0 +1,476 @@
1
+ # Throughline — 構造化記憶による会話履歴最適化
2
+
3
+ > Claude Codeのコンテキスト肥大化を「捨てずに構造化」で解決するhooksプラグイン。
4
+ > SmartClaudeの実データ($4,211/月相当の利用分析)に基づいて設計。
5
+
6
+ **設計思想:セッション内完結。目的はコンテキスト削減によるコスト削減のみ。**
7
+ 永続的な知識資産の構築や、セッション横断の記憶管理は本プラグインのスコープ外とする。
8
+
9
+ ## 背景・課題
10
+
11
+ SmartClaudeの分析により判明した事実:
12
+
13
+ - **1ターンあたり平均188Kトークン**消費
14
+ - そのうち**履歴が164K(87%)**を占める
15
+ - CLAUDE.md(12.7K)やMCP(3.9K)の最適化では根本解決にならない
16
+ - 既存の `/compact` は全履歴を「要約」するだけ → **重要情報の欠落リスク**
17
+ - 履歴の大半は**Bashコマンドの入出力**(判断に使われた後は参照されない)
18
+
19
+ ## コンセプト
20
+
21
+ ### 現行 `/compact` の問題
22
+
23
+ 1. **全履歴を一括要約** — 直近の作業コンテキストも圧縮されてしまう
24
+ 2. **情報の取捨選択が曖昧** — モデルが「何が後で必要か」を予見できない
25
+ 3. **要約=情報損失** — 設計判断・制約条件など不可逆な情報が消える
26
+
27
+ ### Throughline のアプローチ
28
+
29
+ **「圧縮」ではなく「構造化」。古い部分だけ。直近はそのまま残す。何も捨てない。**
30
+
31
+ ---
32
+
33
+ ## 3層アーキテクチャ
34
+
35
+ 会話コンテキストをツリー構造で管理する。層ごとにコンテキスト注入の粒度を制御。
36
+
37
+ ```
38
+ Turn 7: 「ServerManagerを再起動して」
39
+
40
+ ├── Layer 1 (骨格) ← 常にコンテキストに存在
41
+ │ └── "ServerManager再起動 → 成功"
42
+
43
+ ├── Layer 2 (判断) ← 基本的にコンテキストに存在
44
+ │ ├── [DECISION] Electron起動検出にSleep 4秒必要
45
+ │ └── [ISSUE] 3秒では不足(起動ラグあり)
46
+
47
+ └── Layer 3 (詳細) ← コンテキスト外(SQLiteに永続化、オンデマンド参照)
48
+ ├── Get-Process → PID 19048 electron
49
+ ├── Stop-Process → stopped
50
+ ├── npm start → background ID: bazIqox0f
51
+ ├── Sleep 3 → Exit code 1(検出失敗)
52
+ └── Sleep 4 → Count 1(検出成功)
53
+ ```
54
+
55
+ ### 各層の定義
56
+
57
+ | Layer | 名称 | コンテキスト | 内容 | トークンコスト |
58
+ |-------|------|-------------|------|---------------|
59
+ | **L1** | 骨格 (Skeleton) | **常駐** | ターンの意図と結論。1行サマリ | 極小(~10 tok/turn) |
60
+ | **L2** | 判断 (Judgment) | **常駐** | 決定・制約・未解決問題。構造化タグ付き | 小(~50 tok/turn) |
61
+ | **L3** | 詳細 (Detail) | **退避** | コマンドIN/OUT、生レスポンス、スタックトレース | 大(~2,000+ tok/turn) |
62
+
63
+ ### 期待効果
64
+
65
+ ```
66
+ 従来: 1ターンあたり ~2,000+ トークン(生データ丸ごと)
67
+ SC後: 1ターンあたり ~60 トークン(L1 + L2のみ)
68
+ 削減率: 約97%
69
+ 情報損失: ゼロ(L3はSQLiteに全量保存、オンデマンドで参照可能)
70
+ ```
71
+
72
+ ### L2 分類カテゴリ
73
+
74
+ | カテゴリ | タグ | 説明 | 例 |
75
+ |---------|------|------|-----|
76
+ | 設計判断 | `DECISION` | 技術選定、方式決定 | "通信方式: WebSocket (port 443)" |
77
+ | 制約条件 | `CONSTRAINT` | 禁止事項、前提条件 | "ポート8080使用不可(FW制限)" |
78
+ | 背景情報 | `CONTEXT` | プロジェクト要件、状況 | "Windows / Linux両対応が必須" |
79
+ | 実装済み | `IMPL` | 完了した作業のサマリ | "トークンダッシュボード実装済み" |
80
+ | 未解決 | `ISSUE` | バグ、TODO、要検討事項 | "起動ラグにより検出タイミング要調整" |
81
+
82
+ ---
83
+
84
+ ## SQLite スキーマ設計
85
+
86
+ ### DB ファイル配置
87
+
88
+ ```
89
+ ~/.throughline/
90
+ ├── throughline.db # メインDB
91
+ ├── throughline.db-wal # WALモード(書き込み性能)
92
+ └── config.json # ユーザー設定
93
+ ```
94
+
95
+ ### テーブル設計
96
+
97
+ ```sql
98
+ -- セッション管理
99
+ CREATE TABLE sessions (
100
+ session_id TEXT PRIMARY KEY,
101
+ project_path TEXT NOT NULL,
102
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
103
+ last_active TEXT NOT NULL DEFAULT (datetime('now')),
104
+ total_turns INTEGER DEFAULT 0,
105
+ status TEXT DEFAULT 'active' -- active | compacted | closed
106
+ );
107
+
108
+ -- Layer 1: 骨格(ターンの1行サマリ)
109
+ CREATE TABLE skeletons (
110
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
111
+ session_id TEXT NOT NULL REFERENCES sessions(session_id),
112
+ turn_number INTEGER NOT NULL,
113
+ role TEXT NOT NULL, -- user | assistant
114
+ summary TEXT NOT NULL, -- "ServerManager再起動 → 成功"
115
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
116
+ UNIQUE(session_id, turn_number, role)
117
+ );
118
+
119
+ -- Layer 2: 判断(構造化された決定・制約・問題)
120
+ CREATE TABLE judgments (
121
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
122
+ session_id TEXT NOT NULL REFERENCES sessions(session_id),
123
+ turn_number INTEGER NOT NULL,
124
+ category TEXT NOT NULL, -- DECISION | CONSTRAINT | CONTEXT | IMPL | ISSUE
125
+ content TEXT NOT NULL, -- 構造化された判断内容
126
+ resolved INTEGER DEFAULT 0, -- ISSUEが解決済みかどうか
127
+ resolved_at TEXT,
128
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
129
+ );
130
+ CREATE INDEX idx_judgments_session_cat ON judgments(session_id, category);
131
+ CREATE INDEX idx_judgments_unresolved ON judgments(session_id, resolved) WHERE resolved = 0;
132
+
133
+ -- Layer 3: 詳細(コマンドIN/OUT、生データ)
134
+ CREATE TABLE details (
135
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
136
+ session_id TEXT NOT NULL REFERENCES sessions(session_id),
137
+ turn_number INTEGER NOT NULL,
138
+ tool_name TEXT, -- Bash | Write | Edit | Read | etc.
139
+ input_text TEXT, -- コマンド入力 / ツール引数
140
+ output_text TEXT, -- コマンド出力 / ツール結果
141
+ exit_code INTEGER,
142
+ token_count INTEGER, -- この詳細のトークン推定値
143
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
144
+ );
145
+ CREATE INDEX idx_details_session_turn ON details(session_id, turn_number);
146
+
147
+ -- コンテキスト注入ログ(デバッグ・分析用)
148
+ CREATE TABLE injection_log (
149
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
150
+ session_id TEXT NOT NULL REFERENCES sessions(session_id),
151
+ event_type TEXT NOT NULL, -- pre_compact | context_compaction | on_demand
152
+ layers_sent TEXT NOT NULL, -- "L1+L2" | "L1+L2+L3:turn7"
153
+ token_before INTEGER,
154
+ token_after INTEGER,
155
+ injected_at TEXT NOT NULL DEFAULT (datetime('now'))
156
+ );
157
+ ```
158
+
159
+ ### クエリ例
160
+
161
+ ```sql
162
+ -- コンテキスト注入用: L1+L2を生成(古いターンのみ)
163
+ SELECT
164
+ s.turn_number,
165
+ s.summary,
166
+ json_group_array(
167
+ json_object('category', j.category, 'content', j.content)
168
+ ) AS judgments
169
+ FROM skeletons s
170
+ LEFT JOIN judgments j ON s.session_id = j.session_id AND s.turn_number = j.turn_number
171
+ WHERE s.session_id = ?
172
+ AND s.turn_number < ? -- 直近Nターンより古いもの
173
+ GROUP BY s.turn_number
174
+ ORDER BY s.turn_number;
175
+
176
+ -- 未解決ISSUEだけ取得(常にコンテキストに含めるべき)
177
+ SELECT turn_number, content, created_at
178
+ FROM judgments
179
+ WHERE session_id = ? AND category = 'ISSUE' AND resolved = 0
180
+ ORDER BY turn_number;
181
+
182
+ -- オンデマンド: 特定ターンのL3詳細を取得
183
+ SELECT tool_name, input_text, output_text, exit_code
184
+ FROM details
185
+ WHERE session_id = ? AND turn_number = ?
186
+ ORDER BY id;
187
+
188
+ -- 分析: セッションごとのトークン削減効果
189
+ SELECT
190
+ session_id,
191
+ SUM(token_count) AS total_detail_tokens,
192
+ COUNT(*) AS detail_count
193
+ FROM details
194
+ GROUP BY session_id;
195
+ ```
196
+
197
+ ---
198
+
199
+ ## 処理フロー
200
+
201
+ ```
202
+ ┌─────────────────────────┐
203
+ │ Claude Code セッション │
204
+ └────────┬────────────────┘
205
+
206
+ ┌─────────▼─────────┐
207
+ │ PostToolUse Hook │ ← 毎ツール実行後
208
+ │ (detail-capture) │
209
+ └─────────┬─────────┘
210
+
211
+ ┌─────────▼─────────┐
212
+ │ L3をSQLiteに保存 │ ← リアルタイムで詳細を永続化
213
+ │ (tool名, IN/OUT) │
214
+ └─────────┬─────────┘
215
+
216
+ ┌─────────▼──────────┐
217
+ │ Stop Hook │ ← Claudeが応答完了するたび
218
+ │ (turn-processor) │
219
+ └─────────┬──────────┘
220
+
221
+ ┌──────────────▼──────────────┐
222
+ │ ターンを分析・構造化 │
223
+ │ ├─ L1: 1行サマリ生成 │
224
+ │ └─ L2: DECISION/CONSTRAINT │
225
+ │ /CONTEXT/IMPL/ISSUE │
226
+ │ を抽出 │
227
+ └──────────────┬──────────────┘
228
+
229
+ ┌─────────▼─────────┐
230
+ │ L1 + L2をSQLiteに │
231
+ │ 保存 │
232
+ └─────────┬─────────┘
233
+
234
+ ┌────────────▼────────────┐
235
+ │ トークン閾値チェック │
236
+ │ 超過? ──→ compact推奨 │
237
+ └────────────┬────────────┘
238
+
239
+ ┌───────────────▼───────────────┐
240
+ │ PreCompact / ContextCompaction │
241
+ │ ├─ 古いターンのL1+L2を │
242
+ │ │ additionalContextとして注入 │
243
+ │ ├─ 未解決ISSUEは常に含める │
244
+ │ └─ L3はSQLiteに残存(参照可能)│
245
+ └───────────────────────────────┘
246
+ ```
247
+
248
+ ---
249
+
250
+ ## 実装方針
251
+
252
+ ### 1. Hooks 構成
253
+
254
+ ```json
255
+ {
256
+ "hooks": {
257
+ "PostToolUse": [
258
+ {
259
+ "matcher": "Bash|Write|Edit|Read",
260
+ "hooks": [
261
+ {
262
+ "type": "command",
263
+ "command": "node .claude/hooks/detail-capture.mjs"
264
+ }
265
+ ]
266
+ }
267
+ ],
268
+ "Stop": [
269
+ {
270
+ "matcher": "",
271
+ "hooks": [
272
+ {
273
+ "type": "command",
274
+ "command": "node .claude/hooks/turn-processor.mjs"
275
+ }
276
+ ]
277
+ }
278
+ ],
279
+ "PreCompact": [
280
+ {
281
+ "matcher": "",
282
+ "hooks": [
283
+ {
284
+ "type": "command",
285
+ "command": "node .claude/hooks/throughline.mjs"
286
+ }
287
+ ]
288
+ }
289
+ ]
290
+ }
291
+ }
292
+ ```
293
+
294
+ ### 2. 主要モジュール
295
+
296
+ | モジュール | Hook Event | 役割 |
297
+ |-----------|-----------|------|
298
+ | `detail-capture.mjs` | PostToolUse | ツール実行のIN/OUTをリアルタイムでSQLite L3に保存 |
299
+ | `turn-processor.mjs` | Stop | ターン完了時にL1(サマリ)+L2(判断)を生成・保存。トークン閾値チェック |
300
+ | `throughline.mjs` | PreCompact | 古いターンのL1+L2をadditionalContextとして注入。未解決ISSUE含む |
301
+ | `db.mjs` | — | SQLite接続管理。better-sqlite3使用(同期API、Node.js軽量) |
302
+ | `classifier.mjs` | — | ターン内容をDECISION/CONSTRAINT/CONTEXT/IMPL/ISSUEに分類 |
303
+ | `token-estimator.mjs` | — | tiktoken互換のトークン数推定 |
304
+
305
+ ### 3. ツール実行履歴の構造化ルール
306
+
307
+ #### 原則
308
+
309
+ コマンドの実行結果は **その場でClaudeの判断に消費され、役目を終える情報** である。
310
+ ただし **捨てるのではなく、L3としてSQLiteに退避する。** オンデマンドで参照可能。
311
+
312
+ #### 構造化の実例
313
+
314
+ ```
315
+ Before(生データ、コンテキスト内 ~2,000+ トークン):
316
+ IN: powershell -Command "Get-Process electron..."
317
+ OUT: Id 19048, Name electron
318
+ IN: powershell -Command "Stop-Process -Name electron..."
319
+ OUT: stopped
320
+ IN: cd "C:\...\ServerManager" && npm start &
321
+ OUT: Command running in background with ID: bazIqox0f
322
+ IN: powershell -Command "Start-Sleep -Seconds 3; Get-Process electron..."
323
+ OUT: Exit code 1
324
+ IN: powershell -Command "Start-Sleep -Seconds 4; (Get-Process electron).Count"
325
+ OUT: 1
326
+
327
+ After(L1+L2のみコンテキスト内、~60 トークン):
328
+ L1: "ServerManager再起動 → 成功"
329
+ L2: [DECISION] Electron起動検出にSleep 4秒必要(3秒では不足)
330
+ L3: → SQLite details テーブルに全5コマンド分を保存(オンデマンド参照可)
331
+ ```
332
+
333
+ ### 4. 分類ロジック(classifier.mjs)
334
+
335
+ **方式: ハイブリッド(採用)**
336
+ - まずヒューリスティックで粗分類(トークンゼロ)
337
+ - ツール使用履歴: Write/Edit → IMPL、Bash → IMPL or ISSUE(exit codeで判定)
338
+ - キーワードパターン: 「〜に決めた」→ DECISION、「〜は禁止」→ CONSTRAINT
339
+ - 判定が曖昧なものだけLLMに投げる(最小限のトークン消費)
340
+ - 分類精度の統計をinjection_logに記録し、ヒューリスティックの改善に活用
341
+
342
+ ### 5. オンデマンドL3参照
343
+
344
+ ```
345
+ /sc-detail <turn_number> # カスタムスラッシュコマンド
346
+ ```
347
+
348
+ 1. Claudeがコンテキスト内のL1+L2から該当ターンを特定
349
+ 2. スラッシュコマンド or MCPツールでSQLiteからL3を取得
350
+ 3. additionalContextとしてそのターンのL3のみを一時注入
351
+
352
+ ### 6. 自動コンパクト閾値設定
353
+
354
+ Throughline の核心は「序盤から積極的にコンテキストを削減する」ことです。
355
+ これを実現するため、`install.mjs` が Claude Code の自動コンパクト閾値を引き下げます。
356
+
357
+ **環境変数:**
358
+ ```
359
+ CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=10
360
+ ```
361
+
362
+ - デフォルト(未設定時)は約95%。コンテキストが満杯になってから初めて圧縮される
363
+ - Throughline は10%(デフォルト値)に設定し、早期かつ頻繁にコンパクトを発火させる
364
+ - コンパクト後は L1+L2 のみ(~60 tok/turn)に置換されるため、すぐに容量が回復する
365
+ - 結果として「コンテキストが常に小さく保たれる」状態を実現
366
+
367
+ **設定場所:** `install.mjs` がプロジェクトの `.claude/settings.json` に自動書き込み
368
+ **カスタマイズ:** インストール時に閾値を指定可能(例: `node install.mjs --threshold 20 # 例: 20%に変更`)
369
+
370
+ ```json
371
+ {
372
+ "env": {
373
+ "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "10"
374
+ }
375
+ }
376
+ ```
377
+
378
+ **ユーザー体験:** `node install.mjs` を一度実行するだけで、あとは完全自動。
379
+ ユーザーは何も意識しなくてよい。
380
+
381
+ ### 7. クロスプラットフォーム対応
382
+
383
+ - 全hookスクリプトは `.mjs`(Node.js ESM)で統一
384
+ - `node .claude/hooks/xxx.mjs` でWindows / Linux / macOS全対応
385
+ - bash / PowerShell 依存なし
386
+ - SQLiteはbetter-sqlite3(ネイティブビルド済みバイナリ提供あり)
387
+
388
+ ---
389
+
390
+
391
+ ## コンテキスト操作の技術的根拠
392
+
393
+ ### Anthropic公式: Context Editing(Beta)
394
+
395
+ Anthropic APIには「Context Editing」というベータ機能が存在する。
396
+
397
+ - **Tool result clearing**: 古くなったツール実行結果をコンテキストから除去できる
398
+ - **自動警告**: クリア閾値に近づくと、Claudeに重要情報の保存を促す警告が自動送信される
399
+ - **メモリファイル連携**: クリアされる前に重要な情報をメモリファイルに退避可能
400
+
401
+ → **Anthropicは「セッション途中でコンテキストを削る」ことを公式に想定・サポートしている。**
402
+ → Throughlineの設計思想は、このAPIが示す方向性と完全に一致する。
403
+
404
+ ---
405
+
406
+ ## 開発フェーズ
407
+
408
+ ### Phase 1: MVP
409
+ - SQLiteスキーマ作成 + db.mjs
410
+ - detail-capture: PostToolUseでL3をリアルタイム保存
411
+ - turn-processor: StopでL1(サマリ)生成・保存
412
+ - 直近10ターン保護ルール
413
+ - install.mjs: hooks設定 + `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=10` を `.claude/settings.json` に書き込み
414
+
415
+ ### Phase 2: 構造化記憶
416
+ - classifier: L2分類(ハイブリッド方式)
417
+ - L2重複排除: contentハッシュによる同一判断の多重注入防止
418
+ - throughline: PreCompactでL1+L2注入
419
+ - /sc-detail コマンドでL3オンデマンド参照
420
+ - /sc-search コマンドでL3をキーワード検索(SQLite FTS5)
421
+ - injection_logによる効果測定
422
+
423
+ ### Phase 3: 公開
424
+ - GitHub公開・README・npm配布
425
+ - ベンチマーク(compact前後のトークン削減率)
426
+
427
+ ---
428
+
429
+ ## 配布計画
430
+
431
+ ### リポジトリ構成(予定)
432
+
433
+ ```
434
+ throughline/
435
+ ├── README.md
436
+ ├── package.json
437
+ ├── install.mjs # ワンコマンドセットアップ
438
+ ├── src/
439
+ │ ├── db.mjs # SQLite管理
440
+ │ ├── detail-capture.mjs # PostToolUse hook
441
+ │ ├── turn-processor.mjs # Stop hook
442
+ │ ├── throughline.mjs # PreCompact hook
443
+ │ ├── classifier.mjs # L2分類ロジック
444
+ │ └── token-estimator.mjs # トークン推定
445
+ ├── commands/
446
+ │ └── sc-detail.md # L3参照カスタムコマンド
447
+ └── docs/
448
+ ├── CONCEPT.md # この文書
449
+ ├── BENCHMARKS.md # 実測データ
450
+ └── SCHEMA.md # DBスキーマ詳細
451
+ ```
452
+
453
+ ### ターゲットユーザー
454
+
455
+ - Claude Code MAX契約者(パワーユーザー)
456
+ - CLAUDE.md + hooks を活用している中〜上級者
457
+ - トークン消費に課題を感じている開発者
458
+
459
+ ### 差別化ポイント
460
+
461
+ - **実データ駆動**: SmartClaudeの$4,211/月相当の分析に基づく設計
462
+ - **情報損失ゼロ**: 3層構造で「捨てずに構造化」
463
+ - **序盤から積極的に削減**: 閾値10%の自動コンパクトで常にコンテキストを小さく保つ
464
+ - **完全自動**: インストール後は何もしなくていい。ユーザー操作ゼロ
465
+ - **シンプル**: セッション内完結。余計な機能を持たない
466
+ - **クロスプラットフォーム**: Windows / Linux / macOS対応
467
+ - **既存ワークフロー非破壊**: hooks経由で透過的に動作
468
+
469
+ ---
470
+
471
+ ## 備考
472
+
473
+ - このコンセプトはBellの短期記憶DB設計と同じ思想に基づく
474
+ - SmartClaudeの実データ(履歴87%問題)がこの設計の根拠
475
+ - 最終的にはClaude Code本体に取り込まれるべき機能だが、それを待たずに自前で実装・公開する
476
+ - Anthropic公式のContext Editing APIが、このコンセプトの正当性を裏付けている