@cocorograph/hub-agent 0.8.31 → 0.8.32
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/sibling-inject.mjs +29 -12
package/package.json
CHANGED
package/src/sibling-inject.mjs
CHANGED
|
@@ -85,8 +85,12 @@ export function normalizeProcessStartedAt(raw) {
|
|
|
85
85
|
return raw.trim()
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
async function defaultPidStartedAt(pid) {
|
|
89
|
-
|
|
88
|
+
export async function defaultPidStartedAt(pid, exec = execFile) {
|
|
89
|
+
// 送信側と同じ TZ/locale で比較可能な文字列を作る。契約の正本は Hub の codex_agent.py。
|
|
90
|
+
// launchd / WSL の環境は利用者のシェルと一致しないため、常駐サービスの環境は継承しない。
|
|
91
|
+
const { stdout } = await exec("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
92
|
+
env: { TZ: "UTC", LC_ALL: "C", LANG: "C" },
|
|
93
|
+
})
|
|
90
94
|
return normalizeProcessStartedAt(stdout)
|
|
91
95
|
}
|
|
92
96
|
|
|
@@ -352,6 +356,13 @@ export class SiblingInjectBridge {
|
|
|
352
356
|
}
|
|
353
357
|
}
|
|
354
358
|
|
|
359
|
+
_acceptsDelegateEvent(cwd, sessionId, event) {
|
|
360
|
+
this._pruneDelegations()
|
|
361
|
+
if (event.phase !== "started") return true
|
|
362
|
+
const sessionKey = this._delegationSessionKey(cwd, sessionId)
|
|
363
|
+
return !this._terminalDelegations.get(sessionKey)?.has(event.delegation_id)
|
|
364
|
+
}
|
|
365
|
+
|
|
355
366
|
async _delegateProcessAlive(event) {
|
|
356
367
|
if (!Number.isInteger(event.pid) || event.pid <= 0 || !event.pid_started_at) return true
|
|
357
368
|
try {
|
|
@@ -610,17 +621,23 @@ export class SiblingInjectBridge {
|
|
|
610
621
|
...(pid_started_at !== undefined ? { pid_started_at } : {}),
|
|
611
622
|
timestamp: timestamp || new Date().toISOString(),
|
|
612
623
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
this._recordDelegateEvent(cwd, target_session_id, event)
|
|
618
|
-
result = { ok: true, delivered_to: r.session }
|
|
624
|
+
// 墓標確認から配送成功時の台帳反映まで await を挟まない同期区間に閉じる。
|
|
625
|
+
// 配送失敗した started は台帳へ残さず、終端後に遅着した started は配送前に拒否する。
|
|
626
|
+
if (!this._acceptsDelegateEvent(cwd, target_session_id, event)) {
|
|
627
|
+
result = { ok: false, error: "stale_delegate_event" }
|
|
619
628
|
} else {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
629
|
+
const r = this.claudeBridge?.emitToStream
|
|
630
|
+
? this.claudeBridge.emitToStream(cwd, target_session_id, event)
|
|
631
|
+
: { status: "not_found" }
|
|
632
|
+
if (r.status === "delivered") {
|
|
633
|
+
this._recordDelegateEvent(cwd, target_session_id, event)
|
|
634
|
+
result = { ok: true, delivered_to: r.session }
|
|
635
|
+
} else {
|
|
636
|
+
result = {
|
|
637
|
+
ok: false,
|
|
638
|
+
error: AMBIGUOUS_TARGET_ERROR,
|
|
639
|
+
...(r.candidates ? { candidates: r.candidates } : {}),
|
|
640
|
+
}
|
|
624
641
|
}
|
|
625
642
|
}
|
|
626
643
|
}
|