throughline 0.3.23 → 0.3.25
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.
- package/.claude/commands/tl-trim.md +42 -0
- package/.codex-sidecar.yml +62 -0
- package/CHANGELOG.md +583 -0
- package/README.ja.md +42 -5
- package/README.md +400 -23
- package/bin/throughline.mjs +168 -4
- package/codex/skills/throughline/SKILL.md +157 -0
- package/codex/skills/throughline/agents/openai.yaml +7 -0
- package/docs/INHERITANCE_ON_CLEAR_ONLY.md +146 -0
- package/docs/L1_L2_L3_REDESIGN.md +415 -0
- package/docs/PUBLIC_RELEASE_PLAN.md +184 -0
- package/docs/THROUGHLINE_CODEX_DUAL_SUPPORT.md +249 -0
- package/docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md +555 -0
- package/docs/THROUGHLINE_CODEX_MONITOR_IMPLEMENTATION_PLAN.md +220 -0
- package/docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md +528 -0
- package/docs/THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md +672 -0
- package/docs/archive/CONCEPT.md +476 -0
- package/docs/archive/EXPERIMENT.md +371 -0
- package/docs/archive/README.md +22 -0
- package/docs/archive/SESSION_LINKING_DESIGN.md +231 -0
- package/docs/archive/THROUGHLINE_NEXT_STEPS.md +134 -0
- package/docs/throughline-codex-trim-rollback-incident-report.md +306 -0
- package/docs/throughline-handoff-context.example.json +57 -0
- package/docs/throughline-rollback-context-trim-insight.md +455 -0
- package/package.json +6 -2
- package/src/cli/codex-capture.mjs +95 -0
- package/src/cli/codex-handoff-model-smoke.mjs +292 -0
- package/src/cli/codex-handoff-model-smoke.test.mjs +262 -0
- package/src/cli/codex-handoff-smoke.mjs +163 -0
- package/src/cli/codex-handoff-smoke.test.mjs +149 -0
- package/src/cli/codex-handoff-start.mjs +291 -0
- package/src/cli/codex-handoff-start.test.mjs +194 -0
- package/src/cli/codex-hook.mjs +276 -0
- package/src/cli/codex-hook.test.mjs +293 -0
- package/src/cli/codex-host-primitive-audit.mjs +110 -0
- package/src/cli/codex-host-primitive-audit.test.mjs +75 -0
- package/src/cli/codex-restore-smoke.mjs +357 -0
- package/src/cli/codex-restore-source-audit.mjs +304 -0
- package/src/cli/codex-resume.mjs +138 -0
- package/src/cli/codex-rollback-model-visible-smoke.mjs +373 -0
- package/src/cli/codex-rollback-model-visible-smoke.test.mjs +255 -0
- package/src/cli/codex-sidecar-diagnostics.mjs +48 -0
- package/src/cli/codex-sidecar-dry-run.mjs +85 -0
- package/src/cli/codex-summarize.mjs +224 -0
- package/src/cli/codex-threads.mjs +89 -0
- package/src/cli/codex-visibility-smoke.mjs +196 -0
- package/src/cli/codex-vscode-restore-smoke.mjs +226 -0
- package/src/cli/codex-vscode-rollback-smoke.mjs +114 -0
- package/src/cli/doctor.mjs +503 -1
- package/src/cli/doctor.test.mjs +542 -3
- package/src/cli/handoff-preview.mjs +78 -0
- package/src/cli/help.test.mjs +64 -0
- package/src/cli/install.mjs +227 -4
- package/src/cli/install.test.mjs +207 -4
- package/src/cli/trim.mjs +564 -0
- package/src/codex-app-server.mjs +1816 -0
- package/src/codex-app-server.test.mjs +512 -0
- package/src/codex-auto-refresh.mjs +194 -0
- package/src/codex-auto-refresh.test.mjs +182 -0
- package/src/codex-capture.mjs +235 -0
- package/src/codex-capture.test.mjs +393 -0
- package/src/codex-handoff-model-smoke.mjs +114 -0
- package/src/codex-handoff-model-smoke.test.mjs +89 -0
- package/src/codex-handoff-smoke.mjs +124 -0
- package/src/codex-handoff-smoke.test.mjs +103 -0
- package/src/codex-handoff.mjs +331 -0
- package/src/codex-handoff.test.mjs +220 -0
- package/src/codex-host-primitive-audit.mjs +374 -0
- package/src/codex-host-primitive-audit.test.mjs +208 -0
- package/src/codex-restore-smoke.test.mjs +639 -0
- package/src/codex-restore-source-audit.mjs +1348 -0
- package/src/codex-restore-source-audit.test.mjs +623 -0
- package/src/codex-resume.test.mjs +242 -0
- package/src/codex-rollout-memory.mjs +711 -0
- package/src/codex-rollout-memory.test.mjs +610 -0
- package/src/codex-sidecar-cli.test.mjs +75 -0
- package/src/codex-sidecar.mjs +246 -0
- package/src/codex-sidecar.test.mjs +172 -0
- package/src/codex-summarize.test.mjs +143 -0
- package/src/codex-thread-identity.mjs +23 -0
- package/src/codex-thread-index.mjs +173 -0
- package/src/codex-thread-index.test.mjs +164 -0
- package/src/codex-usage.mjs +110 -0
- package/src/codex-usage.test.mjs +140 -0
- package/src/codex-visibility-smoke.test.mjs +222 -0
- package/src/codex-vscode-restore-smoke.mjs +206 -0
- package/src/codex-vscode-restore-smoke.test.mjs +325 -0
- package/src/codex-vscode-rollback-smoke.mjs +90 -0
- package/src/codex-vscode-rollback-smoke.test.mjs +290 -0
- package/src/db-schema.test.mjs +97 -0
- package/src/haiku-summarizer.mjs +267 -26
- package/src/haiku-summarizer.test.mjs +282 -0
- package/src/handoff-preview.test.mjs +108 -0
- package/src/handoff-record.mjs +294 -0
- package/src/handoff-record.test.mjs +226 -0
- package/src/hook-entrypoints.test.mjs +326 -0
- package/src/package-files.test.mjs +19 -0
- package/src/prompt-submit.mjs +9 -6
- package/src/resume-context.mjs +44 -140
- package/src/resume-context.test.mjs +172 -0
- package/src/session-start.mjs +8 -5
- package/src/state-file.mjs +50 -6
- package/src/state-file.test.mjs +50 -0
- package/src/token-monitor.mjs +14 -10
- package/src/token-monitor.test.mjs +27 -0
- package/src/trim-cli.test.mjs +1584 -0
- package/src/trim-model.mjs +584 -0
- package/src/trim-model.test.mjs +568 -0
- package/src/turn-processor.mjs +17 -10
- package/src/vscode-task.mjs +94 -6
- package/src/vscode-task.test.mjs +186 -6
package/bin/throughline.mjs
CHANGED
|
@@ -9,6 +9,25 @@
|
|
|
9
9
|
* throughline process-turn # Stop hook (Claude Code から呼ばれる)
|
|
10
10
|
* throughline session-start # SessionStart hook (Claude Code から呼ばれる)
|
|
11
11
|
* throughline detail <時刻> # L2+L3 詳細取得 (Claude が Bash 経由で呼ぶ想定)
|
|
12
|
+
* throughline handoff-preview # Codex-facing throughline_handoff JSON preview
|
|
13
|
+
* throughline codex-capture # Capture active Codex rollout turns into Throughline DB
|
|
14
|
+
* throughline codex-hook stop # Codex native Stop hook (capture + L1 summarize)
|
|
15
|
+
* throughline codex-summarize # Summarize captured Codex L2 turns into L1 via Codex CLI
|
|
16
|
+
* throughline codex-resume # Render Codex active-work context from DB
|
|
17
|
+
* throughline codex-handoff-smoke # Validate fresh-thread Codex handoff prompt
|
|
18
|
+
* throughline codex-handoff-model-smoke # Experimental ephemeral Codex exec handoff smoke
|
|
19
|
+
* throughline codex-handoff-start # Guided fresh-thread Codex handoff start
|
|
20
|
+
* throughline codex-visibility-smoke # Experimental model-visible Codex memory smoke
|
|
21
|
+
* throughline codex-rollback-model-visible-smoke # Controlled rollback visibility smoke
|
|
22
|
+
* throughline codex-restore-smoke # Experimental read-only app-server restart restore smoke
|
|
23
|
+
* throughline codex-restore-source-audit # Read-only local restore source inventory
|
|
24
|
+
* throughline codex-host-primitive-audit # Read-only Codex app-server primitive audit
|
|
25
|
+
* throughline codex-vscode-restore-smoke # Manual VS Code reload/reconnect restore smoke
|
|
26
|
+
* throughline codex-vscode-rollback-smoke # Manual rollback non-resurrection smoke
|
|
27
|
+
* throughline codex-threads # List read-only Codex thread id candidates
|
|
28
|
+
* throughline codex-sidecar-diagnostics # Check codex-sidecar availability
|
|
29
|
+
* throughline codex-sidecar-dry-run # Print normalized sidecar request
|
|
30
|
+
* throughline trim --dry-run # Preview same-session context trim plan
|
|
12
31
|
* throughline doctor # 環境チェック
|
|
13
32
|
* throughline status # DB 統計表示
|
|
14
33
|
* throughline --version # バージョン表示
|
|
@@ -27,13 +46,13 @@ switch (cmd) {
|
|
|
27
46
|
await (await import('../src/cli/install.mjs')).run(['--uninstall', ...rest]);
|
|
28
47
|
break;
|
|
29
48
|
case 'process-turn':
|
|
30
|
-
await import('../src/turn-processor.mjs');
|
|
49
|
+
await (await import('../src/turn-processor.mjs')).run();
|
|
31
50
|
break;
|
|
32
51
|
case 'session-start':
|
|
33
|
-
await import('../src/session-start.mjs');
|
|
52
|
+
await (await import('../src/session-start.mjs')).run();
|
|
34
53
|
break;
|
|
35
54
|
case 'prompt-submit':
|
|
36
|
-
await import('../src/prompt-submit.mjs');
|
|
55
|
+
await (await import('../src/prompt-submit.mjs')).run();
|
|
37
56
|
break;
|
|
38
57
|
case 'monitor':
|
|
39
58
|
(await import('../src/token-monitor.mjs')).main();
|
|
@@ -44,6 +63,63 @@ switch (cmd) {
|
|
|
44
63
|
case 'save-inflight':
|
|
45
64
|
await (await import('../src/cli/save-inflight.mjs')).run();
|
|
46
65
|
break;
|
|
66
|
+
case 'handoff-preview':
|
|
67
|
+
await (await import('../src/cli/handoff-preview.mjs')).run(rest);
|
|
68
|
+
break;
|
|
69
|
+
case 'codex-capture':
|
|
70
|
+
await (await import('../src/cli/codex-capture.mjs')).run(rest);
|
|
71
|
+
break;
|
|
72
|
+
case 'codex-hook':
|
|
73
|
+
await (await import('../src/cli/codex-hook.mjs')).run(rest);
|
|
74
|
+
break;
|
|
75
|
+
case 'codex-summarize':
|
|
76
|
+
await (await import('../src/cli/codex-summarize.mjs')).run(rest);
|
|
77
|
+
break;
|
|
78
|
+
case 'codex-resume':
|
|
79
|
+
await (await import('../src/cli/codex-resume.mjs')).run(rest);
|
|
80
|
+
break;
|
|
81
|
+
case 'codex-handoff-smoke':
|
|
82
|
+
await (await import('../src/cli/codex-handoff-smoke.mjs')).run(rest);
|
|
83
|
+
break;
|
|
84
|
+
case 'codex-handoff-model-smoke':
|
|
85
|
+
await (await import('../src/cli/codex-handoff-model-smoke.mjs')).run(rest);
|
|
86
|
+
break;
|
|
87
|
+
case 'codex-handoff-start':
|
|
88
|
+
await (await import('../src/cli/codex-handoff-start.mjs')).run(rest);
|
|
89
|
+
break;
|
|
90
|
+
case 'codex-visibility-smoke':
|
|
91
|
+
await (await import('../src/cli/codex-visibility-smoke.mjs')).run(rest);
|
|
92
|
+
break;
|
|
93
|
+
case 'codex-rollback-model-visible-smoke':
|
|
94
|
+
await (await import('../src/cli/codex-rollback-model-visible-smoke.mjs')).run(rest);
|
|
95
|
+
break;
|
|
96
|
+
case 'codex-restore-smoke':
|
|
97
|
+
await (await import('../src/cli/codex-restore-smoke.mjs')).run(rest);
|
|
98
|
+
break;
|
|
99
|
+
case 'codex-restore-source-audit':
|
|
100
|
+
await (await import('../src/cli/codex-restore-source-audit.mjs')).run(rest);
|
|
101
|
+
break;
|
|
102
|
+
case 'codex-host-primitive-audit':
|
|
103
|
+
await (await import('../src/cli/codex-host-primitive-audit.mjs')).run(rest);
|
|
104
|
+
break;
|
|
105
|
+
case 'codex-vscode-restore-smoke':
|
|
106
|
+
await (await import('../src/cli/codex-vscode-restore-smoke.mjs')).run(rest);
|
|
107
|
+
break;
|
|
108
|
+
case 'codex-vscode-rollback-smoke':
|
|
109
|
+
await (await import('../src/cli/codex-vscode-rollback-smoke.mjs')).run(rest);
|
|
110
|
+
break;
|
|
111
|
+
case 'codex-threads':
|
|
112
|
+
await (await import('../src/cli/codex-threads.mjs')).run(rest);
|
|
113
|
+
break;
|
|
114
|
+
case 'codex-sidecar-diagnostics':
|
|
115
|
+
await (await import('../src/cli/codex-sidecar-diagnostics.mjs')).run(rest);
|
|
116
|
+
break;
|
|
117
|
+
case 'codex-sidecar-dry-run':
|
|
118
|
+
await (await import('../src/cli/codex-sidecar-dry-run.mjs')).run(rest);
|
|
119
|
+
break;
|
|
120
|
+
case 'trim':
|
|
121
|
+
await (await import('../src/cli/trim.mjs')).run(rest);
|
|
122
|
+
break;
|
|
47
123
|
case 'doctor':
|
|
48
124
|
await (await import('../src/cli/doctor.mjs')).run(rest);
|
|
49
125
|
break;
|
|
@@ -74,13 +150,101 @@ Usage:
|
|
|
74
150
|
throughline monitor Multi-session token monitor (use --all, --session <id>)
|
|
75
151
|
throughline detail <time> Retrieve L2+L3 detail for a turn (e.g. 14:23:05 or 14:23-14:30)
|
|
76
152
|
throughline save-inflight Save in-flight memo (stdin) to the current /tl baton
|
|
153
|
+
throughline handoff-preview Print Codex-facing throughline_handoff JSON
|
|
154
|
+
throughline codex-capture Capture active Codex rollout turns into DB
|
|
155
|
+
(requires --codex-thread-id or env thread id)
|
|
156
|
+
throughline codex-hook stop Codex native Stop hook: capture rollout and
|
|
157
|
+
summarize old L2 turns into L1 via Codex CLI
|
|
158
|
+
throughline codex-summarize Summarize captured Codex L2 into L1 via Codex CLI
|
|
159
|
+
(requires a codex:<thread-id> session)
|
|
160
|
+
throughline codex-resume Render Codex active-work context from DB
|
|
161
|
+
(use --format handoff for a fresh-thread handoff)
|
|
162
|
+
(handoff accepts --max-recent-bodies,
|
|
163
|
+
--max-body-chars, and --max-detail-refs)
|
|
164
|
+
(use --format item-json for a developer message item)
|
|
165
|
+
(use --memo-stdin to prepend a current-work memo)
|
|
166
|
+
throughline codex-handoff-smoke
|
|
167
|
+
Read-only validation that --format handoff is
|
|
168
|
+
pasteable as a fresh Codex thread start prompt
|
|
169
|
+
(use --print-prompt to include the prompt)
|
|
170
|
+
throughline codex-handoff-model-smoke
|
|
171
|
+
Experimental: run the fresh-thread handoff prompt
|
|
172
|
+
through codex exec --ephemeral --sandbox read-only.
|
|
173
|
+
Use --dry-run to inspect readiness without model exec.
|
|
174
|
+
Use --print-prompt with --dry-run to include the prompt.
|
|
175
|
+
Use --memo-stdin to prepend current-work memo.
|
|
176
|
+
Live smoke requires THROUGHLINE_EXPERIMENTAL_CODEX_HANDOFF_MODEL_SMOKE=1
|
|
177
|
+
throughline codex-handoff-start
|
|
178
|
+
Guided read-only fresh-thread handoff start plan:
|
|
179
|
+
structural smoke, model-smoke dry-run boundary,
|
|
180
|
+
render command, optional --print-prompt, and
|
|
181
|
+
--memo-stdin replay guidance
|
|
182
|
+
throughline codex-visibility-smoke
|
|
183
|
+
Experimental: inject Codex active-work memory and
|
|
184
|
+
start a marker-check model turn. Requires
|
|
185
|
+
THROUGHLINE_EXPERIMENTAL_CODEX_MODEL_VISIBLE_SMOKE=1
|
|
186
|
+
(use --memo-stdin and --request-timeout-ms as needed)
|
|
187
|
+
(use --resume-after-inject to re-resume before turn/start)
|
|
188
|
+
throughline codex-rollback-model-visible-smoke
|
|
189
|
+
Experimental controlled two-phase smoke for whether
|
|
190
|
+
a rolled-back user marker is still model-visible.
|
|
191
|
+
--prepare starts a marker turn and rolls it back.
|
|
192
|
+
--verify asks for only the marker prefix after
|
|
193
|
+
reload/reconnect. Requires
|
|
194
|
+
THROUGHLINE_EXPERIMENTAL_CODEX_ROLLBACK_MODEL_VISIBLE_SMOKE=1
|
|
195
|
+
(use --marker-file to avoid leaking the full marker)
|
|
196
|
+
throughline codex-restore-smoke
|
|
197
|
+
Experimental read-only smoke: start fresh app-server
|
|
198
|
+
processes and compare thread/read + thread/resume
|
|
199
|
+
+ thread/turns/list counts with the rollout source. Requires
|
|
200
|
+
THROUGHLINE_EXPERIMENTAL_CODEX_RESTORE_SMOKE=1
|
|
201
|
+
(use --inspect-risky-rollout only for read-only
|
|
202
|
+
risk-evidence inspection; it still exits nonzero)
|
|
203
|
+
throughline codex-restore-source-audit
|
|
204
|
+
Read-only local inventory of Codex rollout,
|
|
205
|
+
session index, state sqlite, VS Code storage,
|
|
206
|
+
settings, logs, and extension restore-path signals.
|
|
207
|
+
Does not prove restart safety
|
|
208
|
+
throughline codex-host-primitive-audit
|
|
209
|
+
Read-only Codex app-server schema audit for a
|
|
210
|
+
current-thread compacted-history remediation
|
|
211
|
+
primitive. Does not mutate threads
|
|
212
|
+
throughline codex-vscode-restore-smoke
|
|
213
|
+
Manual two-phase VS Code reload/reconnect smoke.
|
|
214
|
+
--prepare injects a hidden marker developer memory
|
|
215
|
+
and requires
|
|
216
|
+
THROUGHLINE_EXPERIMENTAL_CODEX_VSCODE_RESTORE_SMOKE=1.
|
|
217
|
+
--verify searches the rollout for the marker answer
|
|
218
|
+
throughline codex-vscode-rollback-smoke
|
|
219
|
+
Manual rollback non-resurrection smoke.
|
|
220
|
+
--verify requires a rollback event, rolled-back
|
|
221
|
+
user text, a later user turn, restore safety ok,
|
|
222
|
+
and --after-vscode-restart for restart-safe proof
|
|
223
|
+
throughline codex-threads List read-only Codex thread id candidates
|
|
224
|
+
for --codex-thread-id
|
|
225
|
+
throughline codex-sidecar-diagnostics
|
|
226
|
+
Check codex-sidecar diagnostics status
|
|
227
|
+
throughline codex-sidecar-dry-run
|
|
228
|
+
Print normalized read-only sidecar request
|
|
229
|
+
throughline trim --dry-run Preview same-session context trim plan
|
|
230
|
+
(Codex: accepts --codex-thread-id <id> or
|
|
231
|
+
THROUGHLINE_CODEX_THREAD_ID / CODEX_THREAD_ID)
|
|
232
|
+
(text preview accepts --preview-max-chars <n>)
|
|
233
|
+
throughline trim --preflight
|
|
234
|
+
Codex-only app-server read/resume guard; does not rollback
|
|
235
|
+
throughline trim --execute Codex rollback/inject guard; requires a Codex
|
|
236
|
+
thread id, injectable DB memory, and matching
|
|
237
|
+
rollout/app-server turns
|
|
77
238
|
throughline doctor Check environment
|
|
239
|
+
throughline doctor --trim Show trim host boundary diagnostics
|
|
240
|
+
throughline doctor --codex Show Codex primary diagnostics
|
|
78
241
|
throughline status Show DB statistics
|
|
79
242
|
throughline --version Show version
|
|
80
243
|
|
|
81
|
-
Hook subcommands (called by Claude Code):
|
|
244
|
+
Hook subcommands (called by Claude Code / Codex):
|
|
82
245
|
throughline session-start SessionStart hook
|
|
83
246
|
throughline process-turn Stop hook
|
|
84
247
|
throughline prompt-submit UserPromptSubmit hook (/tl baton writer)
|
|
248
|
+
throughline codex-hook stop Codex Stop hook
|
|
85
249
|
`);
|
|
86
250
|
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: throughline
|
|
3
|
+
description: Use when the user asks to use Throughline from Codex, continue or restore Throughline memory, run Codex trim/rewind/rollback, inject remembered context, summarize a captured Codex session, or check whether the Throughline Codex Stop hook captured the current session. Hide long Throughline command details behind this workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Throughline
|
|
7
|
+
|
|
8
|
+
Use this skill to operate Throughline from Codex without making the user type long
|
|
9
|
+
commands.
|
|
10
|
+
|
|
11
|
+
If the user invokes `$throughline` by itself, treat that as a request to inspect
|
|
12
|
+
the current Codex context and prepare a refresh plan. Codex rollback / inject is
|
|
13
|
+
enabled again after controlled rollback model-visible smokes failed to reproduce
|
|
14
|
+
rollback marker resurrection.
|
|
15
|
+
|
|
16
|
+
## Core Rule
|
|
17
|
+
|
|
18
|
+
Do not ask the user for a Codex thread id when the current environment can
|
|
19
|
+
provide it. Prefer the current `CODEX_THREAD_ID` / `THROUGHLINE_CODEX_THREAD_ID`
|
|
20
|
+
identity and verify it with `throughline doctor --codex`.
|
|
21
|
+
|
|
22
|
+
Do not manually capture payloads before checking natural Stop hook capture.
|
|
23
|
+
If natural capture looks wrong, inspect `doctor --codex`, the latest rollout,
|
|
24
|
+
and hook logs first.
|
|
25
|
+
|
|
26
|
+
## Common Requests
|
|
27
|
+
|
|
28
|
+
### Bare "$throughline" / "use Throughline"
|
|
29
|
+
|
|
30
|
+
Run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
throughline doctor --codex
|
|
34
|
+
throughline trim --dry-run --host codex --all --json
|
|
35
|
+
throughline codex-handoff-start --session codex:<current-thread-id> --json
|
|
36
|
+
throughline trim --preflight --host codex --all --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This is the safe Codex context-refresh inspection flow. `--all` previews a
|
|
40
|
+
rollback-based reset of the model-visible thread. `codex-handoff-start` is an
|
|
41
|
+
optional fresh-thread continuation surface: it validates the handoff, shows the
|
|
42
|
+
model-smoke dry-run boundary, and can render the prompt with `--print-prompt`
|
|
43
|
+
without mutating the current thread. Report the preflight result, handoff-start
|
|
44
|
+
status, and context reduction estimate from the dry-run. Do not claim the
|
|
45
|
+
refresh happened unless `trim --execute` or auto-refresh actually ran.
|
|
46
|
+
|
|
47
|
+
The injected memory must preserve the original `/tl` memory contract:
|
|
48
|
+
|
|
49
|
+
- older turns: L1 summaries
|
|
50
|
+
- recent work: L2 full bodies for the latest 20 turns
|
|
51
|
+
- L3: detail references only; L3 bodies / tool payloads are not injected
|
|
52
|
+
|
|
53
|
+
If the dry-run reports no captured turns or no injectable memory, say that
|
|
54
|
+
clearly.
|
|
55
|
+
|
|
56
|
+
### "Throughline status" / "doctor"
|
|
57
|
+
|
|
58
|
+
Run:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
throughline doctor --codex
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Report whether:
|
|
65
|
+
|
|
66
|
+
- Codex hooks feature is enabled
|
|
67
|
+
- Codex Stop hook is registered
|
|
68
|
+
- VSCode monitor task is registered, and whether `Developer: Reload Window` is
|
|
69
|
+
needed to make the folder-open monitor appear
|
|
70
|
+
- current Codex thread and latest DB session match
|
|
71
|
+
|
|
72
|
+
### "resume" / "memory" / "continue from Throughline"
|
|
73
|
+
|
|
74
|
+
First run `throughline doctor --codex`.
|
|
75
|
+
|
|
76
|
+
If the current thread and latest DB session match, render memory with:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
throughline codex-resume --session codex:<current-thread-id>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If the user gave a current-work memo, pipe it with `--memo-stdin`.
|
|
83
|
+
|
|
84
|
+
If the user wants to continue in a fresh Codex thread instead of mutating the
|
|
85
|
+
current thread, use:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
throughline codex-handoff-start --session codex:<current-thread-id> --print-prompt
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If the user gave a current-work memo, pipe it with `--memo-stdin`. This is
|
|
92
|
+
read-only and does not mutate the current thread.
|
|
93
|
+
|
|
94
|
+
### "summarize"
|
|
95
|
+
|
|
96
|
+
Run:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
throughline codex-summarize --session codex:<current-thread-id> --json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Codex-primary summarization uses the Codex CLI backend. Do not claim it fell
|
|
103
|
+
back to Claude Haiku.
|
|
104
|
+
|
|
105
|
+
### "trim" / "rewind" / "rollback" / "context cleanup"
|
|
106
|
+
|
|
107
|
+
Default to the same inspection flow as bare `$throughline` when the user
|
|
108
|
+
asks to trim, rewind, rollback, clean up context, or use Throughline memory.
|
|
109
|
+
|
|
110
|
+
Preview:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
throughline trim --dry-run --host codex
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Safe new-thread continuation:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
throughline codex-handoff-start --session codex:<current-thread-id> --json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Report the context reduction estimate from the dry-run when present:
|
|
123
|
+
|
|
124
|
+
- rollback candidate estimated tokens
|
|
125
|
+
- injected memory estimated tokens
|
|
126
|
+
- net estimated token reduction and percentage
|
|
127
|
+
|
|
128
|
+
The estimate is `chars / 4` from rollout text, not an exact host tokenizer
|
|
129
|
+
measurement. If rollback candidate turns are `0`, say that this session has no
|
|
130
|
+
current trim savings yet under the active keep-recent setting.
|
|
131
|
+
|
|
132
|
+
Guard check:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
throughline trim --preflight --host codex
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Execute path:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
throughline trim --execute --host codex --all
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Run this only when the user explicitly wants the current thread trimmed. It sends
|
|
145
|
+
rollback + Throughline DB memory injection after the app-server guard checks.
|
|
146
|
+
|
|
147
|
+
## User-Facing Explanation
|
|
148
|
+
|
|
149
|
+
Explain the behavior simply:
|
|
150
|
+
|
|
151
|
+
- normal Codex turn end: Stop hook captures DB memory and writes monitor state
|
|
152
|
+
- `$throughline` / context refresh: doctor, dry-run, preflight, and optional
|
|
153
|
+
execute; execute mutates the current Codex thread
|
|
154
|
+
- Stop hook auto-refresh attempts rollback / inject when verified usage reaches
|
|
155
|
+
90%; estimate usage does not trigger mutation
|
|
156
|
+
- dry-run reports estimated savings when there are rollback candidate turns, but
|
|
157
|
+
exact host-visible token reduction is not yet measured with the host tokenizer
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Throughline"
|
|
3
|
+
short_description: "Operate Throughline memory, Codex capture, resume, and trim"
|
|
4
|
+
default_prompt: "Use $throughline to check capture, resume memory, summarize, inspect guarded Codex trim, or prepare a safe fresh-thread handoff without typing long commands."
|
|
5
|
+
|
|
6
|
+
policy:
|
|
7
|
+
allow_implicit_invocation: true
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# 引き継ぎ発火条件の絞り込み調査 & 実装計画
|
|
2
|
+
|
|
3
|
+
## Status (2026-04-18 更新)
|
|
4
|
+
|
|
5
|
+
- **Phase 0 実機検証: 完了**
|
|
6
|
+
- **案 A 不成立**: VSCode 拡張 2.1.112 でも /clear 後の SessionStart は `source="startup"` で発火 (probe ログ 30 件中 startup 29 / resume 1)。公式 docs / MINGW64 環境と挙動が異なる既知差異
|
|
7
|
+
- **案 C 不成立**: SessionStart 発火時点で transcript ファイルは未作成
|
|
8
|
+
- **案 D(時間差ヒューリスティック): 撤回**。誤爆の可能性を排除できず、ユーザー明示指名の方が決定論的で意図が明確
|
|
9
|
+
- **採用: バトン方式(案 E)**: 旧セッションで `/tl` スラッシュコマンドを打つと UserPromptSubmit hook が `handoff_batons` テーブルに session_id を書き込み、次の新規セッションの SessionStart が TTL 1 時間以内のバトンを消費して merge する
|
|
10
|
+
- 実装: [src/baton.mjs](../src/baton.mjs), [src/prompt-submit.mjs](../src/prompt-submit.mjs), [src/session-start.mjs](../src/session-start.mjs), [src/session-merger.mjs](../src/session-merger.mjs) (`mergeSpecificPredecessor`), [.claude/commands/tl.md](../.claude/commands/tl.md)
|
|
11
|
+
- Bash tool サブプロセスには `$CLAUDE_SESSION_ID` 相当の env が無いため、session_id は UserPromptSubmit hook payload から取得する
|
|
12
|
+
- **GitHub issue**: [anthropics/claude-code#49937](https://github.com/anthropics/claude-code/issues/49937) 提出済み。修正されれば source ベースに戻す余地は残る
|
|
13
|
+
|
|
14
|
+
## Context
|
|
15
|
+
|
|
16
|
+
Throughline の SessionStart フックは現在 **同一 project_path の未合流セッションがあれば無条件で記憶を引き継いでいる**。そのため以下が起きている:
|
|
17
|
+
|
|
18
|
+
- ユーザーが `/clear` していないのに手動で新規セッションを始めると、前任の記憶が引き継がれて「90 ターン引き継ぎました」と注入される(**最優先で解消したい挙動**)
|
|
19
|
+
- VSC を再起動して完全新規セッションを開いた場合も同様に引き継がれる
|
|
20
|
+
|
|
21
|
+
ユーザーの望む挙動: **`/clear` 直後の新規セッションのときだけ** 前任を引き継ぎ、手動新規・VSC 再起動後の新規では引き継がない。
|
|
22
|
+
|
|
23
|
+
## Findings (2026-04-17 時点)
|
|
24
|
+
|
|
25
|
+
### 現行実装 (根拠: [src/session-start.mjs](../src/session-start.mjs), [src/session-merger.mjs](../src/session-merger.mjs))
|
|
26
|
+
|
|
27
|
+
- [src/session-start.mjs:33](../src/session-start.mjs#L33) で payload の `source` を **読み捨てている**
|
|
28
|
+
- [src/session-start.mjs:48-51](../src/session-start.mjs#L48-L51) で無条件に `mergePredecessorInto` を呼ぶ
|
|
29
|
+
- [src/session-merger.mjs:68-78](../src/session-merger.mjs#L68-L78) の前任選定は「同 project_path・未合流・自分より created_at が古い・最新 updated_at」のみで、source や時間窓は見ていない
|
|
30
|
+
|
|
31
|
+
### 過去ログは参考扱い
|
|
32
|
+
|
|
33
|
+
- `C:\Users\kite_\.throughline\spike\session-start.log` の 93 件は Opus 4.6 以前の採取で、モデル更新(現 4.7)と Claude Code バージョン更新を跨いでいる
|
|
34
|
+
- 「startup 76 / resume 16 / clear 1」の分布はあくまで参考値で、現行環境の挙動として採用しない
|
|
35
|
+
- コメント [src/session-start.mjs:7-10](../src/session-start.mjs#L7-L10) の「/clear 後も source='startup'」も当時の観察で、現行環境で再検証する
|
|
36
|
+
|
|
37
|
+
### 確定したい前提
|
|
38
|
+
|
|
39
|
+
**「/clear 直後の SessionStart は `source === 'clear'` で識別できる」** を現行環境で実証できれば、案 A が成立する。できなければ別アプローチ(時間差 / transcript マーカー)に切り替える。
|
|
40
|
+
|
|
41
|
+
## 想定アプローチ(合意用の選択肢)
|
|
42
|
+
|
|
43
|
+
### 案 A: `source === "clear"` のみ引き継ぐ(シンプル案)
|
|
44
|
+
|
|
45
|
+
- [src/session-start.mjs](../src/session-start.mjs) で `source !== 'clear'` なら `mergePredecessorInto` を呼ばない
|
|
46
|
+
- 取りこぼし(startup で来る /clear)は許容
|
|
47
|
+
- ユーザー視点: 「手動新規・VSC 再起動・一部の /clear」で真に新規、それ以外は引き継ぐ
|
|
48
|
+
|
|
49
|
+
### 案 B: `source === "clear"` + 時間差ヒューリスティック
|
|
50
|
+
|
|
51
|
+
- 案 A に加え、`source === "startup"` でも **前任の updated_at が N 秒以内**(候補: 60 秒)なら /clear 由来とみなし引き継ぐ
|
|
52
|
+
- 取りこぼしを減らせるが、「手動新規を早いタイミングで開いた」ケースを /clear と誤判定するリスクあり
|
|
53
|
+
|
|
54
|
+
### 案 C: transcript マーカー判定
|
|
55
|
+
|
|
56
|
+
- 新 transcript の先頭に `<command-name>/clear</command-name>` が残っていれば /clear 由来と判定
|
|
57
|
+
- 未検証前提が多く、Claude Code 側の仕様変更で壊れやすい
|
|
58
|
+
|
|
59
|
+
## 推奨アプローチ
|
|
60
|
+
|
|
61
|
+
**Phase 0 で `source` の実測 → 結果次第で案 A or B を確定 → 実装**。
|
|
62
|
+
|
|
63
|
+
- Phase 0 の結果、/clear で必ず `source='clear'` が来る & 手動新規・VSC 再起動では絶対に来ないことが確認できれば **案 A** で確定
|
|
64
|
+
- /clear で `source='startup'` が混じる場合は **案 B**(時間差ヒューリスティック併用)に切り替え
|
|
65
|
+
- いずれも案 C(transcript マーカー)は fallback として deferred
|
|
66
|
+
|
|
67
|
+
## Phase 0: 実機検証(実装前に必ず実施)
|
|
68
|
+
|
|
69
|
+
**目的**: 現行環境(Opus 4.7 / 最新 Claude Code)で SessionStart payload の `source` が /clear / 手動新規 / VSC 再起動でそれぞれ何になるかを確定する。
|
|
70
|
+
|
|
71
|
+
### 手順
|
|
72
|
+
|
|
73
|
+
1. **debug ロガーを [src/session-start.mjs](../src/session-start.mjs) に一時挿入**
|
|
74
|
+
- payload を受け取った直後(L32 の JSON.parse 直後)に `{ ts, source, session_id, transcript_path, cwd }` を `C:\Users\kite_\.throughline\logs\sessionstart-probe.log` に追記
|
|
75
|
+
- 既存のマージ処理には触れない(挙動を変えずに観測だけする)
|
|
76
|
+
- 1 行 1 JSON (JSONL) 形式で append
|
|
77
|
+
|
|
78
|
+
2. **ユーザー手動で 3 ケース × 複数回の実機採取**
|
|
79
|
+
- **ケース 1: /clear 後の新規セッション** — チャット中に `/clear` 実行 → SessionStart 発火 → 1 行ログ取得 × 3 回以上
|
|
80
|
+
- **ケース 2: 手動新規セッション** — VSC 内で新規チャット作成操作 → SessionStart 発火 → 1 行ログ取得 × 3 回以上
|
|
81
|
+
- **ケース 3: VSC 再起動直後** — VSC を終了 → 起動 → Throughline 有効なプロジェクトを開いた直後 → 1 行ログ取得 × 3 回以上
|
|
82
|
+
|
|
83
|
+
3. **集計と判定**
|
|
84
|
+
- ケース 1 が **全回 `source='clear'`** → 案 A 確定
|
|
85
|
+
- ケース 1 に `startup` が混じる / ケース 2 または 3 に `clear` が混じる → 案 B に切り替えて時間差閾値を設計
|
|
86
|
+
|
|
87
|
+
4. **debug ロガー撤去**
|
|
88
|
+
- 判定後は [src/session-start.mjs](../src/session-start.mjs) から削除(commit 分離)
|
|
89
|
+
|
|
90
|
+
## 実装ステップ(案 A 前提・Phase 0 通過後に実施)
|
|
91
|
+
|
|
92
|
+
1. **[src/session-start.mjs](../src/session-start.mjs) 修正**
|
|
93
|
+
- L33: `const { session_id, source, cwd } = payload` に変更して `source` を取得
|
|
94
|
+
- L7-10 のコメントを実機ログに合わせて更新(「source='clear' のときだけ引き継ぐ。startup で来る /clear は取りこぼす」仕様を明記)
|
|
95
|
+
- L48 付近: `if (source === 'clear') { mergePredecessorInto(...) }` でガード
|
|
96
|
+
- 引き継がない場合も [src/session-start.mjs:41-45](../src/session-start.mjs#L41-L45) の sessions INSERT は従来通り実行(DB には残す)
|
|
97
|
+
|
|
98
|
+
2. **[src/session-merger.test.mjs](../src/session-merger.test.mjs) にテスト追加**
|
|
99
|
+
- `resolveMergeTarget` / `mergePredecessorInto` は現状維持(判定は session-start 側に持たせる)
|
|
100
|
+
- 代わりに session-start.mjs の条件分岐をユニット化する。テストは薄めの統合で:
|
|
101
|
+
- source='clear' → `mergePredecessorInto` が呼ばれ合流する
|
|
102
|
+
- source='startup' → 呼ばれず前任 sessions の merged_into が NULL のまま
|
|
103
|
+
- source='resume' → 同上
|
|
104
|
+
- 既存 [src/session-merger.test.mjs:121-151](../src/session-merger.test.mjs#L121-L151) の時系列単調性テストは引き続きパスする前提
|
|
105
|
+
|
|
106
|
+
3. **[src/resume-context.mjs](../src/resume-context.mjs) と注入ヘッダ**
|
|
107
|
+
- 注入は session-start.mjs 側の `mergeResult.merged` 分岐で既に制御されているので修正不要
|
|
108
|
+
- ただし「同一 session 継続(source='resume')での注入」が必要か要検討。現状の resume フックは本計画のスコープ外として deferred(別タスクで検討)
|
|
109
|
+
|
|
110
|
+
4. **[docs/L1_L2_L3_REDESIGN.md](L1_L2_L3_REDESIGN.md) / [CLAUDE.md](../CLAUDE.md) / [README.md](../README.md) の更新**
|
|
111
|
+
- 「記憶張り替えの発火条件は SessionStart source='clear' のみ」を明記
|
|
112
|
+
- CLAUDE.md 冒頭「設計の核」の「`/clear` 後も SQLite はそのまま残る。`SessionStart` フックで前任セッションの全レコードを新 session_id に張り替える」の直後に引き継ぎ条件を追記
|
|
113
|
+
|
|
114
|
+
## 最終検証手順(Phase 0 通過 & 案 A 実装後)
|
|
115
|
+
|
|
116
|
+
1. `node --test src/*.test.mjs` が全部グリーン(既存 + 追加ケース)
|
|
117
|
+
2. 手動 E2E:
|
|
118
|
+
- Throughline 有効状態で VSC を終了
|
|
119
|
+
- VSC 再起動 → 新規セッション → 引き継ぎヘッダが **出ない** ことを確認
|
|
120
|
+
- そのセッション内で `/clear` → 新規セッション → 引き継ぎヘッダが **出る** ことを確認(source='clear' が来たケース)
|
|
121
|
+
- 同じ操作を 3 回繰り返し、source='startup' で /clear した回のスキップが許容範囲か観測
|
|
122
|
+
3. `C:\Users\kite_\.throughline\throughline.db` を直接確認:
|
|
123
|
+
```bash
|
|
124
|
+
node --input-type=module <<'EOF'
|
|
125
|
+
import { getDb } from './src/db.mjs';
|
|
126
|
+
const db = getDb();
|
|
127
|
+
console.log(db.prepare("SELECT session_id, merged_into, created_at FROM sessions ORDER BY created_at DESC LIMIT 10").all());
|
|
128
|
+
EOF
|
|
129
|
+
```
|
|
130
|
+
- 手動新規 / VSC 再起動時の `merged_into` が NULL のまま残ること
|
|
131
|
+
- /clear 後のセッションでのみ前任の `merged_into` が新 session_id を指すこと
|
|
132
|
+
|
|
133
|
+
## 重要ファイル一覧
|
|
134
|
+
|
|
135
|
+
- [src/session-start.mjs](../src/session-start.mjs) — 主変更箇所
|
|
136
|
+
- [src/session-merger.mjs](../src/session-merger.mjs) — 参照のみ(現状維持)
|
|
137
|
+
- [src/session-merger.test.mjs](../src/session-merger.test.mjs) — テスト追加
|
|
138
|
+
- [src/resume-context.mjs](../src/resume-context.mjs) — 参照のみ
|
|
139
|
+
- [CLAUDE.md](../CLAUDE.md) / [docs/L1_L2_L3_REDESIGN.md](L1_L2_L3_REDESIGN.md) / [README.md](../README.md) — ドキュメント更新
|
|
140
|
+
|
|
141
|
+
## Non-Goals (本計画では扱わない)
|
|
142
|
+
|
|
143
|
+
- VSC 拡張側の source 送信挙動の調査・修正(Claude Code 本体のスコープ)
|
|
144
|
+
- 並行セッション X-1 問題の解決([docs/archive/SESSION_LINKING_DESIGN.md:194](archive/SESSION_LINKING_DESIGN.md#L194) で受容済み)
|
|
145
|
+
- source='startup' で来る /clear の取りこぼし対策(案 B/C は fallback として deferred)
|
|
146
|
+
- token-monitor / sc-detail 系 CLI への影響調査(本計画と独立)
|