@tyhld/conductor 0.3.0 → 0.6.0
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/README.md +301 -19
- package/dist/cli.js +143 -18
- package/dist/ear-routing.js +57 -0
- package/dist/ear.js +57 -0
- package/dist/env-file-perm.js +67 -0
- package/dist/nudge.js +172 -0
- package/dist/realtime-parse.js +116 -0
- package/dist/realtime.js +251 -0
- package/dist/relay-runner.js +65 -0
- package/dist/relay.js +832 -133
- package/dist/websocket-transport.js +66 -0
- package/launchd/ear-install.sh +96 -0
- package/package.json +30 -1
- package/sales-template/README.md +185 -25
- package/sales-template/install.sh +890 -0
- package/sales-template/launchd/install.sh +151 -0
- package/sales-template/settings.json +26 -97
- package/sales-template/setup.sh +754 -117
- package/sales-template/systemd/README.md +28 -4
- package/sales-template/systemd/install.sh +54 -5
- package/sales-template/systemd/paste-cache-prune-install.sh +75 -0
- package/sales-template/systemd/tyhld-paste-cache-prune.service +25 -0
- package/sales-template/systemd/tyhld-paste-cache-prune.timer +19 -0
- package/sales-template/uninstall.sh +245 -0
- package/scripts/hooks/README.md +246 -0
- package/scripts/hooks/cc2_guard.py +145 -0
- package/scripts/hooks/codex-hooks.sample.json +58 -0
- package/scripts/hooks/hook_datalink.py +440 -0
- package/scripts/hooks/install-codex-hooks.sh +127 -0
- package/scripts/hooks/notification_hook.py +167 -0
- package/scripts/hooks/permission_request_hook.py +207 -0
- package/scripts/hooks/policy.py +759 -0
- package/scripts/hooks/settings.sample.json +142 -0
- package/scripts/hooks/stop_hook.py +275 -0
- package/scripts/hooks/summary_ja.py +155 -0
- package/scripts/hooks/test_hook_datalink.py +282 -0
- package/scripts/hooks/test_policy.py +1241 -0
- package/skills/conductor-craftsman/SKILL.md +40 -0
- package/systemd/conductor-ear.service +63 -0
- package/systemd/conductor@.service +62 -0
- package/systemd/ear-install.sh +131 -0
- package/systemd/guard-sync-install.sh +94 -0
- package/systemd/tyhld-guard-sync.service +28 -0
- package/systemd/tyhld-guard-sync.timer +25 -0
- package/sales-template/cc2_guard.py +0 -395
- package/sales-template/systemd/conductor@.service +0 -47
package/README.md
CHANGED
|
@@ -59,17 +59,17 @@ npm run build
|
|
|
59
59
|
| 環境変数 | 値 | 備考 |
|
|
60
60
|
|----------|----|------|
|
|
61
61
|
| `CONDUCTOR_URL` | `https://<your-conductor-host>`(中央) | 接続先 |
|
|
62
|
-
| `
|
|
62
|
+
| `CONDUCTOR_TOKEN` | **Bitwarden から取得** | テナントトークン。値はここに書きません |
|
|
63
63
|
| `CONDUCTOR_MACHINE` | 任意 | PC識別名。未設定なら `os.hostname()` |
|
|
64
64
|
|
|
65
|
-
> 🔑 **鍵(`
|
|
65
|
+
> 🔑 **鍵(`CONDUCTOR_TOKEN`)は Bitwarden の共有項目から取得してください。**
|
|
66
66
|
> コード・リポジトリ・この README には値を一切書きません。
|
|
67
67
|
|
|
68
68
|
設定して起動する例:
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
export CONDUCTOR_URL=https://<your-conductor-host>
|
|
72
|
-
read -s -p '
|
|
72
|
+
read -s -p 'tenant token: ' CONDUCTOR_TOKEN && export CONDUCTOR_TOKEN
|
|
73
73
|
node dist/cli.js start # もしくは scripts/conductor-start.sh(後述)
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -77,13 +77,44 @@ node dist/cli.js start # もしくは scripts/conductor-start.sh(
|
|
|
77
77
|
|
|
78
78
|
---
|
|
79
79
|
|
|
80
|
+
## 新PCの初回セットアップ(ブラウザ検品の道具)★人が1回だけ流す
|
|
81
|
+
|
|
82
|
+
職人(Claude Code)がブラウザ検品(Playwright)を行うPCでは、**最初に1回だけ**この2本を流してください。
|
|
83
|
+
流していないPCでは、職人が検品のたびに端末へ「サンドボックス外通信の許可(Host: `cdn.playwright.dev`)」を出して止まります。
|
|
84
|
+
この問いは番人を通らないため**管制のカードに出せず、端末でしか押せません**(→ 便が人待ちになる。経緯は [ADR-010](docs/adr/ADR-010-playwright-shared-browser.md))。
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# A) 共有ブラウザ … PCに1回だけ Chromium と playwright を入れる(職人は毎便ダウンロードしなくなる)
|
|
88
|
+
bash scripts/pw-browser-install.sh # まず予定を表示(書き込みなし)
|
|
89
|
+
APPLY=1 bash scripts/pw-browser-install.sh # 実際に入れる
|
|
90
|
+
|
|
91
|
+
# B) 通信許可(保険) … それでも取得が要るときのため、各現場へ許可ドメインを配る
|
|
92
|
+
bash scripts/update-allowed-domains.sh # まず予定を表示(書き込みなし)
|
|
93
|
+
APPLY=1 bash scripts/update-allowed-domains.sh # 実際に配る
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **A は何を置くか**: `$HOME/.tyhld/pw-venv`(版を固定した playwright)と `$HOME/.tyhld/pw-browsers`(Chromium の実体)。
|
|
97
|
+
番人の `$HOME/.tyhld/hooks` と同じ「1台に1箇所」の流儀です。入れた後に**実行ファイルの実在・サンドボックス内から読めるか・実際に起動するか**を実測して表示します。
|
|
98
|
+
- **職人は自分で入れません**。`$HOME/.tyhld` はサンドボックスの中から**読めるが書けない**ので、道具が無ければ職人はそこで止まり「人の手番」と報告します(鉄則8)。
|
|
99
|
+
- **B は他を触りません**。`sandbox.network.allowedDomains` に不足分を追記するだけで、`permissions`(deny/ask/allow)・`hooks` は1文字も変えません。
|
|
100
|
+
`scripts/update-guard.sh`(全部入り)を流す場合は同じ一覧が同時に配られるので、B は不要です。
|
|
101
|
+
- **★2026-09-03(甲)以降、外への通信は全部通します**(`allowedDomains: ["*"]`)。この問いは管制の3ボタンでは押せないと実測で確定したため(Claude Code 2.1.258 本体の作り)、聞かれる前に通して職人を自走させます。
|
|
102
|
+
- **配るのは `APPLY=1 bash scripts/update-guard.sh`** です(`①-e3` がホームの `~/.claude/settings.json` へ1か所だけ配る)。B は `sandbox` を持つ現場しか対象にしないので、B だけでは届かない現場があります。
|
|
103
|
+
- **緩むのは「電話をかける」だけ**です。秘密の持ち出し(`.env` / `~/.ssh` / `$DATABASE_URL` など)を止める番人は**別の仕組み**で、1ミリも緩みません。本番DBへの直結禁止(`deniedDomains`)も `"*"` より先に効くため、そのまま閉じたままです。
|
|
104
|
+
- **鉄則(職人の作業規律)を直したときは `APPLY=1 bash scripts/update-guard.sh` を流してください。**
|
|
105
|
+
稼働中の機体では `~/.claude/skills/conductor-craftsman/SKILL.md` が古い写しのまま残るため、
|
|
106
|
+
これを流さないと職人の動きは変わりません(`update-guard.sh ①-d`。同一なら何もしません)。
|
|
107
|
+
- **`setup.sh` からは呼びません**。顧客機の初期設置に大きなダウンロードを足すと設置そのものが止まるためです(ADR-010)。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
80
111
|
## 使い方
|
|
81
112
|
|
|
82
113
|
最低限、次の2つの環境変数を渡して `conductor start` を実行します。
|
|
83
114
|
|
|
84
115
|
```bash
|
|
85
116
|
CONDUCTOR_URL=https://<your-conductor-host> \
|
|
86
|
-
|
|
117
|
+
CONDUCTOR_TOKEN=(テナントトークン) \
|
|
87
118
|
conductor start
|
|
88
119
|
```
|
|
89
120
|
|
|
@@ -123,17 +154,217 @@ conductor start -a "ログイン画面を実装中"
|
|
|
123
154
|
| 環境変数 | 必須 | 意味 | 既定値 |
|
|
124
155
|
|----------|------|------|--------|
|
|
125
156
|
| `CONDUCTOR_URL` | ✅ | 中央(devlog-tracker)のベースURL。例: `https://<your-conductor-host>` | (なし) |
|
|
126
|
-
| `
|
|
157
|
+
| `CONDUCTOR_TOKEN` | ✅ | テナントトークン。中央API側の同名 env と一致させます | (なし) |
|
|
127
158
|
| `CONDUCTOR_MACHINE` | – | PCの識別名 | `os.hostname()`(PCのホスト名) |
|
|
128
159
|
| `CONDUCTOR_INTERVAL_SEC` | – | heartbeat送信間隔(秒) | `30` |
|
|
129
160
|
| `CONDUCTOR_RELAY_ENABLED` | – | `true` で relay(指示の取得→アイドル時のみ tmux 送信→完了検出)を有効化 | `false` |
|
|
130
161
|
| `CONDUCTOR_RELAY_INTERVAL_SEC` | – | relay のポーリング間隔(秒) | `15` |
|
|
162
|
+
| `CONDUCTOR_NUDGE_DIR` | – | 耳 → relay の呼び鈴(空ファイル)の置き場 | `$XDG_RUNTIME_DIR/conductor` |
|
|
131
163
|
|
|
132
164
|
> **relay(ADR-029 段階3 / 既定 off)**:`CONDUCTOR_RELAY_ENABLED=true` のときだけ、
|
|
133
165
|
> 中央から自分宛(machine+site)の指示を取得し、**送信先のtmuxセッション(名前 = 現場名 site)が
|
|
134
166
|
> 完全にアイドルのときだけ** 指示を流し込みます。少しでも作業中っぽければ送らず次回に再挑戦する
|
|
135
167
|
> 保守的な判定(「誤爆より送り遅れ」)です。off の間は従来どおり heartbeat のみで挙動は変わりません。
|
|
136
168
|
|
|
169
|
+
> **指示の着信合図(ADR-066)**:relay 有効時は、上のポーリングに加えて、耳(下記)から届く
|
|
170
|
+
> 「今すぐ1周して」の呼び鈴でも動きます。指示が積まれてから職人へ届くまでの最大15秒の待ちが消えます。
|
|
171
|
+
> 呼び鈴は空ファイルの touch で、**指示本文もトークンも載りません**。指示の中身は従来どおり
|
|
172
|
+
> 既存の取得APIから取り直します。耳が動いていなくても、relay は上記の間隔のポーリングで
|
|
173
|
+
> **これまでどおり完全に動きます**(耳は加速装置であって依存先ではありません)。
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 耳(conductor ear)— このPCに1本の合図受け取り役
|
|
178
|
+
|
|
179
|
+
`conductor ear` は、中央からの「指示が積まれた」合図(Supabase Realtime)を **PCにつき1本** の接続で
|
|
180
|
+
受け取り、その現場の relay(`conductor@<現場>`)へ「今すぐ1周して」とだけ伝える常駐です。
|
|
181
|
+
接続本数がソフト数ではなく **PC数** で決まる形にするための集約役です(ADR-066 便2c)。
|
|
182
|
+
|
|
183
|
+
| | conductor@<現場> | conductor-ear |
|
|
184
|
+
|---|---|---|
|
|
185
|
+
| 本数 | 現場ごとに1本 | **PCごとに1本** |
|
|
186
|
+
| 役目 | heartbeat + relay(指示の配達・完了検出) | 合図を受けて relay へ呼び鈴を送るだけ |
|
|
187
|
+
| 職人(tmux)への書き込み | する | **しない**(指示も取らない) |
|
|
188
|
+
|
|
189
|
+
- 耳 → relay の呼び鈴は、置き場(既定 `$XDG_RUNTIME_DIR/conductor`、`CONDUCTOR_NUDGE_DIR` で変更可)に
|
|
190
|
+
置かれた **空ファイル `<現場名>.nudge` を書き直すだけ**。relay は起動時に自分のファイルを作り
|
|
191
|
+
(=「この現場が動いている」の名簿にもなります)、フォルダを見張ります。
|
|
192
|
+
- このPCで動いていない現場宛ての合図は、渡さずログだけ残します。
|
|
193
|
+
- 接続先URL・公開鍵・購読設定は中央の `POST /api/conductor/realtime-token` の応答から受け取るため、
|
|
194
|
+
**追加の環境変数はありません**(必要なのは `CONDUCTOR_URL` / `CONDUCTOR_TOKEN` だけ)。
|
|
195
|
+
- 切断は自動で張り直し(5秒→10秒→…最大5分)、トークンは失効前に取り直します。
|
|
196
|
+
- **Node の版要件は上がりません(18以上のまま)**。合図の通信に使う WebSocket は、実行環境に標準品が
|
|
197
|
+
あればそれを、無ければ**同梱の `ws` を使います**(Node に標準の WebSocket が入ったのは 22 からで、
|
|
198
|
+
20 以下では `Node.js detected but native WebSocket not found.` で耳が張れませんでした)。
|
|
199
|
+
お客さま機の Node を上げていただく必要はありません。
|
|
200
|
+
- 中央にRealtimeが未設定・`@supabase/supabase-js` 未インストール・耳を止めている——いずれの場合も
|
|
201
|
+
**relay は15秒ポーリングでそのまま動きます**。
|
|
202
|
+
|
|
203
|
+
### 導入(ADR-066 便2e で自動化済み)
|
|
204
|
+
|
|
205
|
+
耳は**どちらの導入経路でも自動で入ります**。人が手でユニットを置く必要はありません。
|
|
206
|
+
|
|
207
|
+
| 機 | 入り方 |
|
|
208
|
+
|---|---|
|
|
209
|
+
| お客さま機 | `bash setup.sh <現場名>` の中で自動(⑥ systemd の段) |
|
|
210
|
+
| 自社機 | `bash scripts/systemd-install.sh` の中で自動 |
|
|
211
|
+
| 手動で入れ直す | `bash systemd/ear-install.sh` |
|
|
212
|
+
| 前面で試す | `bash scripts/ear-start.sh` |
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
systemctl --user status conductor-ear # 「合図の受け取りを開始しました」が出れば成功
|
|
216
|
+
journalctl --user -u conductor-ear -f # ログ
|
|
217
|
+
|
|
218
|
+
# やめる(relay は15秒ポーリングでそのまま動きます)
|
|
219
|
+
systemctl --user disable --now conductor-ear
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- ユニットの**正本は `systemd/conductor-ear.service` の1つだけ**。`ExecStart` は配置時に
|
|
223
|
+
`systemd/ear-install.sh` が「その機で実際に動くコマンド」へ置換します(お客さま機は npm の
|
|
224
|
+
`conductor`、自社機はリポジトリの `dist/cli.js`)。**そのままコピーしても動きません。**
|
|
225
|
+
- 耳が入らない機(systemd が無い・コマンドが見つからない等)でも、**セットアップは成功扱いで進みます**。
|
|
226
|
+
警告を残して先へ進み、relay は15秒ポーリングで従来どおり動きます。
|
|
227
|
+
|
|
228
|
+
> **台帳と掃除の順序(便2c の申し送り・便2e で解消)**:`setup.sh` の古いユニット掃除は
|
|
229
|
+
> 「台帳に載っている `@` 無しの `conductor-*.service`」を撤去します。`conductor-ear.service` は
|
|
230
|
+
> その綴りに当たるため、**掃除の例外(`CURRENT_MACHINE_UNITS`)に先に入れてから台帳へ載せて**います。
|
|
231
|
+
> 順序が崩れると「自分で入れた耳を次回セットアップで自分で消す」壊れ方をするので、
|
|
232
|
+
> `test/setup-ear-order.test.ts` が順序と振る舞いを固定しています。
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## CI(GitHub Actions)
|
|
237
|
+
|
|
238
|
+
`main` への push と、`main` を base とする pull request で `.github/workflows/ci.yml` が回ります。
|
|
239
|
+
ジョブは `test` の1本だけで、次を順に実行します(Node 22 / ubuntu-latest)。
|
|
240
|
+
|
|
241
|
+
| ステップ | コマンド | 見ているもの |
|
|
242
|
+
|----------|---------|-------------|
|
|
243
|
+
| Build | `npm run build` | TypeScript がコンパイルできるか(tsc) |
|
|
244
|
+
| Test | `npm test` | relay 等の単体テスト(`node --test`) |
|
|
245
|
+
| Hook test | `python3 scripts/hooks/test_policy.py` | 番人(policy.py / cc2_guard.py)の deny/allow/defer 判定 |
|
|
246
|
+
| Shell syntax | `bash -n`(scripts と sales-template の `*.sh`) | シェルスクリプトの構文エラー |
|
|
247
|
+
| Shell static analysis | `shellcheck -x --severity=warning`(同じ `*.sh`) | 未定義変数・クォート漏れ・空変数展開など `bash -n` が見ない欠陥 |
|
|
248
|
+
|
|
249
|
+
ローカルで同じチェックを回すには:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npm run build
|
|
253
|
+
npm test
|
|
254
|
+
python3 scripts/hooks/test_policy.py
|
|
255
|
+
for f in scripts/*.sh sales-template/*.sh sales-template/systemd/*.sh; do bash -n "$f"; done
|
|
256
|
+
shellcheck -x --severity=warning scripts/*.sh sales-template/*.sh sales-template/systemd/*.sh
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
> lint / format は `package.json` の scripts に未定義のため CI に載せていません。
|
|
260
|
+
> `shellcheck` はローカルには未導入です(CI の ubuntu-latest には標準搭載)。手元で回すなら `sudo apt install shellcheck` 等で入れてください。
|
|
261
|
+
|
|
262
|
+
### Node のバージョン要件(実行と開発で意図的に違う)
|
|
263
|
+
|
|
264
|
+
| 要件 | バージョン | どこで表明しているか |
|
|
265
|
+
|------|-----------|---------------------|
|
|
266
|
+
| **実行要件**(常駐を動かす) | **Node 18 以上** | `package.json` の `engines.node`、`sales-template/setup.sh` の前提チェック、上の「必要なもの」 |
|
|
267
|
+
| **開発・テスト要件**(`npm test` を回す) | **Node 22 以上** | `.nvmrc`(`22`)、CI の `node-version: 22` |
|
|
268
|
+
|
|
269
|
+
- 常駐(heartbeat / relay)が実行するのは `tsc` でコンパイル済みの `dist/cli.js` なので **Node 18 で動きます**。実際、この開発機の systemd は `/usr/bin/node` = v20.20.0 で稼働しています。
|
|
270
|
+
- Node 22 が要るのは `npm test` が `--experimental-strip-types` で `.ts` を**直接**実行するときだけです。
|
|
271
|
+
- **この2つを混同して `engines.node` に開発要件(22)を書いてはいけません。** Node 18/20 の環境で `npm i -g @tyhld/conductor` が `EBADENGINE` 警告を出し、`engine-strict=true` の環境では**実行できるのにインストールが拒まれます**。
|
|
272
|
+
- 開発時は `nvm use` / `fnm use` が `.nvmrc` を読んで 22 に切り替えます。
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 配布(リリース)★人が `npm publish` を打つ手順はありません
|
|
277
|
+
|
|
278
|
+
**配布先は公開 npm(`registry.npmjs.org`)1本です**(えふさん決定 2026-09-04)。
|
|
279
|
+
|
|
280
|
+
### やることは1つだけ
|
|
281
|
+
|
|
282
|
+
**`package.json` の `version` を上げて `main` に入れる。** それだけです。
|
|
283
|
+
`main` への push で `.github/workflows/release.yml` が走り、次のように動きます。
|
|
284
|
+
|
|
285
|
+
| 判定 | 動き |
|
|
286
|
+
|---|---|
|
|
287
|
+
| `version` が公開 npm の `latest` より**新しい** | build → テスト → `npm publish`(公開 npm へ) |
|
|
288
|
+
| 同じ・古い | **何もしない**(版を上げ忘れても事故りません) |
|
|
289
|
+
|
|
290
|
+
★**人が `npm publish` を打ってはいけません。**
|
|
291
|
+
|
|
292
|
+
<details><summary>なぜ手で打たないのか(実測 2026-09-04)</summary>
|
|
293
|
+
|
|
294
|
+
公開 npm には **0.3.0 しか出ておらず**、0.5.0 は **GitHub Packages(非公開)** に出ていました。
|
|
295
|
+
手元で `npm publish` を打つと、そのPCの `~/.npmrc` の `@tyhld` スコープ設定(GitHub Packages 向き)が効いてしまうためです。
|
|
296
|
+
|
|
297
|
+
その結果お客さまは公開 npm の 0.3.0 を掴みます。0.3.0 の中身は**古い鍵の名前**(`CONDUCTOR_SHARED_SECRET`)を読むので、いまの接続情報(`CONDUCTOR_TOKEN`)では「未設定です」で落ちます(migakia の設置で再現)。
|
|
298
|
+
|
|
299
|
+
**根治は「人のPCの設定に依存しない場所から出す」こと。** CI から出せば、誰のPCの `.npmrc` も関係なくなります。
|
|
300
|
+
あわせて `package.json` に `publishConfig`(`registry` = 公開 npm / `access` = public)を明記してあります。`publishConfig` は publish のときだけ効き、`.npmrc` のスコープ設定より優先されます。**取得側(他リポの `@tyhld/*` 部品)は一切変えていません。**
|
|
301
|
+
</details>
|
|
302
|
+
|
|
303
|
+
### どうやって名乗るか — Trusted Publishing(合言葉を持たない)
|
|
304
|
+
|
|
305
|
+
★**合言葉(トークン)は使いません。** GitHub が発行する**身分証(OIDC)**で名乗ります。
|
|
306
|
+
|
|
307
|
+
npm 側に「この org のこのリポジトリのこのワークフローなら出してよい」と**あらかじめ登録**しておき、実行のたびに GitHub が短命の身分証を出します。
|
|
308
|
+
|
|
309
|
+
| なぜトークンをやめたか |
|
|
310
|
+
|---|
|
|
311
|
+
| npm の書き込みトークンは**最長90日**で切れる。切れるたびに人が入れ替える運用は続きません |
|
|
312
|
+
| npm は**トークンでの直接公開を 2027-01 に廃止予定**(npm の画面に明記) |
|
|
313
|
+
| トークンを作らない・置かない・配らない = **漏れて困るものが存在しない** |
|
|
314
|
+
|
|
315
|
+
> ★**証明書(`--provenance`)は付けていません。** 証明書は**公開リポジトリからしか出せない**仕組みで、
|
|
316
|
+
> 非公開のこの conductor では `E422`(`Only public source repositories are supported when
|
|
317
|
+
> publishing with provenance`)で弾かれました(実測 2026-09-04・run 33785720505)。
|
|
318
|
+
> conductor は**非公開のまま**にするので、証明書のほうを外しています。
|
|
319
|
+
> **名乗り方(Trusted Publishing)はそのまま**で、認証はこれで通っています。
|
|
320
|
+
|
|
321
|
+
### 人の手番は1回だけ — npmjs に「出してよい相手」を登録する
|
|
322
|
+
|
|
323
|
+
<https://www.npmjs.com/package/@tyhld/conductor> → **Settings** → **Trusted publisher** → **GitHub Actions** で、次の**5項目**を入れて保存します。
|
|
324
|
+
|
|
325
|
+
| 入力欄 | 入れる値 |
|
|
326
|
+
|---|---|
|
|
327
|
+
| Publisher | **GitHub Actions** |
|
|
328
|
+
| Organization or user | `tyhld` |
|
|
329
|
+
| Repository | `conductor` |
|
|
330
|
+
| Workflow filename | **`release.yml`** |
|
|
331
|
+
| Environment name | **(空のまま)** |
|
|
332
|
+
|
|
333
|
+
> ★**Workflow filename は `release.yml`**(パスではなくファイル名だけ)。ここが違うと、
|
|
334
|
+
> npm は「知らないワークフローからの publish」として拒みます。
|
|
335
|
+
> Release はこの詰まり方を見分けて、上の表と同じ値を画面に出します。
|
|
336
|
+
|
|
337
|
+
> ★**`NPM_TOKEN` は使いません。** GitHub Secrets に入っていても参照しません。
|
|
338
|
+
> 「トークンでも出せる」道を残すと、どちらの経路で出たのか分からなくなるためです。
|
|
339
|
+
> (0.3.0 への `deprecate` だけは npm の画面から人が打ちます。下記)
|
|
340
|
+
|
|
341
|
+
<details><summary>初回の見届け方</summary>
|
|
342
|
+
|
|
343
|
+
1. `main` に入ったあと、**Actions → Release** の実行を開く
|
|
344
|
+
2. **「公開 npm へ出す(Trusted Publishing)」** が**緑**になっていること(`出しました。` が出ます)
|
|
345
|
+
3. <https://www.npmjs.com/package/@tyhld/conductor> を開き、**版が上がっていること**
|
|
346
|
+
|
|
347
|
+
黒い画面で確かめるなら、次の1行で `latest` が読めます。
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
curl -s https://registry.npmjs.org/@tyhld/conductor | jq -r '."dist-tags".latest'
|
|
351
|
+
```
|
|
352
|
+
</details>
|
|
353
|
+
|
|
354
|
+
### 古い版に「使わないで」の印を付ける(1回だけ・人の手番)
|
|
355
|
+
|
|
356
|
+
公開 npm に残っている 0.3.0 は動きません。次の1行で印を付けてください(`npm login` 済みの端末で)。
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
npm deprecate @tyhld/conductor@0.3.0 "古い版です。0.5.0 以上を使ってください"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
> 消す(`npm unpublish`)のではなく **deprecate**(印を付ける)にします。消すと、その版を掴んでいる機体の再インストールが失敗するためです。
|
|
363
|
+
|
|
364
|
+
### 最低版
|
|
365
|
+
|
|
366
|
+
`sales-template/install.sh` と `sales-template/setup.sh` は `MIN_CONDUCTOR_VERSION`(この2か所だけ・テストで同一を固定)より古い本体を見つけると、更新を試し、それでも古ければ**止まって案内**します。
|
|
367
|
+
|
|
137
368
|
---
|
|
138
369
|
|
|
139
370
|
## よくある質問
|
|
@@ -142,12 +373,55 @@ conductor start -a "ログイン画面を実装中"
|
|
|
142
373
|
A. 送りません。中央側は「最後の生存報告からの経過時間」でオフラインを判定する設計です。
|
|
143
374
|
そのため Ctrl+C で止めると、しばらく後に中央画面側で自動的にオフライン表示になります。
|
|
144
375
|
|
|
145
|
-
**Q.
|
|
376
|
+
**Q. 鍵(トークン)はどこに書くの?**
|
|
146
377
|
A. **コードやリポジトリには絶対に書きません。** 実行時に環境変数で渡してください。
|
|
147
378
|
|
|
148
379
|
---
|
|
149
380
|
|
|
150
|
-
##
|
|
381
|
+
## 職人(CC2)の起動手順 ★現行(2026-07-31 確定)
|
|
382
|
+
|
|
383
|
+
人が CC2(Claude Code)を起こすときの**現行手順**です。tmux で「箱」を作り、その中で職人を1コマンドで起動します。
|
|
384
|
+
|
|
385
|
+
**① 箱(tmux)を作って入る**
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
tmux new -s <現場名> -c ~/projects/<現場名> # 例: tmux new -s kenzokun -c ~/projects/kenzokun
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
`duplicate session` と出たら**既存の箱があります**(=起動済み)。新しく作らず attach してください(並列禁止)。
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
tmux attach -t <現場名>
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**② tmux の中で職人を起動する**
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
unset ANTHROPIC_API_KEY && claude --permission-mode acceptEdits
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
1コマンドで、**最初から accept edits on** の状態で立ち上がります(起動後に Shift+Tab で切り替える運用は不要になりました)。
|
|
404
|
+
|
|
405
|
+
**relay の常駐を確認**
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
systemctl --user is-active conductor@<現場名>.service
|
|
409
|
+
# active でなければ
|
|
410
|
+
systemctl --user enable --now conductor@<現場名>.service
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**補足**
|
|
414
|
+
|
|
415
|
+
- 画面下の**緑の帯**=いま tmux の中にいる印。
|
|
416
|
+
- 認証ダイアログは **Esc** で閉じる。
|
|
417
|
+
- 初回の `trust` 確認は **Yes**。
|
|
418
|
+
- 箱から抜けるのは **Ctrl+b → d**(デタッチ。職人はそのまま動き続けます)。
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## 補助スクリプト: CC2のワンタッチ起動(scripts/cc2.sh)※旧手順(履歴)
|
|
423
|
+
|
|
424
|
+
> **現行の起動手順は上の「職人(CC2)の起動手順」です。** 本節は経緯として残しています(スクリプト自体は削除していません)。
|
|
151
425
|
|
|
152
426
|
CC2(人が起動する Claude Code)の起動手順を1コマンドに畳んで、**起動ミスを根治**するためのスクリプトです。
|
|
153
427
|
「箱(tmux)が未起動なのに気づかず指示だけ待機」「cd 忘れ / `unset` 忘れ / 現場名のタイプミス / 二重起動」を構造的に防ぎます。
|
|
@@ -164,17 +438,24 @@ alias cc2='bash ~/projects/conductor/scripts/cc2.sh'
|
|
|
164
438
|
|
|
165
439
|
やること:
|
|
166
440
|
|
|
167
|
-
- 引数なし → usage
|
|
168
|
-
-
|
|
441
|
+
- 引数なし → usage と**いま起動できる現場名**(`~/projects` にフォルダが在るもの)を表示して終了。
|
|
442
|
+
- フォルダが無い現場名 → **似た候補を提示(タイプミス検出)**してから一覧を表示。
|
|
169
443
|
- **二重起動防止**: 同名 tmux セッションがあれば attach するだけ(並列禁止)。同じディレクトリで動く別名セッションがあれば軽く警告。
|
|
170
444
|
- 新規セッションは作業ディレクトリで作成 → `unset ANTHROPIC_API_KEY` → `claude` を起動 → attach。**cd 忘れ・unset 忘れを構造的に不可能**にします。
|
|
171
445
|
|
|
172
|
-
>
|
|
173
|
-
>
|
|
446
|
+
> 現場名の解決は `scripts/sites.sh` を**単一の真実**として再利用します(決め方を二重定義しない)。
|
|
447
|
+
> **★2026-09-04 変更: 新しい現場は `sites.sh` を直す必要がありません。** 起動できるかどうかは
|
|
448
|
+
> **`~/projects/<現場名>` がフォルダとして在るか**だけで決まります(`mkdir -p ~/projects/<名前>` で足りる)。
|
|
449
|
+
> 以前は `sites.sh` の配列に名前を書き足すまで「未知の現場名です」で止まっていました(新現場 migakia で実測)。
|
|
450
|
+
> `sites.sh` の配列に残っているのは ①置き場が既定と違う現場の対応表(`plus1` → `plus1-foryou`、
|
|
451
|
+
> `jichinavi` → `~/jichinavi`)と ②一括処理(`deploy-guard.sh` / `restart-all-cc2.sh`)が回る名簿だけで、
|
|
452
|
+
> **起動可否には使いません**。破壊的操作(tmux kill 等)はしません。
|
|
174
453
|
|
|
175
454
|
---
|
|
176
455
|
|
|
177
|
-
## 補助スクリプト: CC2の起動(scripts/cc2-start.sh
|
|
456
|
+
## 補助スクリプト: CC2の起動(scripts/cc2-start.sh)※旧手順(履歴)
|
|
457
|
+
|
|
458
|
+
> **現行の起動手順は上の「職人(CC2)の起動手順」です。** 本節は経緯として残しています。
|
|
178
459
|
|
|
179
460
|
人が CC2(Claude Code)を起動するときの「tmux new → cd → `unset ANTHROPIC_API_KEY` → `claude`」を1コマンドにまとめた補助です(常駐/報告役とは無関係)。`cc2.sh` の前身で、タイプミス検出・同ディレクトリ警告は付いていません(基本動作は同じ)。
|
|
180
461
|
|
|
@@ -182,9 +463,10 @@ alias cc2='bash ~/projects/conductor/scripts/cc2.sh'
|
|
|
182
463
|
bash scripts/cc2-start.sh <現場名> # 例: bash scripts/cc2-start.sh kenzokun
|
|
183
464
|
```
|
|
184
465
|
|
|
185
|
-
|
|
466
|
+
引数なし・フォルダが無い現場名で実行すると、いま起動できる現場名の一覧を表示します。同名の tmux セッションが既にあればそこへ接続し、無ければ作成して CC2 を起動します。
|
|
186
467
|
|
|
187
|
-
>
|
|
468
|
+
> 現場名の解決は `scripts/sites.sh` に集約し、`cc2-start.sh` / `cc2.sh` / `conductor-start.sh` が source して共有します(重複を持たない)。
|
|
469
|
+
> **★起動できるかは `~/projects/<現場名>` がフォルダとして在るかで決まります**(名前の一覧では決めません)。
|
|
188
470
|
|
|
189
471
|
---
|
|
190
472
|
|
|
@@ -203,7 +485,7 @@ bash scripts/conductor-start.sh kenzokun --relay # heartbeat + relay
|
|
|
203
485
|
- 第1引数=現場名(`sites.sh` の対応表から作業ディレクトリを解決)。
|
|
204
486
|
- `--relay` 指定時のみ relay(`CONDUCTOR_RELAY_ENABLED=true`)を有効化します。
|
|
205
487
|
- 内部では現場のディレクトリへ `cd` してから `node dist/cli.js start -s <現場> -t working -a "<現場>稼働"` を実行します(ブランチ名を現場の git から判定するため)。
|
|
206
|
-
- `CONDUCTOR_URL` / `
|
|
488
|
+
- `CONDUCTOR_URL` / `CONDUCTOR_TOKEN` は**呼び出し元のシェルに設定済み前提**で、スクリプトに鍵は書きません。未設定なら案内を出して終了します。
|
|
207
489
|
- 未知の現場名・引数なしのときは有効な現場名一覧を表示します。
|
|
208
490
|
|
|
209
491
|
> これは **人がログイン後に1回叩く半自動** です。PC起動時の完全自動は次の「自動常駐」を使います。
|
|
@@ -225,7 +507,7 @@ bash scripts/relay-start.sh relaytest "スタートアップ調査"
|
|
|
225
507
|
CONDUCTOR_RELAY_INTERVAL_SEC=5 bash scripts/relay-start.sh relaytest
|
|
226
508
|
```
|
|
227
509
|
|
|
228
|
-
- 鍵(`CONDUCTOR_URL` / `
|
|
510
|
+
- 鍵(`CONDUCTOR_URL` / `CONDUCTOR_TOKEN`)は `~/.conductor.env` から**自動読込**します。スクリプトには鍵を書かず、画面にも値を出しません。鍵ファイルが無ければ案内して終了します。
|
|
229
511
|
- `CONDUCTOR_RELAY_ENABLED=true` を付けて relay を有効化します。間隔は `CONDUCTOR_RELAY_INTERVAL_SEC`(既定 15秒)で上書き可。
|
|
230
512
|
- どのディレクトリから実行しても OK(スクリプト位置からリポルートを解決)。`dist/cli.js` が無ければ `npm run build` を案内して終了します。
|
|
231
513
|
- 作業ラベル(第2引数)の既定は `relay手動起動` です。
|
|
@@ -243,12 +525,12 @@ CONDUCTOR_RELAY_INTERVAL_SEC=5 bash scripts/relay-start.sh relaytest
|
|
|
243
525
|
```bash
|
|
244
526
|
cat > "$HOME/.conductor.env" <<'EOF'
|
|
245
527
|
CONDUCTOR_URL=https://<your-conductor-host>
|
|
246
|
-
|
|
528
|
+
CONDUCTOR_TOKEN=(Bitwarden から取得した値を貼る)
|
|
247
529
|
EOF
|
|
248
530
|
chmod 600 "$HOME/.conductor.env" # 自分だけ読める権限に
|
|
249
531
|
```
|
|
250
532
|
|
|
251
|
-
> 🔑 `
|
|
533
|
+
> 🔑 `CONDUCTOR_TOKEN` の値は **Bitwarden の共有項目から取得**してください。
|
|
252
534
|
> `$HOME/.conductor.env` は **git 管理外**(リポジトリには入れません)。このファイルが無い/鍵が空のときは案内を出して終了します。
|
|
253
535
|
|
|
254
536
|
### 2) 自動起動する現場リスト
|
|
@@ -288,7 +570,7 @@ bash scripts/autostart-stop.sh # 自動常駐(node dist/cli.js start)をま
|
|
|
288
570
|
### 前提
|
|
289
571
|
|
|
290
572
|
- WSL で **systemd が有効**(`/etc/wsl.conf` の `[boot] systemd=true`、`[user] default=fshim`)。`systemctl --user` が使えること。
|
|
291
|
-
- 鍵ファイル `$HOME/.conductor.env`(`chmod 600` / git管理外)が用意済み。中身は第1段と同じ(`CONDUCTOR_URL` / `
|
|
573
|
+
- 鍵ファイル `$HOME/.conductor.env`(`chmod 600` / git管理外)が用意済み。中身は第1段と同じ(`CONDUCTOR_URL` / `CONDUCTOR_TOKEN`)。**鍵はリポジトリに入れません。**
|
|
292
574
|
- conductor リポで `npm run build` 済み(`dist/cli.js` が存在)。
|
|
293
575
|
|
|
294
576
|
### 導入
|