@cocorograph/hub-agent 0.8.21 → 0.8.23

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/src/tmux.mjs CHANGED
@@ -22,6 +22,7 @@ import { promisify } from "node:util"
22
22
 
23
23
  import { ensureClaudeMd } from "./claude-md.mjs"
24
24
  import { syncClaudeMdWithHub } from "./claude-md-sync.mjs"
25
+ import { createSessionBudget } from "./hub-request-deadline.mjs"
25
26
  import { detectSessionState, getSessionCwd } from "./state.mjs"
26
27
  import { shouldLaunchPaneCli } from "./pane-cli-flag.mjs"
27
28
  import { baseSessionName, sessionNameFor } from "./session-names.mjs"
@@ -836,45 +837,65 @@ export async function createSession(name, cwd, opts = {}) {
836
837
  // .bak.conflict に退避)。Hub が一度も保存されていないプロジェクトでは
837
838
  // 何もしない(テナント標準 CLAUDE.md の運用を尊重する)。
838
839
  // どちらも失敗しても session 起動自体は止めない (warn のみ)。
840
+ // ⚠️ 2 つの呼び出しで **1 本の budget を共有**する。1 往復ごとの期限だけでは
841
+ // 往復の本数ぶん足し算されてセッション起動が長時間止まりうるため、Hub 処理に
842
+ // 割り当てた wall-clock 予算(予算の生成時からの経過時間で、通信の待ち時間の
843
+ // 累積ではない)で全体を打ち切る。予算切れなら「何も書かずに次回へ持ち越す」。
839
844
  if (isUnderHubProjectsBase(resolvedCwd)) {
840
845
  const instructionDir = projectInstructionDir(resolvedCwd)
841
846
  const dirName = path.basename(instructionDir)
842
847
  const configFilename = opts.cliKind === "codex" ? "AGENTS.md" : "CLAUDE.md"
848
+ const budget = createSessionBudget()
849
+ // ⚠️ `ensureClaudeMd` の戻り値を捨てない。`source === 'existing'` は
850
+ // 「このセッションより前からローカルにファイルがあった」= **初回登録**
851
+ // (Hub に無くローカルにあるものを 1 度だけ Hub へ取り込む)の唯一の根拠で、
852
+ // ディスクに残さずここから同期へ手渡す。例外時は **undefined のまま渡さない**
853
+ // (=登録しない。何が起きたか分からない回に Hub を触らせない安全側)。
854
+ let localFilePreexisted
843
855
  try {
844
- await ensureClaudeMd({
845
- targetDir: instructionDir,
846
- dirName,
847
- hubUrl: opts.hubUrl,
848
- accessToken: opts.hubAccessToken,
849
- logger: opts.logger,
850
- fetchImpl: opts.fetchImpl,
851
- configFilename,
852
- })
853
- } catch (err) {
854
- opts.logger?.warn?.(
855
- { session: name, cwd: resolvedCwd, err: err?.message || String(err) },
856
- "ensureClaudeMd failed (workspace dir is usable, but no CLAUDE.md)",
857
- )
858
- }
859
- try {
860
- const syncResult = await syncClaudeMdWithHub({
861
- targetDir: instructionDir,
862
- dirName,
863
- hubUrl: opts.hubUrl,
864
- accessToken: opts.hubAccessToken,
865
- logger: opts.logger,
866
- fetchImpl: opts.fetchImpl,
867
- configFilename,
868
- })
869
- opts.logger?.debug?.(
870
- { session: name, dirName, sync: syncResult },
871
- "syncClaudeMdWithHub completed",
872
- )
873
- } catch (err) {
874
- opts.logger?.warn?.(
875
- { session: name, cwd: resolvedCwd, err: err?.message || String(err) },
876
- "syncClaudeMdWithHub failed (session starts anyway)",
877
- )
856
+ try {
857
+ const ensure = await ensureClaudeMd({
858
+ targetDir: instructionDir,
859
+ dirName,
860
+ hubUrl: opts.hubUrl,
861
+ accessToken: opts.hubAccessToken,
862
+ logger: opts.logger,
863
+ fetchImpl: opts.fetchImpl,
864
+ configFilename,
865
+ budget,
866
+ })
867
+ localFilePreexisted = ensure?.source === "existing"
868
+ } catch (err) {
869
+ opts.logger?.warn?.(
870
+ { session: name, cwd: resolvedCwd, err: err?.message || String(err) },
871
+ "ensureClaudeMd failed (workspace dir is usable, but no CLAUDE.md)",
872
+ )
873
+ }
874
+ try {
875
+ const syncResult = await syncClaudeMdWithHub({
876
+ targetDir: instructionDir,
877
+ dirName,
878
+ hubUrl: opts.hubUrl,
879
+ accessToken: opts.hubAccessToken,
880
+ logger: opts.logger,
881
+ fetchImpl: opts.fetchImpl,
882
+ configFilename,
883
+ budget,
884
+ // undefined のときはキーごと渡さない(呼び出し側の意図を明示する)。
885
+ ...(localFilePreexisted === undefined ? {} : { localFilePreexisted }),
886
+ })
887
+ opts.logger?.debug?.(
888
+ { session: name, dirName, sync: syncResult },
889
+ "syncClaudeMdWithHub completed",
890
+ )
891
+ } catch (err) {
892
+ opts.logger?.warn?.(
893
+ { session: name, cwd: resolvedCwd, err: err?.message || String(err) },
894
+ "syncClaudeMdWithHub failed (session starts anyway)",
895
+ )
896
+ }
897
+ } finally {
898
+ budget.clear()
878
899
  }
879
900
  }
880
901
  // 既存チェック