@tyhld/conductor 0.12.40 → 0.12.41
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/relay.js +55 -21
- package/package.json +1 -1
- package/skills/conductor-craftsman/SKILL.md +26 -0
package/dist/relay.js
CHANGED
|
@@ -970,7 +970,9 @@ export function selectOrphanToRestore(orphans, currentPending) {
|
|
|
970
970
|
}
|
|
971
971
|
/**
|
|
972
972
|
* 実際に tmux へ流し込む1行テキストを組み立てる純粋関数。
|
|
973
|
-
* 送る本文 = 指示body +
|
|
973
|
+
* 送る本文 = 指示body + 便の終え方(Claude=1行 shortCompletionLine/Codex=全文 fullCompletionGuide)+ アンカー。
|
|
974
|
+
* ★Claude の職人は鉄則を会話ごとに1回だけ読む(実測・便 a5306df2:便1〜30本の会話12件すべてで1回)。
|
|
975
|
+
* 毎便同じ書き方の説明は鉄則の「便の終え方」へ寄せ、便には便ごとに変わる値の1行だけを付ける。
|
|
974
976
|
* CC2 の途中送信を防ぐため、改行はすべて空白に潰して「1行=1メッセージ」にする
|
|
975
977
|
* (本文内に生 Enter を含めない=送信は末尾の Enter 1回だけにするため)。
|
|
976
978
|
*
|
|
@@ -986,25 +988,59 @@ export function selectOrphanToRestore(orphans, currentPending) {
|
|
|
986
988
|
* 画面では送信エコーの末尾に出る=完了検出(hasDoneBelowAnchor)の境界になる。
|
|
987
989
|
* 末尾に置く理由: アンカーより上に来る指示文中の "DONE:{site}" を完了検出から確実に除外するため。
|
|
988
990
|
*/
|
|
989
|
-
export function buildSendText(body, site, anchor) {
|
|
990
|
-
const marker = `DONE:${site}`;
|
|
991
|
+
export function buildSendText(body, site, anchor, kind = 'claude') {
|
|
991
992
|
// anchor から素の commandId を取り出す(conductor_complete に渡す引数。接頭辞無しなので新たな
|
|
992
993
|
// アンカー一致を作らず、sliceBelowAnchor の境界判定に干渉しない)。
|
|
993
994
|
const commandId = anchor.startsWith(`${SEND_ANCHOR_PREFIX}:`)
|
|
994
995
|
? anchor.slice(SEND_ANCHOR_PREFIX.length + 1)
|
|
995
996
|
: anchor;
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
//
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
997
|
+
// ★Claude の職人には「便の終え方」の1行だけを付ける(書き方の正本は鉄則の「便の終え方」の節)。
|
|
998
|
+
// ★Codex の職人には今までどおり全文を付ける。鉄則(~/.claude/skills)は Codex には届かないため。
|
|
999
|
+
const guide = kind === 'codex' ? fullCompletionGuide(site, commandId) : shortCompletionLine(site, commandId);
|
|
1000
|
+
const full = `${body}\n\n${guide}` +
|
|
1001
|
+
// アンカー(管理用ジョブ印)は必ず本文の最後に置く。完了検出の境界として使う。
|
|
1002
|
+
`(管理用ジョブ印・変更不要: ${anchor})`;
|
|
1003
|
+
// 改行(と連続改行)を空白1個に潰し、前後を整える。
|
|
1004
|
+
return full.replace(/\r?\n+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
1005
|
+
}
|
|
1006
|
+
/** 鉄則(conductor-craftsman の SKILL.md)の中の、便の終え方の見出し。1行の案内はここを指す。 */
|
|
1007
|
+
export const CRAFTSMAN_FINISH_HEADING = '## 便の終え方';
|
|
1008
|
+
/**
|
|
1009
|
+
* Claude の職人へ付ける「便の終え方」の1行(便 a5306df2・えふさん確定の重複削減)。
|
|
1010
|
+
*
|
|
1011
|
+
* 【なぜ短くしたか】以前は下の全文(約1,500字)を便ごとに毎回付けていた(棚卸し 8ceae57d)。
|
|
1012
|
+
* 書き方の説明は毎便同じなので、正本を鉄則の「便の終え方」の節へ寄せ、便には1行だけ残す。
|
|
1013
|
+
* 【★この1行だけは何があっても残す物】便ごとに変わる3つ=報告の置き場・最終行の合図・完了の知らせの
|
|
1014
|
+
* 指示ID。鉄則がまだ古い機体や、鉄則を読み込めなかった職人でも、この3つがあれば回収は途切れない。
|
|
1015
|
+
* 【★報告の置き場は1か所】置き場は配達役がこの機で決めた正本(reportWriteDir)だけを書く。
|
|
1016
|
+
* 鉄則には「便の本文に別の置き場が書かれていても、この行の置き場を正とする」と書いてある
|
|
1017
|
+
* (便 46205e8e で配達役=~/.local/state・CC1=/tmp の食い違いが実際に起きた)。
|
|
1018
|
+
*/
|
|
1019
|
+
export function shortCompletionLine(site, commandId) {
|
|
1020
|
+
const reportPath = path.join(reportWriteDir(), reportFileName(commandId));
|
|
1021
|
+
return (`【便の終え方】鉄則(conductor-craftsman)の「便の終え方」のとおりに終える。` +
|
|
1022
|
+
`報告の置き場: ${reportPath}(先頭に6欄の囲み)/最終行: DONE:${site} とだけ出力/` +
|
|
1023
|
+
`完了の知らせ: conductor_complete を commandId="${commandId}" で1回だけ(nextWork は必ず書く)。`);
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* 全文の完了案内(★Codex の職人向け・Claude 向けは shortCompletionLine)。
|
|
1027
|
+
* ★ここに書いてある決まりは、鉄則の「便の終え方」の節と中身を同じに保つ
|
|
1028
|
+
* (試験 relay-finish-guide-equivalence が1つずつ突き合わせる)。
|
|
1029
|
+
*/
|
|
1030
|
+
export function fullCompletionGuide(site, commandId) {
|
|
1031
|
+
const marker = `DONE:${site}`;
|
|
1032
|
+
return (
|
|
1033
|
+
// ★確認カードを非エンジニアが読める日本語にする(調査 2987cb8f)。
|
|
1034
|
+
// Bash 等の確認に出る一言説明は、職人(モデル)が tool_input.description に自分で書く自由記入欄で、
|
|
1035
|
+
// Claude Code 組込みの記入例が英語のため既定では英語になる。ここで日本語を依頼しておく。
|
|
1036
|
+
// ★段3の撤去後、この説明の行き先は2つ:
|
|
1037
|
+
// (1) 職人の端末に出る確認ダイアログ(人がその場で読む)
|
|
1038
|
+
// (2) PermissionRequest フックが管制へ渡す toolInput の中身(カードの「くわしく」に残る)
|
|
1039
|
+
// =以前のように relay が画面から拾って中央のカード見出しにする経路(extractPermSummary →
|
|
1040
|
+
// summary)は無い。カードの日本語見出しは summary_ja.py がコマンドから組み立てる。
|
|
1041
|
+
// ★あくまで書き方の依頼。従わなくても英語の説明が入るだけで、見出しは summary_ja.py が
|
|
1042
|
+
// 日本語で作る=壊れない。
|
|
1043
|
+
`作業中にユーザー確認(許可を求めるプロンプト)が出る操作では、その一言説明(description)を` +
|
|
1008
1044
|
`英語ではなく日本語で、「プルリクエストを作成する」「テストを実行する」のように` +
|
|
1009
1045
|
`「何をするか」が一目で分かる簡潔な形(〜を作成する/実行する/削除する 等)で書いてください` +
|
|
1010
1046
|
`(この説明は管制の確認カードにそのまま表示され、非エンジニアのお客さまが読んで許可を判断します)。\n\n` +
|
|
@@ -1041,11 +1077,9 @@ export function buildSendText(body, site, anchor) {
|
|
|
1041
1077
|
`prNumber=既にPRがある場合のみ、outcome=pushed(変更してpushした)/no_change(変更不要だった)/` +
|
|
1042
1078
|
`blocked(衝突・要判断・許可待ち等で完了できなかった)のいずれか。blockedのときも必ず conductor_complete を呼び` +
|
|
1043
1079
|
`reportに理由を書いてください。ブランチを切らない読み取り専用の作業では outcome=no_change を渡してください` +
|
|
1044
|
-
`(branch
|
|
1045
|
-
//
|
|
1046
|
-
|
|
1047
|
-
// 改行(と連続改行)を空白1個に潰し、前後を整える。
|
|
1048
|
-
return full.replace(/\r?\n+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
1080
|
+
`(branchは省略可)。` +
|
|
1081
|
+
// ★nextWork(次の独立作業候補)は必ず書く(conductor_complete の説明と同じ・便 a5306df2 で両方にそろえた)。
|
|
1082
|
+
`nextWork(次の独立作業候補)は必ず書いてください(無ければ「なし」と理由)。\n\n`);
|
|
1049
1083
|
}
|
|
1050
1084
|
// ───────────────────────────────────────────────────────────────────────────
|
|
1051
1085
|
// tmux I/O(失敗は握りつぶして null/false。送らない側に倒すため)
|
|
@@ -2462,7 +2496,7 @@ export async function relayTick(cfg, state, hooks) {
|
|
|
2462
2496
|
// 画面にエコーされたアンカー行を「今回ジョブの境界」として記録し、完了検出は
|
|
2463
2497
|
// アンカーより下=今回ジョブの出力だけを見る(churn・過去ジョブ DONE に強い)。
|
|
2464
2498
|
const anchor = buildAnchor(cmd.id);
|
|
2465
|
-
const text = buildSendText(cmd.body, cfg.site, anchor);
|
|
2499
|
+
const text = buildSendText(cmd.body, cfg.site, anchor, kindOf(cfg));
|
|
2466
2500
|
if (!sendToTmux(cfg.site, text)) {
|
|
2467
2501
|
// 送信失敗(sendToTmux は内部で例外も握って false を返す)。status は queued のまま据え置く。
|
|
2468
2502
|
// 失敗の理由(tmux の stderr)は sendToTmux が直前の行に出している。
|
package/package.json
CHANGED
|
@@ -68,3 +68,29 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
68
68
|
- **なぜ。** 雛形(`.env.example`)は普通は秘密値を置かないが、「exampleだから常に安全」と番人へ例外を作ると、将来誤って実値が書かれたときの穴になる(利便性より安全側・えふさん確定)。
|
|
69
69
|
- **雛形(`.env.example` など)を直すときの正しい形=「案を作る→人が1回で反映」。** 職人は変更後の中身を**リポジトリの外(`/tmp/claude-1000/` の下)**に作り、報告に次の2つを載せる。① 変更の**差分**(何を足す/消すか)。② 人が**素のターミナルで1回貼るだけで反映できる1つのコマンド**(例:`cp /tmp/claude-1000/<下書き> <リポ>/.env.example`)。★このコマンドは**人が自分のターミナルで**打つ(職人の番人は人の端末には掛からない)。職人が `.env.example` を直接書き換えようとしても番人が止めるので、**回避せず、この形で案を出す**。
|
|
70
70
|
- **本物の `.env`・`.env.local` は、これまでどおり中身も書き込みも扱わない**(秘密の値は1文字も読まない・書かない=鉄則12の金庫)。
|
|
71
|
+
|
|
72
|
+
## 便の終え方
|
|
73
|
+
|
|
74
|
+
便の最後には、配達役が付けた1行「【便の終え方】…報告の置き場: ~/最終行: DONE:<現場> とだけ出力/完了の知らせ: conductor_complete を commandId="<指示ID>" で1回だけ」と、管理用ジョブ印 `CONDUCTOR_JOB:<指示ID>` がある。作業がすべて終わったら、この節のとおりに次の順で終える(便 a5306df2:以前は便ごとに付いていた全文を、ここへ寄せた)。
|
|
75
|
+
|
|
76
|
+
① **報告をファイルに書く。** 置き場は配達役の1行が指すファイル**だけ**(正本は `~/.local/state/conductor/reports/<指示ID>.md`)。★便の本文に別の置き場(`/tmp` など)が書かれていても、**配達役の1行の置き場を正とする**(置き場は1か所)。フォルダが無ければ作る。長さの制限は無い。画面に出す必要は無い。中身は変更ファイル・要点・チェック結果を簡潔に。
|
|
77
|
+
② **ファイルの先頭(1行目から)に、次の囲みを付ける**(管制が機械で読む口)。
|
|
78
|
+
```
|
|
79
|
+
---
|
|
80
|
+
instruction_id: <指示ID>
|
|
81
|
+
site: <現場=DONE: の後ろと同じ名前>
|
|
82
|
+
outcome: pushed または no_change または blocked のどれか1つ
|
|
83
|
+
created_at: 書いた日時(例 2026-09-21T04:20:00+09:00)
|
|
84
|
+
evidence:
|
|
85
|
+
- 受入の証拠を1行に1つ(例 PR https://github.com/... / CI test pass / main に入った など)
|
|
86
|
+
---
|
|
87
|
+
```
|
|
88
|
+
この囲みの下に、いつもどおりの報告本文を書く(本文が空だと未完成と見なされる)。
|
|
89
|
+
③ **その後の最終行に、配達役の1行にある `DONE:<現場>` とだけ出力する**(完了の合図)。
|
|
90
|
+
④ **devlog の MCP ツール `conductor_complete` を、配達役の1行にある commandId で1回だけ呼ぶ**(relay に依存しない確実な完了通知)。report 引数に上の報告本文を添えてもよい。
|
|
91
|
+
- **nextWork(次の独立作業候補)は必ず書く。** 無ければ「なし」と、なぜ無いかの理由を書く。
|
|
92
|
+
- 可能なら次も一緒に渡す(すべて任意・分かる範囲でよく、渡さなくても完了する):`branch=`作った作業ブランチ名(`git rev-parse --abbrev-ref HEAD`)、`baseBranch=`分岐元(通常 main)、`headSha=`最後のコミット(短縮可)、`pushed=`push したか(true/false)、`filesChanged=`変更したファイル数、`prTitle=`お客さま(非エンジニア)がそのまま読む題名(rebase/squash/lint 等の専門用語を避け、やさしい日本語で)、`prNumber=`既に PR がある場合のみ、`outcome=`pushed(変更して push した)/no_change(変更不要だった)/blocked(衝突・要判断・許可待ち等で完了できなかった)のどれか。
|
|
93
|
+
- **blocked のときも必ず conductor_complete を呼び、report に理由を書く。**
|
|
94
|
+
- ブランチを切らない**読み取り専用の作業では outcome=no_change** を渡す(branch は省略可)。
|
|
95
|
+
|
|
96
|
+
**作業中の確認の一言説明** — 作業中にユーザー確認(許可を求めるプロンプト)が出る操作では、その一言説明(description)を英語ではなく日本語で、「プルリクエストを作成する」「テストを実行する」のように「何をするか」が一目で分かる簡潔な形(〜を作成する/実行する/削除する 等)で書く。この説明は管制の確認カードにそのまま表示され、非エンジニアのお客さまが読んで許可を判断する。
|