throughline 0.16.20 → 0.16.21
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/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,28 @@ shipped to npm but were not individually tagged on GitHub.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.16.21] — 2026-10-11
|
|
14
|
+
|
|
15
|
+
### 修正
|
|
16
|
+
|
|
17
|
+
- Claude Codeの自動継続で、受領を確かめられなかった引き継ぎ(`unknown`)の後継をClaude Desktopへ移す処理が、1回しか起きなかった(0.16.19で入れた処理の漏れ。[ADR 0049](docs/adr/0049-claude-handoff-uses-registered-project.md))。1回目のStopで後継のsession idを記録へ入れるが、次のStopで記録を探す条件は「session idがまだ無い」だった。1回目に後継が手すきにならずに戻ると、その後のターンの終わりでは何も起きず、後継は裏の会話のまま残った。Windowsの実機で1回起きた(2026-10-10 23:43の引き継ぎ。1回目は10-11 02:51で、後継は保留の文で`waiting`だった。その後の09:10と10:03のターンの終わりでは、移す処理が起きなかった)。
|
|
18
|
+
- session idが記録にある時は、そのidが同じ会話のStopで、同じ記録からやり直す。短いIDの先頭一致で探すのは、session idがまだ無い時だけ。
|
|
19
|
+
- 受領が残った引き継ぎ(`sent`)の後継は、今までもやり直していた。変えていない。
|
|
20
|
+
|
|
21
|
+
### 対応の範囲
|
|
22
|
+
|
|
23
|
+
| | macOS | Linux | Windows |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| Claude Code | 直した。単体試験と、実機(Claude Code 2.1.289)。試験用の場所の記録と本物の`claude agents`で、0.16.20は戻った後のStopで何もせず、直した版は移すprocessをもう1回起こす事 | 記録を探す処理は同じ物なので直っている。単体試験と、実機(Claude Code 2.1.296)で同じ確認。ただしClaude Desktopへ移す処理は、Linuxでは起動しない(Claude Codeの`--desktop`が無い) | 直した。単体試験と、実機(Claude Code 2.1.296)で同じ確認。この失敗が起きた本物の記録を試験用の場所へ写した物でも、0.16.20は何もせず、直した版は移すprocessを起こす事 |
|
|
26
|
+
| Codex | 変更なし(引き継ぎの部品が別。Desktopへ移す処理が無い) | 同じ | 同じ |
|
|
27
|
+
| Grok | 変更なし(自動継続が無い) | 同じ | 同じ |
|
|
28
|
+
| Cursor | 変更なし(自動継続が無い) | 同じ | 同じ |
|
|
29
|
+
|
|
30
|
+
### 確かめていない事
|
|
31
|
+
|
|
32
|
+
- 本物の引き継ぎで、受領を確かめられなかった後継が、2回目より後のStopでClaude Desktopへ移る所。0.16.19より後、受領を確かめられない引き継ぎは起きていない(狙って起こせない)。
|
|
33
|
+
- この失敗が起きた会話(2026-10-10 23:43の後継)は、直す前に次の後継へ引き継いだ。作業は次の後継が続けていて、この会話はDesktopへ移さない。
|
|
34
|
+
|
|
13
35
|
## [0.16.20] — 2026-10-11
|
|
14
36
|
|
|
15
37
|
### 修正
|
|
@@ -2331,7 +2353,8 @@ two attempts, instrument first instead of patching again.
|
|
|
2331
2353
|
|
|
2332
2354
|
---
|
|
2333
2355
|
|
|
2334
|
-
[Unreleased]: https://github.com/kitepon/Throughline/compare/v0.16.
|
|
2356
|
+
[Unreleased]: https://github.com/kitepon/Throughline/compare/v0.16.21...HEAD
|
|
2357
|
+
[0.16.21]: https://github.com/kitepon/Throughline/compare/v0.16.20...v0.16.21
|
|
2335
2358
|
[0.16.20]: https://github.com/kitepon/Throughline/compare/v0.16.19...v0.16.20
|
|
2336
2359
|
[0.16.19]: https://github.com/kitepon/Throughline/compare/v0.16.18...v0.16.19
|
|
2337
2360
|
[0.16.18]: https://github.com/kitepon/Throughline/compare/v0.16.17...v0.16.18
|
|
@@ -33,6 +33,9 @@ Claude Code の自動継続は、PreCompact の hook で、後継を立てる pr
|
|
|
33
33
|
3. 受領を確かめられなかった引き継ぎ(`unknown`、後継の短い ID だけが記録にある)でも、その後継がターンを終えたら、
|
|
34
34
|
Desktop へ移す。継続の指示は起動時の引数で渡してあるので、ターンを終えた後継は指示を受けている。
|
|
35
35
|
後継の session id を記録へ入れる。`state` と `error_code` は変えない(記憶が合流しなかった事は、記録に残す)。
|
|
36
|
+
移す process が後継の手すきを待ち切れずに戻った時は、次の Stop で同じ記録からやり直す。この時は、記録に入れた
|
|
37
|
+
session id が同じ会話だけを対象にする(0.16.21。0.16.19 と 0.16.20 は、session id が無い記録だけを探していて、
|
|
38
|
+
2回目より後の Stop では何も起きなかった。Windows の実機で 2026-10-11 に1回起きた)。
|
|
36
39
|
4. 後継が立たなかった引き継ぎ(`failed`)は、今までどおり何もしない。
|
|
37
40
|
|
|
38
41
|
## Consequences
|
package/package.json
CHANGED
|
@@ -833,9 +833,10 @@ export async function requestClaudeDesktopOpen({ sessionId, transcriptPath = nul
|
|
|
833
833
|
const waiting = listClaudeAutoHandoffs({ dir }).filter(item => item.desktop?.wanted && !item.desktop.state);
|
|
834
834
|
// 受領を確かめられなかった引き継ぎ(unknown)は、後継の session id が記録に無い。その後継がターンを終えたなら、
|
|
835
835
|
// 後継は動いている。裏の会話のまま残さず、同じように Desktop へ移す(ADR 0049)。
|
|
836
|
+
// 1回目の Stop で session id を記録へ入れるので、移せずに戻った後の Stop は、その id で同じ記録を見つける。
|
|
836
837
|
const record = waiting.find(item => item.state === 'sent' && item.successor?.session_id === sessionId) ??
|
|
837
|
-
waiting.find(item => item.state === 'unknown' &&
|
|
838
|
-
|
|
838
|
+
waiting.find(item => item.state === 'unknown' && typeof item.successor?.short_id === 'string' &&
|
|
839
|
+
(item.successor.session_id ? item.successor.session_id === sessionId : sessionId.startsWith(item.successor.short_id)));
|
|
839
840
|
if (!record) return null;
|
|
840
841
|
const successor = { ...record.successor, session_id: sessionId };
|
|
841
842
|
if (typeof transcriptPath === 'string' && transcriptPath) successor.transcript_path = transcriptPath;
|
|
@@ -796,6 +796,16 @@ test('Stop: 受領を確かめられなかった引き継ぎ(unknown)でも
|
|
|
796
796
|
'受領を確かめられなかった事は、記録に残したままにする');
|
|
797
797
|
assert.equal(await requestClaudeDesktopOpen({ sessionId: SUCCESSOR, dir, launch }), null, '2回目の Stop では起動しない');
|
|
798
798
|
|
|
799
|
+
// 移す process が、手すきを待ち切れずに戻った(fox の実物、2026-10-11 02:51)。記録には後継の session id が入っている。
|
|
800
|
+
// 次の Stop で、同じ記録からやり直す
|
|
801
|
+
const busy = await runClaudeDesktopOpen(SESSION, { dir, env: {}, pollMs: 10, idleTimeoutMs: 40, pty: () => { throw new Error('must not open'); },
|
|
802
|
+
spawn: (command, args) => { assert.equal(args[0], 'agents'); return { status: 0, stdout: JSON.stringify([{ id: SUCCESSOR.slice(0, 8), kind: 'background', status: 'busy' }]) }; } });
|
|
803
|
+
assert.deepEqual([busy.state, busy.desktop.state, busy.successor.session_id], ['unknown', null, SUCCESSOR]);
|
|
804
|
+
assert.equal(await requestClaudeDesktopOpen({ sessionId: `${SUCCESSOR.slice(0, 8)}-0000-4000-8000-000000000009`, dir, launch }), null, '短い ID が同じでも、別の会話の Stop では動かない');
|
|
805
|
+
assert.equal(await requestClaudeDesktopOpen({ sessionId: SUCCESSOR, dir, launch }), `h-${SESSION}`, '戻った後の Stop でやり直す');
|
|
806
|
+
assert.deepEqual(launched, [SESSION, SESSION]);
|
|
807
|
+
assert.equal(readClaudeAutoHandoff(SESSION, dir).desktop.state, 'requested');
|
|
808
|
+
|
|
799
809
|
// 移す process は、その記録で後継を止めて Desktop で開く
|
|
800
810
|
const calls = [];
|
|
801
811
|
const opened = await runClaudeDesktopOpen(SESSION, { dir, env: {}, pollMs: 10, idleTimeoutMs: 500,
|