@tyhld/conductor 0.12.68 → 0.12.69

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyhld/conductor",
3
- "version": "0.12.68",
3
+ "version": "0.12.69",
4
4
  "description": "采配くん管制の見守りアプリ(conductor-agent)。各PCで常駐し、中央(devlog-tracker)へ定期的に生存報告(heartbeat)を送る常駐CLI。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -131,23 +131,43 @@ note() { printf ' %s\n' "$1"; }
131
131
  SUMMARY=()
132
132
  record() { SUMMARY+=("$1"); }
133
133
 
134
+ # ─── 端末への出力 ──────────────────────────────────────────────────────────
135
+ # 【なぜ /dev/tty へ書くか(実機 2026-10-01・後藤さん PC)】
136
+ # `curl … | bash` を Windows Terminal + WSL で流すと、標準エラー(>&2)に書いた文が
137
+ # 画面に出ない(halt の案内・ask_tty の質問文・die の案内が見えず、合言葉が漏えいした)。
138
+ # 標準出力と sudo(端末へ直接書く)は見えていた。
139
+ # =お客さまが読む必要のある文は /dev/tty(端末そのもの)へ書く。
140
+ #
141
+ # 【検査での差し替え口(CONDUCTOR_INSTALL_TTY_OUT)】
142
+ # 既定は /dev/tty。検査ではふつうのファイルに向け、書かれた内容を確かめる。
143
+ # 入力の差し替え口(CONDUCTOR_INSTALL_TTY)とは別。同じファイルに向けると入力を壊す。
144
+ # ─────────────────────────────────────────────────────────────────────────────
145
+ INSTALL_TTY_OUT="${CONDUCTOR_INSTALL_TTY_OUT:-/dev/tty}"
146
+ # ★`exec 4>... 2>/dev/null` と書くと exec が stderr も /dev/null に永続的に向けてしまう。
147
+ # 先に書けるかを調べ(サブシェルで試す)、開けるときだけ exec する。
148
+ if (exec 3>"$INSTALL_TTY_OUT") 2>/dev/null; then
149
+ exec 4>"$INSTALL_TTY_OUT"
150
+ else
151
+ exec 4>&2 # 端末が開けなければ標準エラーへ落とす
152
+ fi
153
+
134
154
  # 直せないので止まる(お客さまの手番)。★必ず「何をして、次にどうするか」を書く。
135
155
  halt() {
136
- printf '\n%s\n' "$BAR" >&2
137
- printf 'ここでいったん止まります(あと1つ、お手数をおかけします)\n' >&2
138
- printf '%s\n\n' "$BAR" >&2
139
- printf '%s\n' "$1" >&2
140
- printf '\n%s\n' "$BAR" >&2
141
- printf 'この作業が終わったら、さきほどの1行をもう一度そのまま打ってください。\n' >&2
142
- printf '済んだところは飛ばして、続きから進みます。\n' >&2
143
- printf '%s\n' "$BAR" >&2
156
+ printf '\n%s\n' "$BAR" >&4
157
+ printf 'ここでいったん止まります(あと1つ、お手数をおかけします)\n' >&4
158
+ printf '%s\n\n' "$BAR" >&4
159
+ printf '%s\n' "$1" >&4
160
+ printf '\n%s\n' "$BAR" >&4
161
+ printf 'この作業が終わったら、さきほどの1行をもう一度そのまま打ってください。\n' >&4
162
+ printf '済んだところは飛ばして、続きから進みます。\n' >&4
163
+ printf '%s\n' "$BAR" >&4
144
164
  exit 1
145
165
  }
146
166
 
147
167
  # 想定していない壊れ方(お客さまには直せないので、そのまま送ってもらう)。
148
168
  die() {
149
- printf '\n[install] うまくいきませんでした: %s\n' "$1" >&2
150
- printf '[install] この画面をそのままサポートへお送りください。\n' >&2
169
+ printf '\n[install] うまくいきませんでした: %s\n' "$1" >&4
170
+ printf '[install] この画面をそのままサポートへお送りください。\n' >&4
151
171
  exit 1
152
172
  }
153
173
 
@@ -168,10 +188,10 @@ die() {
168
188
  # 止まった(CI は端末が無いので気づけなかった=すり抜けた)。
169
189
  # ★入力元を差し替えられるようにするだけ。段・判定・止まり方は1つも変えない。
170
190
  #
171
- # 【聞く文は標準エラーへ出す】
172
- # 以前は /dev/tty へ直接書いていたが、入力元を差し替えるとそこが読み取り用の
173
- # ファイルになる(同じファイルへ書くと入力を壊す)。聞く文は標準エラーへ出す。
174
- # `curl … | bash` でも sudo のパスワード入力と同じくちゃんと画面に見える。
191
+ # 【聞く文は端末(fd 4)へ出す】
192
+ # 以前は標準エラー(>&2)へ出していたが、`curl … | bash` を Windows Terminal + WSL で
193
+ # 流すと標準エラーが画面に出ない(実機 2026-10-01・後藤さん PC)。
194
+ # 端末(/dev/tty・検査時は CONDUCTOR_INSTALL_TTY_OUT)へ書く。
175
195
  # >>> tty-io >>> ★この印の間はテストが切り出して単体で流す。動かすときは消さない。
176
196
  # ═════════════════════════════════════════════════════════════════════════════
177
197
 
@@ -184,10 +204,10 @@ tty_open() {
184
204
  return 0
185
205
  fi
186
206
  if ! exec 3<"$INSTALL_TTY" 2>/dev/null; then
187
- printf '\n[install] ここから先は、お客さまに入力していただく必要があります。\n' >&2
188
- printf '[install] ★いまの実行には「入力できる画面(端末)」がありません。\n' >&2
189
- printf '[install] 自動実行や、画面のない環境からは進められません。\n' >&2
190
- printf '[install] Ubuntu(WSL)の画面をご自分で開いて、そこで1行を打ち直してください。\n' >&2
207
+ printf '\n[install] ここから先は、お客さまに入力していただく必要があります。\n' >&4
208
+ printf '[install] ★いまの実行には「入力できる画面(端末)」がありません。\n' >&4
209
+ printf '[install] 自動実行や、画面のない環境からは進められません。\n' >&4
210
+ printf '[install] Ubuntu(WSL)の画面をご自分で開いて、そこで1行を打ち直してください。\n' >&4
191
211
  exit 1
192
212
  fi
193
213
  TTY_READY=1
@@ -198,11 +218,11 @@ ask_tty() {
198
218
  local var="$1" prompt="$2" default="${3:-}" answer=''
199
219
  tty_open
200
220
  if [[ -n "$default" ]]; then
201
- printf '%s\n' "$prompt" >&2
202
- printf ' (そのままで良ければ Enter → %s): ' "$default" >&2
221
+ printf '%s\n' "$prompt" >&4
222
+ printf ' (そのままで良ければ Enter → %s): ' "$default" >&4
203
223
  else
204
- printf '%s\n' "$prompt" >&2
205
- printf ' : ' >&2
224
+ printf '%s\n' "$prompt" >&4
225
+ printf ' : ' >&4
206
226
  fi
207
227
  IFS= read -r -u 3 answer || answer=''
208
228
  if [[ -z "$answer" ]]; then
@@ -215,10 +235,10 @@ ask_tty() {
215
235
  ask_tty_secret() {
216
236
  local var="$1" prompt="$2" answer=''
217
237
  tty_open
218
- printf '%s\n' "$prompt" >&2
219
- printf ' (入力しても画面には出ません): ' >&2
238
+ printf '%s\n' "$prompt" >&4
239
+ printf ' (入力しても画面には出ません): ' >&4
220
240
  IFS= read -r -s -u 3 answer || answer=''
221
- printf '\n' >&2
241
+ printf '\n' >&4
222
242
  printf -v "$var" '%s' "$answer"
223
243
  }
224
244
  # <<< tty-io <<<
@@ -988,9 +1008,11 @@ else
988
1008
 
989
1009
  ask_tty CONSOLE_URL ' ① 管制のアドレス' "$DEFAULT_CONSOLE_URL"
990
1010
  [[ -n "$CONSOLE_URL" ]] || halt '管制のアドレスが空でした。もう一度この1行を打ってやり直してください。'
1011
+ # ★合言葉をアドレス欄に入れてしまった場合の防止(実機 2026-10-01: 合言葉が画面に表示されて漏えい)。
1012
+ # 入力値は画面にもログにも出さない(合言葉そのものの可能性があるため)。
991
1013
  case "$CONSOLE_URL" in
992
1014
  https://*) : ;;
993
- *) halt "管制のアドレスは https:// から始まります(入力: ${CONSOLE_URL})。案内をご確認のうえ、もう一度この1行を打ってください。" ;;
1015
+ *) CONSOLE_URL=''; halt 'https:// で始まっていません。合言葉はまだ入れないでください。次の欄(②)が合言葉です。もう一度この1行を打ってやり直してください。' ;;
994
1016
  esac
995
1017
 
996
1018
  ask_tty_secret CONSOLE_TOKEN ' ② 合言葉'
@@ -1112,7 +1134,8 @@ if [[ "$DRY_RUN" == "1" ]]; then
1112
1134
  else
1113
1135
  doing '采配くんを設置します(ここから先は設置係が引き継ぎます)'
1114
1136
  say ''
1115
- conductor setup "$SITE" || die '設置に失敗しました(上に出ている内容をサポートへお送りください)'
1137
+ # ★画面なし方式であることを設置係へ伝える(⑧の案内を切り替えるため)。
1138
+ CONDUCTOR_RUNNER_MODE=headless conductor setup "$SITE" || die '設置に失敗しました(上に出ている内容をサポートへお送りください)'
1116
1139
  record '設置: 実行した'
1117
1140
  fi
1118
1141
 
@@ -105,8 +105,21 @@ PROJECT_DIR="${2:-$HOME/projects/$SITE}"
105
105
  MIN_CONDUCTOR_VERSION="0.12.3"
106
106
 
107
107
  # ─── ヘルパ ───────────────────────────────────────────────────────────────────
108
- fail() { echo; echo "[setup] エラー: $1" >&2; exit 1; }
109
- warn() { echo "[setup] warn: $1" >&2; }
108
+
109
+ # ─── 端末への出力(install.sh と同じ仕組み) ─────────────────────────────────
110
+ # 【なぜ /dev/tty へ書くか】`curl … | bash` を Windows Terminal + WSL で流すと、
111
+ # 標準エラー(>&2)に書いた文が画面に出ない(実機 2026-10-01)。
112
+ # お客さまが読む文は端末そのもの(/dev/tty)へ書く。
113
+ _SETUP_TTY_OUT="${CONDUCTOR_INSTALL_TTY_OUT:-/dev/tty}"
114
+ # ★`exec 9>... 2>/dev/null` と書くと exec が stderr も /dev/null に永続的に向けてしまう。
115
+ if (exec 3>"$_SETUP_TTY_OUT") 2>/dev/null; then
116
+ exec 9>"$_SETUP_TTY_OUT"
117
+ else
118
+ exec 9>&2 # 端末が開けなければ標準エラーへ落とす
119
+ fi
120
+
121
+ fail() { echo >&9; echo "[setup] エラー: $1" >&9; exit 1; }
122
+ warn() { echo "[setup] warn: $1" >&9; }
110
123
 
111
124
  # 入力元。curl | bash では /dev/tty から読む。テスト等で端末が無い場合は標準入力に落ちる。
112
125
  # install.sh の CONDUCTOR_INSTALL_TTY と同じ差し替え口を使う。
@@ -121,15 +134,18 @@ fi
121
134
 
122
135
  # setup_read — /dev/tty があれば使い、無ければ標準入力から読む。
123
136
  # 使い方: setup_read [-s] <変数名> <プロンプト>
137
+ # ★プロンプト(聞く文)は端末(fd 9)へ出す。`read -p` は stderr に書くが、
138
+ # Windows Terminal + WSL では見えないので、先に fd 9 へ書いてから `-p ''` で読む。
124
139
  setup_read() {
125
140
  local silent='' var prompt
126
141
  if [[ "${1:-}" == "-s" ]]; then silent='-s'; shift; fi
127
142
  var="$1"; prompt="$2"
143
+ printf '%s' "$prompt" >&9
128
144
  # shellcheck disable=SC2229 # $silent は動的な旗、$var は動的な変数名。意図どおり。
129
145
  if [[ "$_SETUP_TTY_OK" == "1" ]]; then
130
- IFS= read -r $silent -p "$prompt" "$var" <"$_SETUP_TTY" || printf -v "$var" ''
146
+ IFS= read -r $silent "$var" <"$_SETUP_TTY" || printf -v "$var" ''
131
147
  else
132
- IFS= read -r $silent -p "$prompt" "$var" || printf -v "$var" ''
148
+ IFS= read -r $silent "$var" || printf -v "$var" ''
133
149
  fi
134
150
  }
135
151
 
@@ -378,9 +394,9 @@ fi
378
394
 
379
395
  if [[ ${#errors[@]} -gt 0 ]]; then
380
396
  echo
381
- echo "[setup] 前提チェックに失敗しました:" >&2
397
+ echo "[setup] 前提チェックに失敗しました:" >&9
382
398
  for e in "${errors[@]}"; do
383
- echo " - $e" >&2
399
+ echo " - $e" >&9
384
400
  done
385
401
  exit 1
386
402
  fi
@@ -1181,7 +1197,47 @@ fi
1181
1197
 
1182
1198
  step "⑧ 完了! 職人(Claude Code)の起動方法"
1183
1199
 
1184
- cat <<GUIDE
1200
+ if [[ "${CONDUCTOR_RUNNER_MODE:-}" == "headless" ]]; then
1201
+ # ★画面なし方式(install.sh から呼ばれた場合)。tmux の3行は出さない。
1202
+ cat <<GUIDE
1203
+
1204
+ 采配くんのセットアップが完了しました。
1205
+
1206
+ 管制から便を出すと自動で動きます。
1207
+ 職人の画面を手で開く必要はありません。
1208
+
1209
+ ──────────────────────────────────────────────────────────
1210
+ ★いちばん確実な「動いています」の確かめ方
1211
+ ──────────────────────────────────────────────────────────
1212
+
1213
+ 管制の画面(采配くん)をブラウザで開いてください。
1214
+ そこに「${SITE}」が出ていれば、つながって動いています。★これが正の確認方法です。
1215
+
1216
+ 出てこないときは、次の順に試してください。
1217
+ 1. 1〜2分待ってから、管制の画面を開き直す
1218
+ 2. それでも出ないときは: ${SVC_RESTART_CMD}
1219
+ 3. それでも出ないときは、この画面をそのままサポートへお送りください
1220
+
1221
+ ──────────────────────────────────────────────────────────
1222
+ 困ったとき(黒い画面のコマンド・補助)
1223
+ ──────────────────────────────────────────────────────────
1224
+ 状態を見る: ${SVC_STATUS_CMD}
1225
+ 動きの記録: ${SVC_LOG_CMD}
1226
+ 入れ直す: ${SVC_RESTART_CMD}
1227
+ 止める: ${SVC_STOP_CMD}
1228
+ 合言葉を入れ直す: rm ~/.conductor.env → そのあと setup.sh をもう一度実行
1229
+
1230
+ ──────────────────────────────────────────────────────────
1231
+ 職人の画面を手で開きたいとき(tmux 方式・補助)
1232
+ ──────────────────────────────────────────────────────────
1233
+
1234
+ tmux new-session -d -s "$SITE" -c "$PROJECT_DIR"
1235
+ tmux send-keys -t "$SITE" "unset ANTHROPIC_API_KEY && claude" C-m
1236
+ tmux attach -t "$SITE"
1237
+
1238
+ GUIDE
1239
+ else
1240
+ cat <<GUIDE
1185
1241
 
1186
1242
  采配くんのセットアップが完了しました。
1187
1243
 
@@ -1219,3 +1275,4 @@ cat <<GUIDE
1219
1275
  合言葉を入れ直す: rm ~/.conductor.env → そのあと setup.sh をもう一度実行
1220
1276
 
1221
1277
  GUIDE
1278
+ fi