@cocorograph/hub-agent 0.7.93 → 0.7.94

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/main.mjs +67 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocorograph/hub-agent",
3
- "version": "0.7.93",
3
+ "version": "0.7.94",
4
4
  "description": "Hub Hosted Cockpit のローカル常駐 agent。Hub と outbound WSS で接続し、ローカルの tmux/pty を中継する。",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
package/src/main.mjs CHANGED
@@ -3076,6 +3076,50 @@ export function handleClaudeChatInput(msg, ctx) {
3076
3076
  })
3077
3077
  }
3078
3078
 
3079
+ /**
3080
+ * claude.attach の ready 直後にpushする履歴を組み立てる。
3081
+ * Browserからの claude.history.request 往復を省くため、resume時だけ先回りして読む。
3082
+ * 失敗しても空のhistory.responseへ縮退し、attach自体を失敗させない。
3083
+ */
3084
+ export async function loadClaudeAttachHistory({
3085
+ cwd,
3086
+ sessionId,
3087
+ logger,
3088
+ getProjectsRootFn = getActiveProjectsRoot,
3089
+ fetchHistoryFn = fetchSessionHistory,
3090
+ }) {
3091
+ if (!cwd || !sessionId) return null
3092
+ try {
3093
+ const projectsRoot = await getProjectsRootFn()
3094
+ const result = await fetchHistoryFn({
3095
+ cwd,
3096
+ session_id: sessionId,
3097
+ maxLines: 500,
3098
+ projectsRoot,
3099
+ logger,
3100
+ })
3101
+ return {
3102
+ type: "claude.history.response",
3103
+ session_id: sessionId,
3104
+ cwd,
3105
+ events: result.events || [],
3106
+ total_lines: result.total_lines || 0,
3107
+ truncated: result.truncated === true,
3108
+ error: result.error,
3109
+ }
3110
+ } catch (err) {
3111
+ return {
3112
+ type: "claude.history.response",
3113
+ session_id: sessionId,
3114
+ cwd,
3115
+ events: [],
3116
+ total_lines: 0,
3117
+ truncated: false,
3118
+ error: err?.message || String(err),
3119
+ }
3120
+ }
3121
+ }
3122
+
3079
3123
  /**
3080
3124
  * SDK チャット配達保証 (S2, 2026-07-05): `codex.input` を処理し、browser が付与した
3081
3125
  * `input_id` があれば `codex.input.ack` / `codex.input.nack` を返す (claude.input と
@@ -3494,6 +3538,16 @@ async function dispatch(msg, ctx) {
3494
3538
  // model / permissionMode は agent.json の値も使えるよう fallback。
3495
3539
  const cwdArg = msg.cwd || ctx.config?.claude_cwd || undefined
3496
3540
  const resumeSessionId = msg.resume_session_id || null
3541
+ // attachは同期処理なので、履歴I/Oを先に開始してreadyまでの待ちを重ねる。
3542
+ // 新Browserはhistory_pushedを見て別requestを省略し、旧Browserは従来どおり
3543
+ // requestしてもhydrateのuuid dedupで安全に収束する。
3544
+ const historyPromise = resumeSessionId
3545
+ ? loadClaudeAttachHistory({
3546
+ cwd: cwdArg || process.env.HOME || process.cwd(),
3547
+ sessionId: resumeSessionId,
3548
+ logger: ctx.logger,
3549
+ })
3550
+ : Promise.resolve(null)
3497
3551
  const info = ctx.claudeBridge.attach({
3498
3552
  stream_id,
3499
3553
  cwd: cwdArg,
@@ -3517,12 +3571,25 @@ async function dispatch(msg, ctx) {
3517
3571
  type: "claude.ready",
3518
3572
  stream_id,
3519
3573
  resuming: info.resuming,
3574
+ history_pushed: resumeSessionId !== null,
3520
3575
  // id 空間統一 (2026-07-08): この agent は browser の input_id をキュー id として
3521
3576
  // 採用し、楽観送信待ちアイテムの確認前キャンセルに対応することを通知する capability。
3522
3577
  // 旧 agent にはこのフラグが無く、browser は楽観アイテムの×を出さない (ゴースト
3523
3578
  // 実行防止のフォールバック)。
3524
3579
  supports_queue_input_id: true,
3525
3580
  })
3581
+ // dispatch全体はWSメッセージ順を守る直列キュー上にある。ここで履歴I/Oをawaitすると
3582
+ // 同一接続のpermission/input等まで停止するため、readyの同期送信後は非同期でpushする。
3583
+ void historyPromise
3584
+ .then((pushedHistory) => {
3585
+ if (pushedHistory) ctx.client.send({ ...pushedHistory, stream_id })
3586
+ })
3587
+ .catch((err) => {
3588
+ ctx.logger?.warn?.(
3589
+ { err: err?.message || String(err), stream_id },
3590
+ "failed to push Claude attach history",
3591
+ )
3592
+ })
3526
3593
  // S1 (2026-07): セッション状態の identity 正本化。TUI の claude.tui.bind
3527
3594
  // (main.mjs 内 clearChatSignal 呼び出し箇所参照) と対称に、SDK チャットの
3528
3595
  // attach 時点でも前セッションのチャット信号を引き継がない。