@tyhld/conductor 0.12.45 → 0.12.46
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/dist/cli.js +3 -0
- package/dist/relay.js +73 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -121,6 +121,8 @@ function loadConfig(args) {
|
|
|
121
121
|
}
|
|
122
122
|
// ★職人の種類(ADR-021)。未設定・知らない値は 'claude'(後退させない)。
|
|
123
123
|
const agentKind = parseAgentKind(process.env.CONDUCTOR_AGENT_KIND);
|
|
124
|
+
// ★1便1context(便 87a1a28a)。既定オフ。1/true/yes/on のときだけ入る。
|
|
125
|
+
const freshContext = /^(1|true|yes|on)$/i.test((process.env.CONDUCTOR_FRESH_CONTEXT ?? '').trim());
|
|
124
126
|
// relay 設定(既定 off。off の間は既存の heartbeat 挙動を一切変えない)。
|
|
125
127
|
const relayEnabled = /^(1|true|yes|on)$/i.test((process.env.CONDUCTOR_RELAY_ENABLED ?? '').trim());
|
|
126
128
|
let relayIntervalSec = 15;
|
|
@@ -154,6 +156,7 @@ function loadConfig(args) {
|
|
|
154
156
|
relayIntervalSec,
|
|
155
157
|
promptIntervalSec,
|
|
156
158
|
agentKind,
|
|
159
|
+
freshContext,
|
|
157
160
|
};
|
|
158
161
|
}
|
|
159
162
|
/** 1回分の報告を送る。送信結果(HTTPステータス)をログ表示する。 */
|
package/dist/relay.js
CHANGED
|
@@ -1694,6 +1694,66 @@ export function hasPendingDeliveryInInput(cap) {
|
|
|
1694
1694
|
}
|
|
1695
1695
|
return block.join('\n').includes('(配達役より)');
|
|
1696
1696
|
}
|
|
1697
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
1698
|
+
// 1便1context:配る直前に職人の会話を新しくする(便 87a1a28a・★既定オフ)
|
|
1699
|
+
//
|
|
1700
|
+
// 【なぜ /clear か(試験用の tmux で本物の Claude Code に当てて実測 2026-09-21)】
|
|
1701
|
+
// ・/clear で会話の記録のファイルが新しくなる(新しい会話の番号・前のファイルは閉じる)。
|
|
1702
|
+
// 終わりと始まりのフック(SessionEnd:clear・SessionStart:clear)も鳴る=旧context の終了。
|
|
1703
|
+
// ・/clear のあとの開始時の背負いは 59,849 トークン=起動した直後(59,713)とほぼ同じ。前の会話は持ち越さない。
|
|
1704
|
+
// ・職人を止めないので、囲いのふた(6bef35c8)も起動待ちも起きない。
|
|
1705
|
+
// ★道具のつなぎ直しはしない(起動時の「つなぎ始め」の記録が /clear のあとには無い)=あとから足した
|
|
1706
|
+
// 口は /clear では使えるようにならない。それが要る日は起こし直し(restart-cc2.sh)を使う。
|
|
1707
|
+
// 【新しくできたかの確かめ】受付側の状態で見る:その作業場所の会話の記録に、打つ前には無かった
|
|
1708
|
+
// ファイルができたか。確かめられなければ false(呼び出し側は配らない)。
|
|
1709
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
1710
|
+
/** 会話を新しくできたかを待つ長さ(ミリ秒)。 */
|
|
1711
|
+
export const RELAY_FRESH_CONFIRM_MS = 10_000;
|
|
1712
|
+
/**
|
|
1713
|
+
* 会話が新しくなってから配るまでに置く間(ミリ秒)。
|
|
1714
|
+
* ★実測(試験用の tmux・本物の Claude Code):新しい会話のファイルができた1秒後に貼り付けると、
|
|
1715
|
+
* 入力欄がまだ整っておらず【貼り付けた本文が落ち、添え書きだけが送信された】(職人は「貼り付けが
|
|
1716
|
+
* 届いていない」と答えて止まった)。間を置いたうえで、画面が入力待ちで落ち着いたことも確かめる。
|
|
1717
|
+
*/
|
|
1718
|
+
export const RELAY_FRESH_SETTLE_MS = 3_000;
|
|
1719
|
+
/** その作業場所の会話の記録のファイル名の一覧。読めなければ空。 */
|
|
1720
|
+
export function listTranscripts(cwd, env = process.env) {
|
|
1721
|
+
try {
|
|
1722
|
+
return readdirSync(claudeTranscriptDir(cwd, env)).filter((n) => n.endsWith('.jsonl'));
|
|
1723
|
+
}
|
|
1724
|
+
catch {
|
|
1725
|
+
return [];
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
export async function freshenContext(site, cwd, d = {
|
|
1729
|
+
listSessions: () => listTranscripts(cwd),
|
|
1730
|
+
type: (text) => runTmux(['send-keys', '-t', site, '-l', text]),
|
|
1731
|
+
enter: () => runTmux(['send-keys', '-t', site, 'Enter']),
|
|
1732
|
+
pause: pauseSync,
|
|
1733
|
+
sleep,
|
|
1734
|
+
ready: () => isIdleStable(site, 'claude'),
|
|
1735
|
+
}, o = { waitMs: RELAY_FRESH_CONFIRM_MS, pollMs: 500 }) {
|
|
1736
|
+
const before = new Set(d.listSessions());
|
|
1737
|
+
try {
|
|
1738
|
+
d.type('/clear');
|
|
1739
|
+
// ★打った字と Enter の間は一拍おく(b69c1608:すぐ続く Enter は改行に取り込まれることがある)。
|
|
1740
|
+
d.pause(RELAY_SUBMIT_PAUSE_MS);
|
|
1741
|
+
d.enter();
|
|
1742
|
+
}
|
|
1743
|
+
catch {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1746
|
+
for (let t = 0;; t += o.pollMs) {
|
|
1747
|
+
if (d.listSessions().some((n) => !before.has(n))) {
|
|
1748
|
+
// ★新しい会話ができた直後は入力欄が整っていない(RELAY_FRESH_SETTLE_MS の説明)。
|
|
1749
|
+
await d.sleep(RELAY_FRESH_SETTLE_MS);
|
|
1750
|
+
return d.ready();
|
|
1751
|
+
}
|
|
1752
|
+
if (t >= o.waitMs)
|
|
1753
|
+
return false;
|
|
1754
|
+
await d.sleep(o.pollMs);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1697
1757
|
/**
|
|
1698
1758
|
* 受け付けられるまで見て、未受付で入力欄に残っているときだけ Enter を押し直す。
|
|
1699
1759
|
* accepted … 押し直さずに受け付けられた
|
|
@@ -2641,6 +2701,19 @@ export async function relayTick(cfg, state, hooks) {
|
|
|
2641
2701
|
noteReadiness(state, 'not-agent', cmd.id);
|
|
2642
2702
|
return;
|
|
2643
2703
|
}
|
|
2704
|
+
// ── 1便1context(★既定オフ・便 87a1a28a) ──
|
|
2705
|
+
// 便を配る直前に職人の会話を新しくする(/clear)。★便を追っている間(state.pending)はここへ
|
|
2706
|
+
// 来ない=質問・確認待ちの便は同じ会話のまま続く。新しくできたと確かめられなければ配らない
|
|
2707
|
+
// (次の周でやり直す)。Codex の職人は対象外。
|
|
2708
|
+
if (cfg.freshContext && kindOf(cfg) === 'claude') {
|
|
2709
|
+
const cwd = tmuxPaneCwd(cfg.site);
|
|
2710
|
+
const fresh = cwd !== null && (await freshenContext(cfg.site, cwd));
|
|
2711
|
+
if (!fresh) {
|
|
2712
|
+
log(`WARN site=${cfg.site} id=${cmd.id} 会話を新しくできなかったので配らずに次の周でやり直します`);
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
log(`site=${cfg.site} id=${cmd.id} 会話を新しくしました(1便1context)`);
|
|
2716
|
+
}
|
|
2644
2717
|
// ── tmux 送信 ──
|
|
2645
2718
|
// この送信に固有のアンカー(buildAnchor(id))を本文末尾に埋め込む。
|
|
2646
2719
|
// 画面にエコーされたアンカー行を「今回ジョブの境界」として記録し、完了検出は
|