@cocorograph/hub-agent 0.8.11 → 0.8.12
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/package.json +1 -1
- package/src/claude-stream-bridge.mjs +28 -13
- package/src/main.mjs +4 -0
package/package.json
CHANGED
|
@@ -523,11 +523,12 @@ export class ClaudeStreamSession {
|
|
|
523
523
|
this._permissionResolvers = new Map()
|
|
524
524
|
/** 現在ターン実行中か (多重 query 防止) */
|
|
525
525
|
this._busy = false
|
|
526
|
-
/** SDK-P0-3 (2026-07-10): 現ターンが既に終端処理済みか (idle / abort の
|
|
526
|
+
/** SDK-P0-3 (2026-07-10): 現ターンが既に終端処理済みか (result / idle / abort の
|
|
527
527
|
* いずれか 1 回だけ _busy=false + drain させるための冪等ガード)。resident query は
|
|
528
528
|
* `result` の後にもバックグラウンド処理が続き、最後に権威的な
|
|
529
|
-
* `session_state_changed:idle`
|
|
530
|
-
*
|
|
529
|
+
* `session_state_changed:idle` が流れることがある。実 SDK では result 後に idle が
|
|
530
|
+
* 来ないターンもあるため、result / idle の先着 1 件だけが settle し、遅延 idle は
|
|
531
|
+
* _staleIdleExpected で次ターンから隔離する。ターン開始時に false へ戻す。 */
|
|
531
532
|
this._turnSettled = false
|
|
532
533
|
/** SDK-P0-3: 現ターンが 1 件でもストリームイベントを出したか。
|
|
533
534
|
* 「前ターンの遅延 idle が、drain で始まったばかりの次ターンを誤終了させる」レースの
|
|
@@ -1630,10 +1631,11 @@ export class ClaudeStreamSession {
|
|
|
1630
1631
|
}
|
|
1631
1632
|
}
|
|
1632
1633
|
|
|
1633
|
-
/** resident
|
|
1634
|
-
*
|
|
1635
|
-
*
|
|
1636
|
-
*
|
|
1634
|
+
/** resident の「ターン終端」を 1 箇所に集約する。
|
|
1635
|
+
* SDK は result 後に session_state_changed:idle を返すことがあるが、実環境では
|
|
1636
|
+
* idle が欠落するターンもある。result / idle の先着を終端とし、result で畳んだ後の
|
|
1637
|
+
* 遅延 idle はガードで次ターンから隔離する。
|
|
1638
|
+
* @param {string} reason "result" | "idle" — ログ用
|
|
1637
1639
|
* @param {(msg: string) => void} [denyPending] 未解決 permission を閉じるクロージャ
|
|
1638
1640
|
*/
|
|
1639
1641
|
_settleResidentTurn(reason, denyPending) {
|
|
@@ -1641,6 +1643,10 @@ export class ClaudeStreamSession {
|
|
|
1641
1643
|
this._turnSettled = true
|
|
1642
1644
|
denyPending?.("turn ended")
|
|
1643
1645
|
this._busy = false
|
|
1646
|
+
// result の後に同一ターンの idle が遅れて届く場合がある。pending drain は同期的に
|
|
1647
|
+
// 次ターンの busy を立てるため、その idle を新ターンへ誤帰属させないよう先にガードする。
|
|
1648
|
+
// idle 自身で畳んだ場合は既に消費済みなので張らない。
|
|
1649
|
+
if (reason === "result") this._armStaleIdleGuard()
|
|
1644
1650
|
// 改修4 (A): シリアライズした pending があれば次の 1 件を InputQueue へ流す。
|
|
1645
1651
|
// ultracode (0.6.28): _drainResidentPending は applyFlagSettings を await するため
|
|
1646
1652
|
// async。for await ループ内からは fire-and-forget で呼ぶ (最初の await より前に
|
|
@@ -1766,12 +1772,12 @@ export class ClaudeStreamSession {
|
|
|
1766
1772
|
}
|
|
1767
1773
|
if (msg?.type === "result") {
|
|
1768
1774
|
if (typeof msg.session_id === "string") this.sessionId = msg.session_id
|
|
1769
|
-
// result は結果 flush でありターン終了ではない。SDK の型定義が権威的な
|
|
1770
|
-
// turn-over signal とする session_state_changed:idle まで busy を維持し、
|
|
1771
|
-
// pending を streaming input へ流さない。
|
|
1772
1775
|
// 現ターンの result が届いた時点で前ターンの遅延 idle は順序保証により
|
|
1773
|
-
//
|
|
1776
|
+
// 既に通過済み。古いガードを解除し、result 用のガードを張り直して settle する。
|
|
1777
|
+
// 実 SDK では result 後に idle が来ないターンがあるため、idle 待ちだけにすると
|
|
1778
|
+
// _busy が永久に true のまま固着し、以後の入力が pending から drain されない。
|
|
1774
1779
|
this._clearStaleIdleGuard()
|
|
1780
|
+
this._settleResidentTurn("result", denyPending)
|
|
1775
1781
|
} else if (isSessionIdleEvent(msg)) {
|
|
1776
1782
|
// SDK-P0-3 (2026-07-10): result が届かずに idle でターンが終わるケースの救済。
|
|
1777
1783
|
// これを見ていなかったため _busy が true で固着し、以降の送信が
|
|
@@ -2282,7 +2288,12 @@ export class ClaudeStreamBridge extends EventEmitter {
|
|
|
2282
2288
|
},
|
|
2283
2289
|
"claude stream reattached to live session",
|
|
2284
2290
|
)
|
|
2285
|
-
return {
|
|
2291
|
+
return {
|
|
2292
|
+
stream_id,
|
|
2293
|
+
resuming: true,
|
|
2294
|
+
reattached: true,
|
|
2295
|
+
turn_active: live._busy === true,
|
|
2296
|
+
}
|
|
2286
2297
|
}
|
|
2287
2298
|
}
|
|
2288
2299
|
const session = new ClaudeStreamSession({
|
|
@@ -2395,7 +2406,11 @@ export class ClaudeStreamBridge extends EventEmitter {
|
|
|
2395
2406
|
)
|
|
2396
2407
|
// per-message モデルでは attach 時点では query() を起動しない (即 ready)。
|
|
2397
2408
|
// 最初の input で query を起動する。
|
|
2398
|
-
return {
|
|
2409
|
+
return {
|
|
2410
|
+
stream_id,
|
|
2411
|
+
resuming: !!resumeSessionId,
|
|
2412
|
+
turn_active: session._busy === true,
|
|
2413
|
+
}
|
|
2399
2414
|
}
|
|
2400
2415
|
|
|
2401
2416
|
/**
|
package/src/main.mjs
CHANGED
|
@@ -3433,6 +3433,10 @@ async function dispatch(msg, ctx) {
|
|
|
3433
3433
|
type: "claude.ready",
|
|
3434
3434
|
stream_id,
|
|
3435
3435
|
resuming: info.resuming,
|
|
3436
|
+
// 再接続時の生成状態は resident session を保持する hub-agent が正本。
|
|
3437
|
+
// jsonl 履歴末尾の推測だけでは「実際は busy なのに UI は idle」となり、
|
|
3438
|
+
// 送信ボタンが楽観バブルを作る一方 agent はキューへ積む二重表示が起きる。
|
|
3439
|
+
turn_active: info.turn_active === true,
|
|
3436
3440
|
history_pushed: resumeSessionId !== null,
|
|
3437
3441
|
// id 空間統一 (2026-07-08): この agent は browser の input_id をキュー id として
|
|
3438
3442
|
// 採用し、楽観送信待ちアイテムの確認前キャンセルに対応することを通知する capability。
|