@cocorograph/hub-agent 0.7.95 → 0.7.97
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/chat-signals.mjs +17 -5
- package/src/main.mjs +3 -1
- package/src/state.mjs +10 -0
- package/src/tmux.mjs +8 -2
package/package.json
CHANGED
package/src/chat-signals.mjs
CHANGED
|
@@ -49,8 +49,9 @@ import { normalizeCliKind } from "./session-names.mjs"
|
|
|
49
49
|
// updatedAtMs, cliKind, sessionId }
|
|
50
50
|
const _byKey = new Map()
|
|
51
51
|
|
|
52
|
-
//
|
|
53
|
-
// スクレイプ結果へフォールバックさせる (チャット終了/別モード移行の検知)
|
|
52
|
+
// チャット status を「生きている」と見なす最大経過時間 (ms)。これを過ぎたら status は tmux
|
|
53
|
+
// スクレイプ結果へフォールバックさせる (チャット終了/別モード移行の検知)。ただし sessionId に
|
|
54
|
+
// 帰属した context snapshot は status と別に保持する。
|
|
54
55
|
// 90s: SDK の result/abort を取りこぼしても status=processing がこの時間で解除される
|
|
55
56
|
// (RC-4 偽陽性 = 中断/異常終了で三点リーダーが固着する最長時間の短縮。旧 15 分)。正常な
|
|
56
57
|
// 生成中は SDK の assistant イベントが頻繁に updatedAtMs/statusAt を前進させるため途中で
|
|
@@ -189,7 +190,8 @@ export function recordChatStreamTick(cwd, cliKind, now = _now()) {
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
/**
|
|
192
|
-
* (cwd, cliKind)
|
|
193
|
+
* (cwd, cliKind) に対応するチャット信号を返す。status は stale なら null へ落とすが、
|
|
194
|
+
* sessionId に帰属する context snapshot は明示切替まで保持する。
|
|
193
195
|
*
|
|
194
196
|
* @param {string} cwd
|
|
195
197
|
* @param {'claude'|'codex'} cliKind
|
|
@@ -201,12 +203,22 @@ export function getChatSignal(cwd, cliKind, now = _now()) {
|
|
|
201
203
|
if (!key) return null
|
|
202
204
|
const sig = _byKey.get(key)
|
|
203
205
|
if (!sig) return null
|
|
204
|
-
|
|
206
|
+
// SDK チャットは応答完了後に長時間イベントが無くても、同じ sessionId の context 値自体は
|
|
207
|
+
// 無効化されない。これを丸ごと null にすると、SDK 専用チャットの tmux が未開始画面 (0%)
|
|
208
|
+
// の場合に正しいドーナツ→0%/非表示へフラップする。TUI 切替時は clearChatSignal が呼ばれる。
|
|
209
|
+
const hasBoundContext =
|
|
210
|
+
typeof sig.sessionId === "string" &&
|
|
211
|
+
sig.sessionId.length > 0 &&
|
|
212
|
+
typeof sig.context_pct === "number" &&
|
|
213
|
+
Number.isFinite(sig.context_pct)
|
|
214
|
+
if (now - sig.updatedAtMs > CHAT_SIGNAL_STALE_MS) {
|
|
215
|
+
return hasBoundContext ? { ...sig, status: null } : null
|
|
216
|
+
}
|
|
205
217
|
// status / context_pct 自体の鮮度は statusAt で判定する。inputPending だけが
|
|
206
218
|
// 信号を延命している間 (= TUI モードで承認カードだけが届く状況) は、stale な
|
|
207
219
|
// SDK 由来の status / context_pct を返さず capture-pane の実値に委ねる。
|
|
208
220
|
if (now - (sig.statusAt || 0) > CHAT_SIGNAL_STALE_MS) {
|
|
209
|
-
return { ...sig, status: null, context_pct: null }
|
|
221
|
+
return { ...sig, status: null, context_pct: hasBoundContext ? sig.context_pct : null }
|
|
210
222
|
}
|
|
211
223
|
return sig
|
|
212
224
|
}
|
package/src/main.mjs
CHANGED
|
@@ -2636,7 +2636,9 @@ export function startStateLoop({ client, plugins, logger, intervalMs, claudeBrid
|
|
|
2636
2636
|
const chatCliKind = sessionCliKind
|
|
2637
2637
|
const contextSessionId =
|
|
2638
2638
|
chat?.sessionId ??
|
|
2639
|
-
(sessionCliKind === "claude"
|
|
2639
|
+
(sessionCliKind === "claude"
|
|
2640
|
+
? boundSessions?.get(s.session_name) ?? `unbound:${s.session_name}`
|
|
2641
|
+
: codexThreadId)
|
|
2640
2642
|
|
|
2641
2643
|
const prev = lastByName.get(s.session_name)
|
|
2642
2644
|
if (
|
package/src/state.mjs
CHANGED
|
@@ -313,6 +313,16 @@ export function detectContextPctFromText(text) {
|
|
|
313
313
|
if (Number.isFinite(n) && n >= 0 && n <= 100) return n
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
+
// Claude の初回 Chrome 連携確認は、TUI セッションがまだ会話を開始していないことを
|
|
317
|
+
// 明示する画面。context 行は未描画だが使用量は実際に 0% なので、同一 cwd に残った
|
|
318
|
+
// 過去 jsonl の高使用率を採用せず 0% を返す。文言の一部だけで誤認しないよう、製品名と
|
|
319
|
+
// 選択肢を対にして判定する。
|
|
320
|
+
if (
|
|
321
|
+
/Claude in Chrome extension detected/i.test(text) &&
|
|
322
|
+
/Yes,? use my browser/i.test(text)
|
|
323
|
+
) {
|
|
324
|
+
return 0
|
|
325
|
+
}
|
|
316
326
|
return null
|
|
317
327
|
}
|
|
318
328
|
|
package/src/tmux.mjs
CHANGED
|
@@ -687,13 +687,19 @@ export async function listSessions(opts = {}) {
|
|
|
687
687
|
boundSessionId(opts.boundSessions, s.name) ||
|
|
688
688
|
(cwd && opts.claudeBridge?.liveSessionIdForCwd?.(cwd)) ||
|
|
689
689
|
null
|
|
690
|
-
|
|
690
|
+
// cwd だけでは同じリポジトリで並走する別 Claude / subagent / 過去会話を区別できない。
|
|
691
|
+
// bound ID が無い状態で statusLine/jsonl の「cwd 最新値」を使うと、再起動後や未オープンの
|
|
692
|
+
// tmux セッションへ別会話の 98〜100% が混入する。実際に値の帰属先を示せる bound session
|
|
693
|
+
// がある場合だけ per-session cache を採用し、無ければ capture-pane の当該行由来値 (または
|
|
694
|
+
// null) に留める。null は「不明」であり、他会話の数値を表示するより正しい。
|
|
695
|
+
const hasBoundSession = typeof boundId === "string" && boundId.length > 0
|
|
696
|
+
const jsonlInfo = hasBoundSession && cwd ? await jsonlContextForCwd(cwd, boundId) : null
|
|
691
697
|
const context_pct =
|
|
692
698
|
freshUnbound
|
|
693
699
|
? 0
|
|
694
700
|
: jsonlInfo?.isReset && typeof jsonlInfo.percent === "number"
|
|
695
701
|
? jsonlInfo.percent
|
|
696
|
-
: typeof fromStatusLine === "number"
|
|
702
|
+
: hasBoundSession && typeof fromStatusLine === "number"
|
|
697
703
|
? fromStatusLine
|
|
698
704
|
: typeof jsonlInfo?.percent === "number"
|
|
699
705
|
? jsonlInfo.percent
|