claude-task-worker 0.99.0 → 0.101.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 +134 -232
- package/dist/index.js +173 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
GitHub Issues/PRを定期ポーリングし、Claude Codeに処理を委譲するCLIツール。
|
|
4
4
|
|
|
5
|
-
同梱の
|
|
5
|
+
同梱の Claude Code プラグイン(`plugin/`)と組み合わせることで、Issue の実装からPRのレビュー対応、Dependabot PR の対応までを自動化する。CLI 本体(npm パッケージ)とプラグイン(Claude Code マーケットプレイス)は同じリポジトリ・同じ名前で提供される。
|
|
6
6
|
|
|
7
7
|
## アーキテクチャ
|
|
8
8
|
|
|
@@ -42,23 +42,10 @@ CLI が GitHub ラベルを検知してタスクを起動し、プラグイン
|
|
|
42
42
|
共通の挙動:
|
|
43
43
|
|
|
44
44
|
- 処理中は `cc-in-progress` を付与し、同一 Issue/PR の重複実行を防ぐ
|
|
45
|
-
- `cc-need-human-check` が付いた Issue
|
|
46
|
-
- Issue 系ワーカーは `-is:blocked` 検索 qualifier で絞り込むため、未解決の blockedBy を持つ Issue は対象外
|
|
45
|
+
- `cc-need-human-check` が付いた Issue、未解決の blockedBy を持つ Issue は対象外
|
|
47
46
|
- 完了時にトリガーラベルを除去し、次のワーカーへ引き継ぐラベルを付与する
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
- `update-design-md` は `uiDesign.enabled` が `true` のときだけ起動する
|
|
51
|
-
|
|
52
|
-
### プラグインの構成
|
|
53
|
-
|
|
54
|
-
| ディレクトリ | 内容 |
|
|
55
|
-
|---|---|
|
|
56
|
-
| `plugin/skills/` | ワーカーが呼ぶスキル群と、対話セッション用の補助スキル(`commit-push` / `create-pr` / `breakdown-issues` / `edit-pencil-design` など) |
|
|
57
|
-
| `plugin/agents/` | サブエージェント定義(`explore-agent` / `frontend-implementer` / `general-purpose-assistant` / `lightweight-assistant` / `pencil-design-updater` / `requirement-todo-organizer`) |
|
|
58
|
-
| `plugin/hooks/` | `SessionStart`(worktree セットアップ / `git fetch --prune`)と `UserPromptSubmit`(`codegraph prompt-hook`)のフック定義 |
|
|
59
|
-
| `plugin/scripts/` | フック・スキルから呼ばれるスクリプト(`setup-worktree.sh` / `stop-servers.mjs` / `resolve-pr-comments.sh` — `resolve-pr-comments` スキルが GitHub MCP を使えない場合の `gh` フォールバック) |
|
|
60
|
-
| `plugin/references/` | 複数スキルが共有する参照ドキュメント(GitHub アクセス方針など) |
|
|
61
|
-
| `plugin/.mcp.json` | MCP サーバー定義(`codegraph` / `context7` / `next-devtools` / `shadcn` / `playwright`) |
|
|
47
|
+
- 定期ワーカー3つ(`update-*`)はラベルではなく時刻を条件に24時間おきに1回動く。表の「間隔」は24時間経過したかを確認する頻度
|
|
48
|
+
- UIデザイン系3ワーカー(`create-ui-design` / `apply-ui-design` / `update-design-md`)は `uiDesign.enabled` が `true` のときだけ起動する(既定 `false`)
|
|
62
49
|
|
|
63
50
|
## セットアップ
|
|
64
51
|
|
|
@@ -69,16 +56,15 @@ CLI が GitHub ラベルを検知してタスクを起動し、プラグイン
|
|
|
69
56
|
| [Node.js](https://nodejs.org/) >= 22.6.0 | CLI の実行ランタイム |
|
|
70
57
|
| [GitHub CLI (`gh`)](https://cli.github.com/) | 全 GitHub 操作(認証済みであること) |
|
|
71
58
|
| [Claude Code (`claude`)](https://docs.anthropic.com/en/docs/claude-code) | タスク実行エンジン |
|
|
72
|
-
| [Git](https://git-scm.com/) | worktree
|
|
73
|
-
| [
|
|
74
|
-
| [
|
|
75
|
-
| [
|
|
76
|
-
| [
|
|
77
|
-
| [
|
|
78
|
-
| [
|
|
79
|
-
| [GitHub MCP](https://github.com/github/github-mcp-server) | GitHub アクセスの高速化・クラウド実行時のプロキシ制限回避。Claude 側のコネクタで有効化する(任意。未設定でも `gh` へフォールバックする) |
|
|
59
|
+
| [Git](https://git-scm.com/) / [jq](https://jqlang.org/) | worktree 操作 / スキル内での JSON 加工 |
|
|
60
|
+
| [CodeGraph](https://www.npmjs.com/package/@colbymchenry/codegraph) | コード探索用インデックス(任意。未導入ならテキスト検索に落ちる) |
|
|
61
|
+
| [Pen CLI](https://docs.pen.dev/for-developers/pen-cli) | `.pen` の編集・参照。UIデザイン先行ワークフロー使用時のみ(要ログイン) |
|
|
62
|
+
| [Playwright](https://playwright.dev/) のブラウザ | Playwright MCP でのブラウザ確認 |
|
|
63
|
+
| [DESIGN.md CLI](https://github.com/google-labs-code/design.md) | `DESIGN.md` の lint。`update-design-md` 使用時のみ(未導入でも動く) |
|
|
64
|
+
| [herdr](https://herdr.dev) | `--project` / `mode: "herdr"` 使用時のみ(`--cloud` は起動ゲートこそ herdr を要求しないが、実行経路の分岐が未追随のため現状は `mode: "herdr"` が要る) |
|
|
65
|
+
| [GitHub MCP](https://github.com/github/github-mcp-server) | GitHub アクセスの高速化・クラウド実行時のプロキシ制限回避(任意。Claude 側のコネクタで有効化) |
|
|
80
66
|
|
|
81
|
-
CLI 本体に npm の実行時依存はない(
|
|
67
|
+
CLI 本体に npm の実行時依存はない(Node.js 標準モジュールのみで動作する)。
|
|
82
68
|
|
|
83
69
|
### インストール
|
|
84
70
|
|
|
@@ -86,7 +72,7 @@ CLI 本体に npm の実行時依存はない(esbuild で `dist/index.js` に
|
|
|
86
72
|
npx claude-task-worker install
|
|
87
73
|
```
|
|
88
74
|
|
|
89
|
-
|
|
75
|
+
マーケットプレイス追加・プラグイン導入・CLI 本体のグローバルインストール・各種 CLI(CodeGraph / DESIGN.md / Pen)と Playwright ブラウザの取得を一括で行う。いずれかが失敗しても処理は継続する。インストール後、Claude Code のセッションを再起動するとプラグインが有効になる。
|
|
90
76
|
|
|
91
77
|
個別にやる場合:
|
|
92
78
|
|
|
@@ -96,38 +82,7 @@ claude plugin marketplace add getty104/claude-task-worker
|
|
|
96
82
|
claude plugin install claude-task-worker@claude-task-worker
|
|
97
83
|
```
|
|
98
84
|
|
|
99
|
-
herdr
|
|
100
|
-
|
|
101
|
-
クラウド実行(`--cloud` フラグ)を使う場合は、クラウド VM(Claude Code on the web)側にもプラグイン・CLI が必要になる。claude.ai の環境設定(Environment setup script / セットアップスクリプト欄)に `npx claude-task-worker install` を直接記載しておく。あわせて、クラウドセッションが push / PR 作成を行うには対象リポジトリの GitHub App 連携が必要。
|
|
102
|
-
|
|
103
|
-
UIデザイン先行ワークフローを使う場合は、同じ claude.ai の環境設定の環境変数欄に `PEN_CLI_KEY` も設定する。`.pen` を扱うスキル(`edit-pencil-design` / `inspect-pencil-node` / `resolve-pencil-conflict`)の Pen CLI 認証に使うもので、クラウド VM では対話ログインができないため。キーの発行元と値の形式は後述の「[Pen CLI のログイン](#pen-cli-のログイン)」を参照。
|
|
104
|
-
|
|
105
|
-
詳細は後述の「[`--cloud`](#--cloud)」を参照。
|
|
106
|
-
|
|
107
|
-
### GitHub コネクタの有効化
|
|
108
|
-
|
|
109
|
-
GitHub MCP は Claude 側のコネクタとして有効化する(本プラグインは `.mcp.json` で宣言しない)。claude.ai の設定 > コネクタ、または Claude Code の `/mcp` から GitHub コネクタを有効化する。
|
|
110
|
-
|
|
111
|
-
任意の設定であり、未設定でもスキルは `gh` へフォールバックして動作する。対応表は [`plugin/references/github-access.md`](./plugin/references/github-access.md) を参照。
|
|
112
|
-
|
|
113
|
-
### Pen CLI のログイン
|
|
114
|
-
|
|
115
|
-
`.pen` を扱うスキル(`edit-pencil-design` / `inspect-pencil-node` / `resolve-pencil-conflict`)は Pen CLI の認証を必要とする。未ログインだと `.pen` の読み書きが失敗するため、UIデザイン先行ワークフローを使うなら**インストール後に一度ログインしておく**。
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
pencil login # メールアドレス + パスワード、またはメールアドレス + OTP コード
|
|
119
|
-
pencil status # 認証状態の確認
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
セッショントークンは `~/.pencil/session-cli.json` に保存され、以降のコマンドで再利用される。
|
|
123
|
-
|
|
124
|
-
CI やワーカーを実行するマシンなど対話ログインできない環境では、環境変数 `PEN_CLI_KEY`(pen.dev の組織設定 > Developer Keys で発行)を使う。保存済みトークンより優先される。
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
export PEN_CLI_KEY=pencil_cli_...
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
詳細は [Pen CLI のドキュメント](https://docs.pen.dev/for-developers/pen-cli)を参照。
|
|
85
|
+
herdr は `curl -fsSL https://herdr.dev/install.sh | sh` または `brew install herdr`([ドキュメント](https://herdr.dev/docs/install/))。
|
|
131
86
|
|
|
132
87
|
### 更新
|
|
133
88
|
|
|
@@ -135,11 +90,11 @@ export PEN_CLI_KEY=pencil_cli_...
|
|
|
135
90
|
claude-task-worker update
|
|
136
91
|
```
|
|
137
92
|
|
|
138
|
-
マーケットプレイス・プラグイン・CLI
|
|
93
|
+
マーケットプレイス・プラグイン・CLI 本体・各種 CLI をまとめて更新する。プラグインの反映にはセッション再起動が必要。
|
|
139
94
|
|
|
140
95
|
### 初期化
|
|
141
96
|
|
|
142
|
-
対象リポジトリで実行すると、GitHub ラベル・Issue テンプレート・GitHub Actions
|
|
97
|
+
対象リポジトリで実行すると、GitHub ラベル・Issue テンプレート・GitHub Actions ワークフロー・設定ファイル(`claude-task-worker.json`)が作成され、CodeGraph のインデックスが構築される。
|
|
143
98
|
|
|
144
99
|
```bash
|
|
145
100
|
claude-task-worker init # 既存ファイルは保護
|
|
@@ -151,30 +106,17 @@ claude-task-worker init --force # 強制上書き
|
|
|
151
106
|
| ラベル | 用途 |
|
|
152
107
|
|---|---|
|
|
153
108
|
| `cc-triage-scope` | トリアージ対象マーク(Issue/PR) |
|
|
154
|
-
| `cc-issue-created` | `create-issue` 由来の Issue
|
|
155
|
-
| `cc-update-issue` | Issue
|
|
156
|
-
| `cc-
|
|
157
|
-
| `cc-exec-issue` | Issue 実行トリガー |
|
|
158
|
-
| `cc-fix-onetime` | PR 修正トリガー(1回) |
|
|
159
|
-
| `cc-resolve-conflict` | PR コンフリクト解消トリガー |
|
|
109
|
+
| `cc-issue-created` | `create-issue` 由来の Issue マーク |
|
|
110
|
+
| `cc-update-issue` / `cc-answer-issue-questions` / `cc-exec-issue` | Issue の更新 / 確認事項回答 / 実行トリガー |
|
|
111
|
+
| `cc-fix-onetime` / `cc-resolve-conflict` | PR の修正 / コンフリクト解消トリガー |
|
|
160
112
|
| `cc-in-progress` | 処理中ステータス |
|
|
161
|
-
| `cc-need-human-check` |
|
|
113
|
+
| `cc-need-human-check` | 人間の確認が必要(付与中はワーカーの対象外) |
|
|
162
114
|
| `cc-pr-created` | PR 作成完了マーク |
|
|
163
115
|
| `cc-epic-issue` | エピックマーク(Issue: サブ全 Close で `epic-issue` 起動 / PR: リリースゲート対象) |
|
|
164
|
-
| `cc-release-ready` | エピックPR
|
|
165
|
-
| `cc-create-ui-design` | UI
|
|
166
|
-
| `cc-ui-design
|
|
167
|
-
| `cc-
|
|
168
|
-
| `cc-ui-design` | デザインPRのマーカー(`triage-pr` のレビュー観点切り替え用) |
|
|
169
|
-
| `cc-cloud-done` | クラウド実行タスクの完了マーク(セッションが最後に付与し、ワーカーが検知して除去する。人が手動で付与しても同じ経路で完了扱いになるため、張り付いたクラウドタスクの救済手段としても使える) |
|
|
170
|
-
|
|
171
|
-
作成されるファイル:
|
|
172
|
-
|
|
173
|
-
- `.github/ISSUE_TEMPLATE/cc-triage-scope.yml` — `cc-triage-scope` 付き Issue 作成用テンプレート
|
|
174
|
-
- `.github/workflows/assign-creator-on-cc-triage-scope.yml` — Issue 作成者の自動アサイン
|
|
175
|
-
- `claude-task-worker.json` — 設定ファイル。**ワーカーごとの既定値は書き出さない**(写経するとプラグイン更新で既定が変わっても古い値に固定されるため)。上書きしたいワーカーだけ手で追記する
|
|
176
|
-
|
|
177
|
-
CodeGraph のセットアップとして、グローバル gitignore(`~/.config/git/ignore`)へ `.codegraph/` を冪等に追記し、`codegraph init` を実行する。CodeGraph 未インストールでも `init` 全体は失敗しない。
|
|
116
|
+
| `cc-release-ready` | エピックPRがリリース可能と判定されたマーク(マージは人間が実施) |
|
|
117
|
+
| `cc-create-ui-design` / `cc-ui-design-pr-created` / `cc-ui-design-ready` | UIデザイン先行ワークフローの各段階 |
|
|
118
|
+
| `cc-ui-design` | デザインPRのマーカー |
|
|
119
|
+
| `cc-cloud-done` | クラウド実行タスクの完了マーク(セッションが付与し、ワーカーが検知して除去する。手動付与で張り付いたタスクを救済できる) |
|
|
178
120
|
|
|
179
121
|
## コマンド
|
|
180
122
|
|
|
@@ -184,27 +126,28 @@ claude-task-worker <command> [--epic <issue-number>]... [--label <label>]... [--
|
|
|
184
126
|
|
|
185
127
|
| コマンド | 内容 |
|
|
186
128
|
|---|---|
|
|
187
|
-
| 各ワーカー名 | 単一ワーカーを起動(`exec-issue` / `triage-pr`
|
|
188
|
-
| `all` | 通常ワーカー9つ + 定期ワーカー3
|
|
189
|
-
| `yolo` |
|
|
129
|
+
| 各ワーカー名 | 単一ワーカーを起動(`exec-issue` / `triage-pr` など) |
|
|
130
|
+
| `all` | 通常ワーカー9つ + 定期ワーカー3つ(`triage-created-issue` / `triage-pr` / `check-dependabot` を除く) |
|
|
131
|
+
| `yolo` | 全ワーカーを同時にポーリング |
|
|
190
132
|
| `init` | ラベル・テンプレート・設定ファイルの作成と CodeGraph セットアップ |
|
|
191
133
|
| `install` / `update` | 上記「セットアップ」を参照 |
|
|
134
|
+
| `cloud-setup [--force]` | クラウド VM 側の準備(下記「`--cloud`」を参照) |
|
|
192
135
|
| `usage` | Claude API 使用状況(5時間/7日間の利用率とリセット時刻)を表示し、Slack にも通知 |
|
|
193
136
|
| `version` | CLI のバージョンを表示(`--version` / `-v` も可) |
|
|
194
137
|
|
|
195
138
|
### `--epic <issue-number>`
|
|
196
139
|
|
|
197
|
-
指定したエピック Issue のサブ Issue
|
|
140
|
+
指定したエピック Issue のサブ Issue のみを処理対象に絞る。複数指定は OR。
|
|
198
141
|
|
|
199
142
|
```bash
|
|
200
143
|
claude-task-worker all --epic 100 --epic 200
|
|
201
144
|
```
|
|
202
145
|
|
|
203
|
-
`epic-issue`
|
|
146
|
+
`epic-issue` ワーカーではエピック Issue 自身の番号として照合される。
|
|
204
147
|
|
|
205
148
|
### `--label <label>`
|
|
206
149
|
|
|
207
|
-
トリガーラベルに加えて指定ラベルが付いた Issue
|
|
150
|
+
トリガーラベルに加えて指定ラベルが付いた Issue のみに絞る。複数指定は AND。`--epic` と併用可能。
|
|
208
151
|
|
|
209
152
|
```bash
|
|
210
153
|
claude-task-worker all --label priority-high --label needs-design
|
|
@@ -212,117 +155,103 @@ claude-task-worker all --label priority-high --label needs-design
|
|
|
212
155
|
|
|
213
156
|
### `--project <name>`
|
|
214
157
|
|
|
215
|
-
指定したプロジェクト(またはグループ、`all`)へ [herdr](https://herdr.dev)
|
|
158
|
+
指定したプロジェクト(またはグループ、`all`)へ [herdr](https://herdr.dev) 経由でコマンドをディスパッチする。CLI はワーカーを直接実行せず、プロジェクトごとに独立した herdr ワークスペースを作ってそこでコマンドを実行し、稼働状況をステータステーブルに表示する。SIGTERM/SIGINT で全セッションを一括停止する。
|
|
216
159
|
|
|
217
160
|
```bash
|
|
218
161
|
claude-task-worker all --project all
|
|
219
|
-
claude-task-worker
|
|
220
|
-
claude-task-worker exec-issue --project app-a --epic 100 --label priority-high
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
プロジェクト名・グループ名は `$XDG_CONFIG_HOME/claude-task-worker/config.json`(未設定なら `~/.config/claude-task-worker/config.json`)で定義する。`all` は全プロジェクトを指す予約語。
|
|
224
|
-
|
|
225
|
-
```json
|
|
226
|
-
{
|
|
227
|
-
"mode": "default",
|
|
228
|
-
"advisor": false,
|
|
229
|
-
"permission": "bypassPermissions",
|
|
230
|
-
"projects": {
|
|
231
|
-
"app-a": "/Users/me/repos/app-a",
|
|
232
|
-
"app-b": "/Users/me/repos/app-b"
|
|
233
|
-
},
|
|
234
|
-
"projectGroups": {
|
|
235
|
-
"frontend": ["app-a", "app-b"]
|
|
236
|
-
}
|
|
237
|
-
}
|
|
162
|
+
claude-task-worker exec-issue --project app-a --epic 100
|
|
238
163
|
```
|
|
239
164
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
- **一斉起動**: プロジェクトごとに `ctw:<プロジェクト名>` ラベルのワークスペースを作り、そこで(`--project` を除いた)同じコマンドを実行する。ワーカーが実際に起動したかを確認し、起動しなければ再送・失敗判定する
|
|
243
|
-
- **稼働一覧**: プロジェクト名・ワークスペースID・ペインID・ステータス・稼働時間をステータステーブルに描画する
|
|
244
|
-
- **一括停止**: SIGTERM/SIGINT で全セッションへ ctrl-c を送り、終了を待ってワークスペースを閉じる。もう一度送ると強制終了
|
|
165
|
+
プロジェクト名・グループ名は `config.json` で定義する(下記「設定ファイル」)。`all` は全プロジェクトを指す予約語。
|
|
245
166
|
|
|
246
167
|
`--project` と併用できないコマンド: `init` / `install` / `update` / `usage` / `version`
|
|
247
168
|
|
|
248
169
|
### `--cloud`
|
|
249
170
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
許可リスト方式にしているのは、クラウド実行が「成果ゼロでも完了扱いになり、トリガーラベルの再付与で再起動され続ける」失敗の仕方をするため。`triage-pr` などは GraphQL ゲートで判断材料を取得できず空振りするが、完了扱いになるとポーリング間隔ごとにクラウドセッションを焼き続ける。
|
|
171
|
+
タスクを Claude Code on the web(クラウド VM)で実行する。プロセス単位のフラグで既定は無効。
|
|
253
172
|
|
|
254
173
|
```bash
|
|
255
174
|
claude-task-worker exec-issue --cloud
|
|
256
175
|
claude-task-worker all --cloud
|
|
257
176
|
```
|
|
258
177
|
|
|
178
|
+
**クラウドで実行されるのは `exec-issue` と `fix-review-point` の2ワーカーだけ**で、それ以外は `--cloud` を付けてもローカル実行のまま残る(`all` / `yolo` にそのまま付けられる)。どのワーカーがクラウドで走るかは起動時にログへ出る。
|
|
179
|
+
|
|
259
180
|
前提条件:
|
|
260
181
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
182
|
+
| 前提 | 備考 |
|
|
183
|
+
|---|---|
|
|
184
|
+
| `script` コマンドが使える環境(macOS / Linux) | クラウドセッションの作成には TTY が必要で、それを `script` コマンドの疑似 pty で供給する。platform が darwin/linux でない、または `script` が PATH に無い場合はタスクを1件も起動せずエラー終了する(フォールバックしない) |
|
|
185
|
+
| claude.ai アカウントでのサインイン | API キー認証・第三者プロバイダ(Bedrock / Vertex)構成では利用不可。`--cloud` 指定時のみ検査される |
|
|
186
|
+
| 対象リポジトリの GitHub App 連携 | クラウド VM から push / PR 作成を行うため |
|
|
187
|
+
| claude.ai の「プルリクエストを自動的に作成する」「プルリクエストの自動修正」が **OFF** | 下記 |
|
|
188
|
+
| VM 側のセットアップスクリプト | 下記 |
|
|
189
|
+
| `PEN_CLI_KEY` 環境変数 | UIデザイン先行ワークフローを使う場合のみ(下記「Pen CLI のログイン」) |
|
|
190
|
+
|
|
191
|
+
claude.ai の設定にある **「プルリクエストを自動的に作成する」「プルリクエストの自動修正」は必ず OFF にする**。どちらもタスクワーカーの制御と競合する。前者はスキルの `create-pr`(`Closes #<N>`・ベースブランチ・ラベル付与)とは別に PR を作るため PR が重複し、後者はセッションが PR 作成後に終了せずレビューを待って修正を続けるため、`cc-cloud-done` による完了検知が 4 時間のタイムアウトまで効かない。
|
|
266
192
|
|
|
267
|
-
|
|
193
|
+
claude.ai の環境設定(セットアップスクリプト欄)に次の2行を記載しておく。
|
|
268
194
|
|
|
269
|
-
|
|
195
|
+
```bash
|
|
196
|
+
npx claude-task-worker install
|
|
197
|
+
npx claude-task-worker cloud-setup
|
|
198
|
+
```
|
|
270
199
|
|
|
271
|
-
|
|
200
|
+
`cloud-setup` は VM 側の `~/.claude/settings.json` に権限モード・出力スタイル・言語を書き込み、グローバル gitignore へ `.codegraph/` を登録する。クラウドセッションは起動フラグの `--permission-mode` を反映しないため、この設定ファイルが権限モードを指定する唯一の経路になる。書き込みはキー単位のマージで既存の設定を消さない(`--force` で上書き)。
|
|
272
201
|
|
|
273
|
-
|
|
202
|
+
補足:
|
|
274
203
|
|
|
275
|
-
|
|
204
|
+
- クラウド実行のタスクは worktree を作らない(VM が自前でリポジトリを持つため)
|
|
205
|
+
- 完了は `cc-cloud-done` ラベルで検知する。4時間で応答がなければ打ち切り、`cc-need-human-check` を付けて失敗通知する
|
|
206
|
+
- `--project` と併用した場合、`--cloud` は各プロジェクトへそのまま転送される
|
|
207
|
+
- `--cloud` と併用できないコマンド: `init` / `install` / `update` / `usage` / `version`
|
|
208
|
+
- **現時点では `mode: "default"` での `--cloud` はクラウド経路へ流れない**(実行経路の分岐が `mode: "herdr"` 判定のまま未追随のため)。`--cloud` を使うには `mode: "herdr"` にしておく必要がある。追随は別Issueで対応予定
|
|
276
209
|
|
|
277
210
|
詳細は [`docs/prd-cloud-worker-execution.md`](./docs/prd-cloud-worker-execution.md) を参照。
|
|
278
211
|
|
|
212
|
+
### Pen CLI のログイン
|
|
213
|
+
|
|
214
|
+
`.pen` を扱うスキルは Pen CLI の認証を必要とする。UIデザイン先行ワークフローを使うなら一度ログインしておく。
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
pencil login # メールアドレス + パスワード、またはメールアドレス + OTP コード
|
|
218
|
+
pencil status # 認証状態の確認
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
CI やクラウド VM など対話ログインできない環境では、環境変数 `PEN_CLI_KEY`(pen.dev の組織設定 > Developer Keys で発行)を使う。保存済みトークンより優先される。
|
|
222
|
+
|
|
279
223
|
## 設定ファイル
|
|
280
224
|
|
|
281
|
-
グローバル設定は
|
|
225
|
+
グローバル設定は `$XDG_CONFIG_HOME/claude-task-worker/config.json`(未設定なら `~/.config/claude-task-worker/config.json`)、リポジトリ設定は実行ディレクトリ直下の `claude-task-worker.json`。
|
|
282
226
|
|
|
283
227
|
### `config.json`(グローバル)
|
|
284
228
|
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"mode": "default",
|
|
232
|
+
"advisor": false,
|
|
233
|
+
"permission": "bypassPermissions",
|
|
234
|
+
"projects": {
|
|
235
|
+
"app-a": "/Users/me/repos/app-a",
|
|
236
|
+
"app-b": "/Users/me/repos/app-b"
|
|
237
|
+
},
|
|
238
|
+
"projectGroups": {
|
|
239
|
+
"frontend": ["app-a", "app-b"]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
285
244
|
| キー | 既定 | 説明 |
|
|
286
245
|
|---|---|---|
|
|
287
246
|
| `projects` | - | プロジェクト名 → 絶対パス |
|
|
288
247
|
| `projectGroups` | `{}` | グループ名 → プロジェクト名配列 |
|
|
289
|
-
| `mode` | `"default"` |
|
|
290
|
-
| `advisor` | `false` | `--advisor`
|
|
291
|
-
| `permission` | `"bypassPermissions"` | Claude CLI
|
|
248
|
+
| `mode` | `"default"` | `"default"`: `claude -p` の子プロセスとして実行 / `"herdr"`: herdr のタブ内で TUI 起動し、実行中の様子を覗ける(`--project` はこちらが必要) |
|
|
249
|
+
| `advisor` | `false` | `true` で `--advisor <model>` を渡す。モデルは `claude-task-worker.json` の `advisorModel` |
|
|
250
|
+
| `permission` | `"bypassPermissions"` | Claude CLI の[権限モード](https://code.claude.com/docs/ja/permission-modes)(`bypassPermissions` / `dontAsk` / `auto` / `acceptEdits` / `manual` / `plan`) |
|
|
292
251
|
|
|
293
|
-
|
|
252
|
+
いずれもトップレベル一括で、プロジェクト単位・ワーカー単位の指定はできない。`permission` はワーカーに承認するユーザーがいないため、`bypassPermissions` / `dontAsk` 以外ではタスクが承認待ちで止まりうる。
|
|
294
253
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
| `mode` | 挙動 |
|
|
298
|
-
|---|---|
|
|
299
|
-
| `"default"` | タスクを `claude -p`(非対話 print モード)の子プロセスとして実行 |
|
|
300
|
-
| `"herdr"` | タスクを herdr のタブ内で TUI セッションとして実行。実行中の様子を herdr で覗ける |
|
|
301
|
-
|
|
302
|
-
`"herdr"` では、worktree 作成後に `ctw:<プロジェクト名>:#<番号>` ラベルのタブを作り、そのルートペインで claude を TUI 起動する。agent ステータスを監視して完了を検知し、セッション transcript から最終レポートを回収して通知に使う。`blocked`(claude が入力待ち)になっても自動失敗にせず待機し、ステータステーブルに `running:blocked` と表示するので herdr のタブを開いて直接対応できる。herdr が未インストール・未起動なら起動時にエラー終了する(`"default"` へフォールバックしない)。
|
|
303
|
-
|
|
304
|
-
> ℹ️ タスク完了時の通知音はワーカー側から止められない(音を鳴らすのは herdr サーバープロセスで、`HERDR_DISABLE_SOUND` もそのプロセスの環境変数として読まれるため)。無音にするには `~/.config/herdr/config.toml` に `[ui.sound] enabled = false` を書いて `herdr server reload-config` する。ただし herdr サーバー全体に効くため、対話セッションの完了音も鳴らなくなる。
|
|
305
|
-
|
|
306
|
-
#### `advisor`(アドバイザーモデル)
|
|
307
|
-
|
|
308
|
-
`true` にすると、タスク起動時に Claude CLI へ `--advisor <model>` を渡す。渡すモデルは `claude-task-worker.json` の `workers.<名前>.advisorModel`。`mode` と同じくトップレベル一括で、プロジェクト単位・ワーカー単位のオン/オフはできない。空文字が指定されたワーカーには渡さない。
|
|
309
|
-
|
|
310
|
-
advisor は main モデル以上の能力が必要(Claude CLI の制約)。`model` が `opus` のワーカーに `opus` advisor を付けても意味がなく、既定で `sonnet` のワーカーも `opus` advisor を付けると下げたぶんのコスト削減を打ち消すため、`advisorModel` の既定値は全ワーカー空文字(advisor なし)。`sonnet` のワーカーの品質が落ちた場合の調整弁として `advisorModel: "opus"` を指定できる。
|
|
311
|
-
|
|
312
|
-
#### `permission`(権限モード)
|
|
313
|
-
|
|
314
|
-
タスク起動時に Claude CLI へ渡す[権限モード](https://code.claude.com/docs/ja/permission-modes)。`mode` / `advisor` と同じくトップレベル一括で、プロジェクト単位・ワーカー単位の指定はできない。
|
|
315
|
-
|
|
316
|
-
| `permission` | 挙動 |
|
|
317
|
-
|---|---|
|
|
318
|
-
| `"bypassPermissions"`(既定) | 全許可。承認するユーザーが常駐しない自律実行のため既定 |
|
|
319
|
-
| `"dontAsk"` | 許可されていない操作は確認せずスキップする |
|
|
320
|
-
| `"auto"` | 安全な操作は自動承認、危険な操作のみ確認 |
|
|
321
|
-
| `"acceptEdits"` | ファイル編集は自動承認、それ以外は都度確認 |
|
|
322
|
-
| `"manual"` | 標準の権限確認 |
|
|
323
|
-
| `"plan"` | 読み取りのみ。変更は行わない |
|
|
324
|
-
|
|
325
|
-
値は Claude CLI の `--permission-mode` にそのまま渡される(choices と同じ綴り)。ワーカーには承認するユーザーがいないため、`bypassPermissions` / `dontAsk` 以外ではタスクが承認待ちで止まりうる(`mode: "herdr"` なら herdr のタブを開いて手動で承認できる)。
|
|
254
|
+
> ℹ️ `mode: "herdr"` の完了通知音はワーカー側から止められない。無音にするには `~/.config/herdr/config.toml` に `[ui.sound] enabled = false` を書いて `herdr server reload-config` する(herdr サーバー全体に効く)。
|
|
326
255
|
|
|
327
256
|
### `claude-task-worker.json`(リポジトリ)
|
|
328
257
|
|
|
@@ -331,32 +260,34 @@ advisor は main モデル以上の能力が必要(Claude CLI の制約)。`
|
|
|
331
260
|
| `fixReviewPointCallbackCommentMessage` | string | - | `fix-review-point` 完了時に PR へ投稿するコメント(未設定なら投稿しない) |
|
|
332
261
|
| `uiDesign` | object | `{ "enabled": false, "designDir": "designs", "yolo": false }` | UIデザイン先行ワークフロー(下記) |
|
|
333
262
|
| `workers` | object | `{}` | ワーカーごとの上書き設定(下記) |
|
|
334
|
-
| `lastRun` | object | `{}` |
|
|
263
|
+
| `lastRun` | object | `{}` | 定期ワーカーの最終実行時刻。ワーカーが自動更新するため手で編集しない |
|
|
335
264
|
|
|
336
265
|
#### ワーカーごとの設定
|
|
337
266
|
|
|
338
267
|
未指定のワーカー・フィールドは既定値にフォールバックする。
|
|
339
268
|
|
|
340
|
-
| フィールド |
|
|
341
|
-
|
|
342
|
-
| `skill` |
|
|
343
|
-
| `model` |
|
|
344
|
-
| `advisorModel` |
|
|
345
|
-
| `effort` |
|
|
346
|
-
| `pollingIntervalSeconds` |
|
|
347
|
-
| `cooldownSeconds` |
|
|
348
|
-
| `maxConcurrentTasks` |
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
| ワーカー | `model` | `effort` | `
|
|
353
|
-
|
|
354
|
-
| `exec-issue` / `fix-review-point` / `answer-issue-questions` / `create-issue` / `create-ui-design` / `triage-pr` | `opus` | `high` |
|
|
355
|
-
| `update-issue` / `triage-created-issue` / `resolve-conflict` | `sonnet` | `high` |
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
358
|
-
| `update-coding-guidelines` / `update-requirement-rules` / `update-design-md` | `opus` | `high` |
|
|
359
|
-
| (未知のワーカー名) | `opus` | `high` |
|
|
269
|
+
| フィールド | 説明 |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `skill` | Claude CLI の `-p` に渡すスラッシュコマンド(`"<skill> <番号>"` の形で起動) |
|
|
272
|
+
| `model` | `--model` の値(`sonnet` / `opus` / `haiku`) |
|
|
273
|
+
| `advisorModel` | `--advisor` の値。空文字なら advisor なし。`config.json` の `advisor: true` のときだけ参照される |
|
|
274
|
+
| `effort` | `--effort` の値(`high` / `medium` / `low`) |
|
|
275
|
+
| `pollingIntervalSeconds` | ポーリング間隔(秒) |
|
|
276
|
+
| `cooldownSeconds` | タスク完了後にポーリングを止める時間(秒)。既定 `0` |
|
|
277
|
+
| `maxConcurrentTasks` | 同時実行できるタスクの最大数。既定 `1` |
|
|
278
|
+
|
|
279
|
+
既定値:
|
|
280
|
+
|
|
281
|
+
| ワーカー | `model` | `effort` | `pollingIntervalSeconds` |
|
|
282
|
+
|---|---|---|---|
|
|
283
|
+
| `exec-issue` / `fix-review-point` / `answer-issue-questions` / `create-issue` / `create-ui-design` / `triage-pr` | `opus` | `high` | 60 |
|
|
284
|
+
| `update-issue` / `triage-created-issue` / `resolve-conflict` | `sonnet` | `high` | 60 |
|
|
285
|
+
| `epic-issue` / `apply-ui-design` | `sonnet` | `medium` | 300 |
|
|
286
|
+
| `check-dependabot` | `sonnet` | `high` | 3600 |
|
|
287
|
+
| `update-coding-guidelines` / `update-requirement-rules` / `update-design-md` | `opus` | `high` | 3600 |
|
|
288
|
+
| (未知のワーカー名) | `opus` | `high` | 60 |
|
|
289
|
+
|
|
290
|
+
`advisorModel` の既定は全ワーカー空文字(advisor なし)。
|
|
360
291
|
|
|
361
292
|
設定例:
|
|
362
293
|
|
|
@@ -365,8 +296,7 @@ advisor は main モデル以上の能力が必要(Claude CLI の制約)。`
|
|
|
365
296
|
"workers": {
|
|
366
297
|
"exec-issue": { "model": "opus", "cooldownSeconds": 600, "maxConcurrentTasks": 3 },
|
|
367
298
|
"fix-review-point": { "model": "sonnet", "advisorModel": "opus", "maxConcurrentTasks": 2 },
|
|
368
|
-
"triage-pr": { "effort": "medium", "pollingIntervalSeconds": 120 }
|
|
369
|
-
"check-dependabot": { "model": "haiku", "pollingIntervalSeconds": 7200 }
|
|
299
|
+
"triage-pr": { "effort": "medium", "pollingIntervalSeconds": 120 }
|
|
370
300
|
}
|
|
371
301
|
}
|
|
372
302
|
```
|
|
@@ -375,86 +305,58 @@ advisor は main モデル以上の能力が必要(Claude CLI の制約)。`
|
|
|
375
305
|
|
|
376
306
|
### Epic(親Issue)連携
|
|
377
307
|
|
|
378
|
-
親 Issue
|
|
308
|
+
親 Issue を持つサブ Issue は、デフォルトブランチではなく `cc-epic-<親Issue番号>` ブランチから worktree を作って処理される。サブ Issue ごとのPRを単一の統合ブランチへ集約するため。エピックブランチが remote に無ければ自動で派生・push される。
|
|
379
309
|
|
|
380
|
-
サブ Issue がすべて Close されると `epic-issue`
|
|
310
|
+
サブ Issue がすべて Close されると `epic-issue` ワーカーがエピックブランチからまとめてPRを作る。エピックPRは `triage-pr` がマージ可能と判定してもマージせず `cc-release-ready` を付けるだけで、実際のマージ(リリース)は人間に委ねられる。
|
|
381
311
|
|
|
382
312
|
### UIデザイン先行ワークフロー
|
|
383
313
|
|
|
384
|
-
UI実装 Issue について、実装の前に Pencil(`.pen`)でデザインを作り、独立したPR
|
|
385
|
-
|
|
386
|
-
`uiDesign.enabled` によるオプトインで、既定(`false`)では2つのワーカーが起動しないため、Pencil を使っていないリポジトリの挙動は本機能の追加前と完全に一致する。
|
|
314
|
+
UI実装 Issue について、実装の前に Pencil(`.pen`)でデザインを作り、独立したPRとしてマージしてから実装へ進むフロー。`uiDesign.enabled` によるオプトインで、既定(`false`)では関連ワーカーが起動しない。
|
|
387
315
|
|
|
388
316
|
| キー | 既定 | 意味 |
|
|
389
317
|
|---|---|---|
|
|
390
|
-
| `uiDesign.enabled` | `false` |
|
|
318
|
+
| `uiDesign.enabled` | `false` | 有効化 |
|
|
391
319
|
| `uiDesign.designDir` | `"designs"` | `.pen` とスナップショットの配置先(リポジトリルートからの相対パス) |
|
|
392
|
-
| `uiDesign.yolo` | `false` |
|
|
320
|
+
| `uiDesign.yolo` | `false` | `true` でデザインPRに `cc-triage-scope` を付け、既存フローで自動レビュー・自動マージへ流す |
|
|
393
321
|
|
|
394
322
|
```text
|
|
395
|
-
|
|
396
|
-
├─ UI実装タスクでない → cc-exec-issue
|
|
323
|
+
triage-created-issue(ルーティング)
|
|
324
|
+
├─ UI実装タスクでない → cc-exec-issue
|
|
397
325
|
└─ UI実装タスク → cc-create-ui-design
|
|
398
|
-
→ create-ui-design
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
→ yolo: true → triage-pr / fix-review-point / resolve-conflict(既存フローでレビュー・マージ)
|
|
403
|
-
yolo: false → 人がデザインPRをレビュー・マージ
|
|
404
|
-
→ apply-ui-design ワーカー
|
|
405
|
-
・デザインPRが MERGED になるまで skip
|
|
406
|
-
・Issue description に「## UIデザイン」セクションを追記
|
|
407
|
-
・cc-ui-design-ready + cc-exec-issue を付与
|
|
408
|
-
→ exec-issue(デザインを参照元として実装)
|
|
326
|
+
→ create-ui-design: .pen + snapshots を作り、デザインPR(cc-ui-design)を作成
|
|
327
|
+
→ yolo: true なら自動レビュー・マージ / false なら人がレビュー・マージ
|
|
328
|
+
→ apply-ui-design: マージ後に Issue description へ「## UIデザイン」を追記し cc-exec-issue を付与
|
|
329
|
+
→ exec-issue: デザインを参照元として実装
|
|
409
330
|
```
|
|
410
331
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
デザインが不要と判明した場合は `create-ui-design` が理由をコメントして `cc-ui-design-ready` + `cc-exec-issue` を付与し、人手を介さず実装へ復帰する。Pencil が使えない環境やデザインPRが却下された場合は `cc-need-human-check` で停止する。
|
|
332
|
+
デザインが不要と判明した場合は `create-ui-design` が理由をコメントして実装へ復帰する。Pencil が使えない環境やデザインPRが却下された場合は `cc-need-human-check` で停止する。
|
|
414
333
|
|
|
415
334
|
## Slack通知
|
|
416
335
|
|
|
417
|
-
環境変数 `CLAUDE_TASK_WORKER_SLACK_WEBHOOK_URL` に
|
|
336
|
+
環境変数 `CLAUDE_TASK_WORKER_SLACK_WEBHOOK_URL` に Incoming Webhook URL を設定すると、タスクの完了時・失敗時に通知が送られる。未設定なら送信されない。
|
|
418
337
|
|
|
419
338
|
```bash
|
|
420
339
|
export CLAUDE_TASK_WORKER_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz
|
|
421
340
|
claude-task-worker all
|
|
422
341
|
```
|
|
423
342
|
|
|
424
|
-
通知には Claude API
|
|
425
|
-
|
|
426
|
-
クラウド実行(`--cloud`)のタスクは、通知の先頭行にクラウドセッションのURL(`https://claude.ai/code/<id>`)が入る。Slack で本文が折りたたまれても先頭行は見えるため。
|
|
343
|
+
通知には Claude API の使用状況も含まれる。あわせて [RunCat Neo](https://kyome.io/runcat/) 用のスナップショットを `~/.claude/runcat-usage.json`(`RUNCAT_OUT_FILE` で変更可)へ書き出す。クラウド実行のタスクは通知の先頭行にセッションURLが入る。
|
|
427
344
|
|
|
428
345
|
## プロセス管理
|
|
429
346
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
- タスクID・タイトル・ステータス(running/completed/failed)・開始時刻・経過時間を表示
|
|
433
|
-
- `mode: "herdr"` では実行中の行に agent ステータスが併記される(`running:working` / `running:blocked`)
|
|
434
|
-
- 同一 Issue/PR の重複実行を自動防止
|
|
435
|
-
- SIGTERM/SIGINT で全子プロセスを graceful shutdown(もう一度送ると強制終了し、ラベル・worktree の後片付けを試みる)
|
|
436
|
-
- 前回の異常終了で残った worktree はワーカー起動時に自動回収される(実行中タスク・対話セッションが掴んでいるものは保護される)
|
|
437
|
-
|
|
438
|
-
### タスク実行のガード
|
|
439
|
-
|
|
440
|
-
ワーカーは応答するユーザーがいない状態でスキルを起動するため、処理が未完のままセッションが終了してラベルだけ進む事故を防ぐガードを持つ。
|
|
347
|
+
実行中のタスクはリアルタイムのステータステーブルで表示される(タスクID・タイトル・ステータス・開始時刻・経過時間)。SIGTERM/SIGINT で graceful shutdown し、もう一度送ると強制終了してラベル・worktree の後片付けを試みる。前回の異常終了で残った worktree はワーカー起動時に自動回収される。
|
|
441
348
|
|
|
442
|
-
|
|
443
|
-
- **ツールの無効化**: `--disallowedTools` で `Monitor` / `ScheduleWakeup` / `AskUserQuestion` / `EnterPlanMode` / `Cron*` / `RemoteTrigger` / `EnterWorktree` を無効化する
|
|
444
|
-
- **自律実行原則の注入**: `--append-system-prompt` で「ユーザーに質問しない・全ステップを完遂してから終了する・曖昧なら安全側を選ぶ・サブエージェントの完了報告を検証する」および CodeGraph 優先のコード探索方針を注入する
|
|
445
|
-
- **完了検証**: `exec-issue` / `epic-issue` は PR の実在(または Issue のクローズ)を確認できるまで `cc-pr-created` を付けず、確認できなければ `cc-need-human-check` を付けて Issue にコメントを残す
|
|
446
|
-
- **空振り検知**: 正常終了しても出力が空のセッションは失敗として分類し、失敗通知(stderr の末尾を含む)を送る
|
|
447
|
-
- **起動プロセスの後片付け**: スキル終了時に `Stop` フックが `docker compose down` と、worktree を作業ディレクトリに持つ残留プロセスの `SIGTERM` をベストエフォートで実行する(worktree はスキル完了直後に削除されるため、残留プロセスが削除の妨げになるのを防ぐ)
|
|
349
|
+
ワーカーは応答するユーザーがいない状態でスキルを起動するため、処理が未完のままラベルだけ進む事故を防ぐガードを持つ(バックグラウンド実行と対話系ツールの無効化、自律実行原則のシステムプロンプト注入、PR 実在の完了検証、空出力セッションの失敗扱い、`Stop` フックによる残留プロセスの停止)。
|
|
448
350
|
|
|
449
351
|
## 開発
|
|
450
352
|
|
|
451
353
|
```bash
|
|
452
354
|
npm install
|
|
453
|
-
npm run build #
|
|
355
|
+
npm run build # 型チェック + esbuild で dist/index.js にバンドル
|
|
454
356
|
npm run dev # 型チェックの watch モード
|
|
455
|
-
npm test #
|
|
357
|
+
npm test # ユニットテスト
|
|
456
358
|
npm run lint # ESLint(--fix で自動修正)
|
|
457
|
-
npm run format # Prettier
|
|
359
|
+
npm run format # Prettier で整形
|
|
458
360
|
```
|
|
459
361
|
|
|
460
362
|
開発版をローカルから使う場合は `npm install && npm run build && npm link`。
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ var __export = (target, all) => {
|
|
|
12
12
|
// src/table.ts
|
|
13
13
|
var table_exports = {};
|
|
14
14
|
__export(table_exports, {
|
|
15
|
+
CONTROL_CHARS: () => CONTROL_CHARS,
|
|
15
16
|
LOG_DISPLAY_LIMIT: () => LOG_DISPLAY_LIMIT,
|
|
16
17
|
TASK_DISPLAY_LIMIT: () => TASK_DISPLAY_LIMIT,
|
|
17
18
|
buildLogTableLines: () => buildLogTableLines,
|
|
@@ -190,7 +191,8 @@ var init_table = __esm({
|
|
|
190
191
|
rawLog = console.log.bind(console);
|
|
191
192
|
rawClear = console.clear.bind(console);
|
|
192
193
|
consoleCaptured = false;
|
|
193
|
-
CONTROL_CHARS =
|
|
194
|
+
CONTROL_CHARS = // eslint-disable-next-line no-control-regex -- ANSI/制御文字を意図的に対象にする
|
|
195
|
+
/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b\[[0-9;?]*[ -/]*[@-~]|[\x00-\x08\x0b-\x1f\x7f]/g;
|
|
194
196
|
}
|
|
195
197
|
});
|
|
196
198
|
|
|
@@ -588,6 +590,7 @@ __export(herdr_runner_exports, {
|
|
|
588
590
|
buildHerdrTaskResult: () => buildHerdrTaskResult,
|
|
589
591
|
createCompletionTracker: () => createCompletionTracker,
|
|
590
592
|
extractCloudSessionId: () => extractCloudSessionId,
|
|
593
|
+
normalizePtyOutput: () => normalizePtyOutput,
|
|
591
594
|
observeAgentStatus: () => observeAgentStatus,
|
|
592
595
|
startHerdrTask: () => startHerdrTask,
|
|
593
596
|
stopHerdrTask: () => stopHerdrTask,
|
|
@@ -629,6 +632,9 @@ function observeAgentStatus(tracker, status) {
|
|
|
629
632
|
function extractCloudSessionId(text) {
|
|
630
633
|
return CLOUD_SESSION_URL_RE.exec(text)?.[1] ?? CLOUD_SESSION_CREATED_RE.exec(text)?.[1];
|
|
631
634
|
}
|
|
635
|
+
function normalizePtyOutput(text) {
|
|
636
|
+
return text.replace(CONTROL_CHARS, "");
|
|
637
|
+
}
|
|
632
638
|
function buildHerdrTaskResult(paneOutput, options) {
|
|
633
639
|
const report = options?.report?.trim() ?? "";
|
|
634
640
|
if (report !== "") {
|
|
@@ -810,6 +816,7 @@ var AGENT_POLL_INTERVAL_MS, PANE_OUTPUT_LINES, CLOUD_SESSION_URL_RE, CLOUD_SESSI
|
|
|
810
816
|
var init_herdr_runner = __esm({
|
|
811
817
|
"src/herdr-runner.ts"() {
|
|
812
818
|
"use strict";
|
|
819
|
+
init_table();
|
|
813
820
|
init_transcript();
|
|
814
821
|
AGENT_POLL_INTERVAL_MS = 3 * 1e3;
|
|
815
822
|
PANE_OUTPUT_LINES = 300;
|
|
@@ -1635,7 +1642,7 @@ import { readFileSync, writeFileSync } from "node:fs";
|
|
|
1635
1642
|
import { isAbsolute, join, normalize, sep as SEP } from "node:path";
|
|
1636
1643
|
|
|
1637
1644
|
// src/dispatch-args.ts
|
|
1638
|
-
var FLAG_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "usage", "version"];
|
|
1645
|
+
var FLAG_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "cloud-setup", "usage", "version"];
|
|
1639
1646
|
function collectFlagValues(argv, flag) {
|
|
1640
1647
|
const values = [];
|
|
1641
1648
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -1888,9 +1895,9 @@ function checkCloudAuth(input) {
|
|
|
1888
1895
|
function checkCloudConfig(input) {
|
|
1889
1896
|
if (!input.cloud) return [];
|
|
1890
1897
|
const errors = [];
|
|
1891
|
-
if (input.
|
|
1898
|
+
if (input.scriptAvailable === false) {
|
|
1892
1899
|
errors.push(
|
|
1893
|
-
`--cloud requires
|
|
1900
|
+
`--cloud requires a pty, provided via the "script" command (creating a new cloud session requires a TTY, which the worker's spawn does not have on its own). "script" is unavailable \u2014 either the platform is not darwin/linux, or "script" is not on PATH. Drop the --cloud flag, or run on darwin/linux where "script" is available.`
|
|
1894
1901
|
);
|
|
1895
1902
|
}
|
|
1896
1903
|
if (input.auth !== void 0) errors.push(...checkCloudAuth(input.auth));
|
|
@@ -2521,15 +2528,26 @@ ${principles}`;
|
|
|
2521
2528
|
function shellQuote2(value) {
|
|
2522
2529
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
2523
2530
|
}
|
|
2531
|
+
function buildScriptCommand(command, args, platform = process.platform) {
|
|
2532
|
+
if (platform === "darwin") {
|
|
2533
|
+
return { command: "script", args: ["-q", "/dev/null", command, ...args] };
|
|
2534
|
+
}
|
|
2535
|
+
if (platform === "linux") {
|
|
2536
|
+
return { command: "script", args: ["-qec", [command, ...args].map(shellQuote2).join(" "), "/dev/null"] };
|
|
2537
|
+
}
|
|
2538
|
+
throw new Error(`unsupported platform for script(1): ${platform}`);
|
|
2539
|
+
}
|
|
2524
2540
|
function buildClaudeExecution(invocation) {
|
|
2525
2541
|
return {
|
|
2526
2542
|
command: CLAUDE_COMMAND,
|
|
2527
2543
|
args: buildClaudeArgs(invocation),
|
|
2528
|
-
|
|
2544
|
+
// クラウド実行では `-p` を付けない代わりに `--cloud` の値(初期プロンプト)として
|
|
2545
|
+
// 渡すため、mode に関わらずプロンプトを返す。
|
|
2546
|
+
...invocation.mode === "herdr" || invocation.cloud === true ? { prompt: invocation.prompt } : {}
|
|
2529
2547
|
};
|
|
2530
2548
|
}
|
|
2531
2549
|
function buildClaudeEnv(mode, cloud) {
|
|
2532
|
-
const base = mode === "herdr" ? { CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: CLAUDE_SPAWN_ENV.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS } : { ...CLAUDE_SPAWN_ENV };
|
|
2550
|
+
const base = mode === "herdr" || cloud ? { CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: CLAUDE_SPAWN_ENV.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS } : { ...CLAUDE_SPAWN_ENV };
|
|
2533
2551
|
if (!cloud) return base;
|
|
2534
2552
|
return { ...base, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" };
|
|
2535
2553
|
}
|
|
@@ -2827,13 +2845,55 @@ async function flagOrphanedCloudSession(target, id, reason, cloudSessionId) {
|
|
|
2827
2845
|
console.error(`[worker] failed to comment on ${target} #${id} about the orphaned cloud session: ${err}`);
|
|
2828
2846
|
});
|
|
2829
2847
|
}
|
|
2848
|
+
async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
2849
|
+
const { extractCloudSessionId: extractCloudSessionId2, normalizePtyOutput: normalizePtyOutput2 } = await Promise.resolve().then(() => (init_herdr_runner(), herdr_runner_exports));
|
|
2850
|
+
const spec = buildScriptCommand("claude", buildCloudCreateArgs(args, initialPrompt));
|
|
2851
|
+
const child = spawn(spec.command, spec.args, {
|
|
2852
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2853
|
+
...cwd ? { cwd } : {},
|
|
2854
|
+
...env ? { env: { ...process.env, ...env } } : {}
|
|
2855
|
+
});
|
|
2856
|
+
let output = "";
|
|
2857
|
+
return await new Promise((resolve3, reject) => {
|
|
2858
|
+
let settled = false;
|
|
2859
|
+
const finish = (err, sessionId) => {
|
|
2860
|
+
if (settled) return;
|
|
2861
|
+
settled = true;
|
|
2862
|
+
clearTimeout(timer);
|
|
2863
|
+
clearInterval(abortCheck);
|
|
2864
|
+
if (err) {
|
|
2865
|
+
child.kill();
|
|
2866
|
+
reject(err);
|
|
2867
|
+
} else {
|
|
2868
|
+
resolve3(sessionId);
|
|
2869
|
+
}
|
|
2870
|
+
};
|
|
2871
|
+
const scan = () => {
|
|
2872
|
+
const sessionId = extractCloudSessionId2(normalizePtyOutput2(output));
|
|
2873
|
+
if (sessionId) finish(void 0, sessionId);
|
|
2874
|
+
};
|
|
2875
|
+
child.stdout?.on("data", (chunk) => {
|
|
2876
|
+
output += chunk.toString("utf-8");
|
|
2877
|
+
scan();
|
|
2878
|
+
});
|
|
2879
|
+
child.on("error", (err) => finish(new Error(`failed to spawn the cloud session command: ${err.message}`)));
|
|
2880
|
+
child.on("close", () => {
|
|
2881
|
+
scan();
|
|
2882
|
+
finish(new Error(`the cloud session command exited without a session id (output tail: ${output.slice(-1e3)})`));
|
|
2883
|
+
});
|
|
2884
|
+
const timer = setTimeout(
|
|
2885
|
+
() => finish(new Error(`timed out waiting for the cloud session id (output tail: ${output.slice(-1e3)})`)),
|
|
2886
|
+
CLOUD_SESSION_TIMEOUT_MS
|
|
2887
|
+
);
|
|
2888
|
+
const abortCheck = setInterval(() => {
|
|
2889
|
+
if (herdrAbortSignal.aborted) {
|
|
2890
|
+
finish(new Error("the worker is shutting down before the cloud session could be created"));
|
|
2891
|
+
}
|
|
2892
|
+
}, CLOUD_SESSION_POLL_INTERVAL_MS);
|
|
2893
|
+
});
|
|
2894
|
+
}
|
|
2830
2895
|
async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget, model) {
|
|
2831
|
-
const herdrRunnerMod = await Promise.resolve().then(() => (init_herdr_runner(), herdr_runner_exports));
|
|
2832
|
-
const { taskTabLabel: taskTabLabel2, waitForPaneReady: waitForPaneReady3, extractCloudSessionId: extractCloudSessionId2 } = herdrRunnerMod;
|
|
2833
|
-
const herdrMod = await Promise.resolve().then(() => (init_herdr(), herdr_exports));
|
|
2834
|
-
const { tabCreate: tabCreate2, tabClose: tabClose2, paneSendText: paneSendText2, paneSendKeys: paneSendKeys2, paneRead: paneRead2, getCurrentWorkspaceId: getCurrentWorkspaceId2 } = herdrMod;
|
|
2835
2896
|
herdrTasks.set(id, { paneId: "", tabId: "" });
|
|
2836
|
-
const label = taskTabLabel2(resolveProjectName(), id);
|
|
2837
2897
|
const initialPrompt = buildCloudPrompt(
|
|
2838
2898
|
prompt,
|
|
2839
2899
|
model ?? "",
|
|
@@ -2842,39 +2902,7 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
2842
2902
|
let result;
|
|
2843
2903
|
let cloudSessionId;
|
|
2844
2904
|
try {
|
|
2845
|
-
|
|
2846
|
-
herdrTasks.set(id, created);
|
|
2847
|
-
try {
|
|
2848
|
-
const ready = await waitForPaneReady3(created.paneId, herdrMod);
|
|
2849
|
-
if (!ready) {
|
|
2850
|
-
console.warn(`[worker] pane ${created.paneId} produced no prompt before the timeout, launching anyway`);
|
|
2851
|
-
}
|
|
2852
|
-
const command = ["claude", ...buildCloudCreateArgs(args, initialPrompt)].map(shellQuote2).join(" ");
|
|
2853
|
-
await paneSendText2(created.paneId, command);
|
|
2854
|
-
await paneSendKeys2(created.paneId, "enter");
|
|
2855
|
-
const deadline = Date.now() + CLOUD_SESSION_TIMEOUT_MS;
|
|
2856
|
-
for (; ; ) {
|
|
2857
|
-
if (herdrAbortSignal.aborted) {
|
|
2858
|
-
throw new Error("the worker is shutting down before the cloud session could be created");
|
|
2859
|
-
}
|
|
2860
|
-
let content = "";
|
|
2861
|
-
try {
|
|
2862
|
-
content = await paneRead2(created.paneId);
|
|
2863
|
-
} catch (err) {
|
|
2864
|
-
console.error(`[worker] failed to read pane ${created.paneId} while waiting for the cloud session: ${err}`);
|
|
2865
|
-
}
|
|
2866
|
-
cloudSessionId = extractCloudSessionId2(content);
|
|
2867
|
-
if (cloudSessionId) break;
|
|
2868
|
-
if (Date.now() >= deadline) {
|
|
2869
|
-
throw new Error(`timed out waiting for the cloud session id (pane tail: ${content.slice(-1e3)})`);
|
|
2870
|
-
}
|
|
2871
|
-
await new Promise((resolve3) => setTimeout(resolve3, CLOUD_SESSION_POLL_INTERVAL_MS));
|
|
2872
|
-
}
|
|
2873
|
-
} finally {
|
|
2874
|
-
await tabClose2(created.tabId).catch((err) => {
|
|
2875
|
-
console.error(`[worker] failed to close cloud task tab ${created.tabId}: ${err}`);
|
|
2876
|
-
});
|
|
2877
|
-
}
|
|
2905
|
+
cloudSessionId = await createCloudSession(args, initialPrompt, cwd, env);
|
|
2878
2906
|
const createOutput = `[worker] created cloud session ${cloudSessionId} with the task's initial prompt`;
|
|
2879
2907
|
if (!cloudTarget) {
|
|
2880
2908
|
console.warn(`[worker] #${id} has no completion-detection target, treating session creation as completion`);
|
|
@@ -2922,7 +2950,8 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
2922
2950
|
console.error(`[worker] failed to run #${id} via cloud: ${err}`);
|
|
2923
2951
|
let orphanNote = "[worker] note: with the 1-command launch, the cloud session may already have started working independently even though this task is being reported as failed locally (orphaned session).";
|
|
2924
2952
|
if (cloudTarget) {
|
|
2925
|
-
|
|
2953
|
+
const reason = herdrAbortSignal.aborted ? "shutdown" : "session-id";
|
|
2954
|
+
await flagOrphanedCloudSession(cloudTarget, id, reason, cloudSessionId);
|
|
2926
2955
|
orphanNote += " added cc-need-human-check so a human can verify whether it completed on its own.";
|
|
2927
2956
|
}
|
|
2928
2957
|
result = {
|
|
@@ -2948,11 +2977,11 @@ function run(command, args, id, title, workerName, path2, onComplete, cwd, env,
|
|
|
2948
2977
|
});
|
|
2949
2978
|
ensureRenderInterval();
|
|
2950
2979
|
renderTable();
|
|
2980
|
+
if (cloud) {
|
|
2981
|
+
void runViaCloud(args, prompt ?? "", id, onComplete, cwd, env, cloudTarget, model);
|
|
2982
|
+
return;
|
|
2983
|
+
}
|
|
2951
2984
|
if (getRunMode() === "herdr") {
|
|
2952
|
-
if (cloud) {
|
|
2953
|
-
void runViaCloud(args, prompt ?? "", id, onComplete, cwd, env, cloudTarget, model);
|
|
2954
|
-
return;
|
|
2955
|
-
}
|
|
2956
2985
|
void runViaHerdr(args, prompt ?? "", id, onComplete, cwd, env);
|
|
2957
2986
|
return;
|
|
2958
2987
|
}
|
|
@@ -5089,6 +5118,78 @@ async function install() {
|
|
|
5089
5118
|
console.log("[install] Done.");
|
|
5090
5119
|
}
|
|
5091
5120
|
|
|
5121
|
+
// src/commands/cloud-setup.ts
|
|
5122
|
+
import { mkdir as mkdir3, writeFile as writeFile3, readFile as readFile2 } from "node:fs/promises";
|
|
5123
|
+
import { homedir as homedir6 } from "node:os";
|
|
5124
|
+
import { join as join8 } from "node:path";
|
|
5125
|
+
var LOG_PREFIX = "cloud-setup";
|
|
5126
|
+
var CLOUD_DEFAULT_PERMISSION_MODE = "auto";
|
|
5127
|
+
var CLOUD_SETTINGS_DEFAULTS = {
|
|
5128
|
+
outputStyle: "Proactive",
|
|
5129
|
+
language: "Japanese"
|
|
5130
|
+
};
|
|
5131
|
+
function claudeSettingsPath() {
|
|
5132
|
+
const dir = process.env.CLAUDE_CONFIG_DIR;
|
|
5133
|
+
return join8(dir && dir.length > 0 ? dir : join8(homedir6(), ".claude"), "settings.json");
|
|
5134
|
+
}
|
|
5135
|
+
function withCloudDefaults(existing, force) {
|
|
5136
|
+
const parsed = existing === null ? {} : JSON.parse(existing);
|
|
5137
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
5138
|
+
throw new Error("not a JSON object");
|
|
5139
|
+
}
|
|
5140
|
+
const settings = { ...parsed };
|
|
5141
|
+
const current = settings["permissions"] ?? {};
|
|
5142
|
+
if (typeof current !== "object" || current === null || Array.isArray(current)) {
|
|
5143
|
+
throw new Error("`permissions` is not an object");
|
|
5144
|
+
}
|
|
5145
|
+
const permissions = { ...current };
|
|
5146
|
+
let changed = false;
|
|
5147
|
+
const set = (target, key, value) => {
|
|
5148
|
+
if (key in target && !force) return;
|
|
5149
|
+
if (target[key] === value) return;
|
|
5150
|
+
target[key] = value;
|
|
5151
|
+
changed = true;
|
|
5152
|
+
};
|
|
5153
|
+
set(permissions, "defaultMode", CLOUD_DEFAULT_PERMISSION_MODE);
|
|
5154
|
+
for (const [key, value] of Object.entries(CLOUD_SETTINGS_DEFAULTS)) set(settings, key, value);
|
|
5155
|
+
if (!changed) return null;
|
|
5156
|
+
return `${JSON.stringify({ ...settings, permissions }, null, 2)}
|
|
5157
|
+
`;
|
|
5158
|
+
}
|
|
5159
|
+
async function writeClaudeSettings(force) {
|
|
5160
|
+
const path2 = claudeSettingsPath();
|
|
5161
|
+
let existing;
|
|
5162
|
+
try {
|
|
5163
|
+
existing = await readFile2(path2, "utf-8");
|
|
5164
|
+
} catch {
|
|
5165
|
+
existing = null;
|
|
5166
|
+
}
|
|
5167
|
+
let next;
|
|
5168
|
+
try {
|
|
5169
|
+
next = withCloudDefaults(existing, force);
|
|
5170
|
+
} catch (e) {
|
|
5171
|
+
console.log(`[${LOG_PREFIX}] Skipped: ${path2} (${e instanceof Error ? e.message : String(e)})`);
|
|
5172
|
+
return;
|
|
5173
|
+
}
|
|
5174
|
+
if (next === null) {
|
|
5175
|
+
console.log(`[${LOG_PREFIX}] Already set: ${path2}`);
|
|
5176
|
+
return;
|
|
5177
|
+
}
|
|
5178
|
+
try {
|
|
5179
|
+
await mkdir3(join8(path2, ".."), { recursive: true });
|
|
5180
|
+
await writeFile3(path2, next, "utf-8");
|
|
5181
|
+
} catch (e) {
|
|
5182
|
+
console.log(`[${LOG_PREFIX}] Failed to write ${path2}: ${e instanceof Error ? e.message : String(e)}`);
|
|
5183
|
+
return;
|
|
5184
|
+
}
|
|
5185
|
+
console.log(`[${LOG_PREFIX}] ${existing === null ? "Created" : "Updated"}: ${path2}`);
|
|
5186
|
+
}
|
|
5187
|
+
async function cloudSetup(options = {}) {
|
|
5188
|
+
await writeClaudeSettings(options.force ?? false);
|
|
5189
|
+
await ensureCodegraphGitIgnore(LOG_PREFIX);
|
|
5190
|
+
console.log(`[${LOG_PREFIX}] Done.`);
|
|
5191
|
+
}
|
|
5192
|
+
|
|
5092
5193
|
// src/commands/update.ts
|
|
5093
5194
|
init_run_command();
|
|
5094
5195
|
var PLUGIN_NAME2 = "claude-task-worker";
|
|
@@ -5144,14 +5245,14 @@ async function update() {
|
|
|
5144
5245
|
|
|
5145
5246
|
// src/commands/version.ts
|
|
5146
5247
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
5147
|
-
import { dirname as dirname3, join as
|
|
5248
|
+
import { dirname as dirname3, join as join9 } from "node:path";
|
|
5148
5249
|
import { fileURLToPath } from "node:url";
|
|
5149
5250
|
import { styleText } from "node:util";
|
|
5150
5251
|
var REGISTRY_URL = "https://registry.npmjs.org/claude-task-worker/latest";
|
|
5151
5252
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
5152
5253
|
function localVersion() {
|
|
5153
5254
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
5154
|
-
const pkgPath =
|
|
5255
|
+
const pkgPath = join9(here, "..", "package.json");
|
|
5155
5256
|
const pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
|
|
5156
5257
|
return pkg.version ?? "unknown";
|
|
5157
5258
|
}
|
|
@@ -5217,6 +5318,7 @@ Commands:
|
|
|
5217
5318
|
init [--force] Create required GitHub labels and config file (use --force to overwrite existing files)
|
|
5218
5319
|
install Add the claude-task-worker marketplace, install the plugin, and install/update the CLI
|
|
5219
5320
|
update Update the claude-task-worker plugin/marketplace and the CLI itself
|
|
5321
|
+
cloud-setup [--force] Prepare a cloud session VM (writes permission mode, output style, and language into ~/.claude/settings.json). Meant for a cloud environment setup script
|
|
5220
5322
|
usage Notify current usage to Slack
|
|
5221
5323
|
version Print the installed claude-task-worker CLI version (aliases: --version, -v)
|
|
5222
5324
|
|
|
@@ -5267,7 +5369,7 @@ if (!workerType) {
|
|
|
5267
5369
|
printUsage();
|
|
5268
5370
|
process.exit(1);
|
|
5269
5371
|
}
|
|
5270
|
-
if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "usage" && !WORKERS[workerType]) {
|
|
5372
|
+
if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "cloud-setup" && workerType !== "usage" && !WORKERS[workerType]) {
|
|
5271
5373
|
console.error(`Unknown command: ${workerType}`);
|
|
5272
5374
|
printUsage();
|
|
5273
5375
|
process.exit(1);
|
|
@@ -5344,13 +5446,27 @@ async function readCloudAuthStatus() {
|
|
|
5344
5446
|
return { kind: "unknown" };
|
|
5345
5447
|
}
|
|
5346
5448
|
}
|
|
5449
|
+
async function resolveScriptAvailable() {
|
|
5450
|
+
try {
|
|
5451
|
+
buildScriptCommand("true", []);
|
|
5452
|
+
} catch {
|
|
5453
|
+
return false;
|
|
5454
|
+
}
|
|
5455
|
+
try {
|
|
5456
|
+
await execFileAsync4("which", ["script"]);
|
|
5457
|
+
return true;
|
|
5458
|
+
} catch {
|
|
5459
|
+
return false;
|
|
5460
|
+
}
|
|
5461
|
+
}
|
|
5347
5462
|
async function assertCloudAvailable() {
|
|
5348
5463
|
const cloud = hasCloudFlag();
|
|
5349
5464
|
const labelReady = cloud ? await createLabel(CLOUD_DONE_LABEL, "33cfff", true) : true;
|
|
5350
5465
|
const status = cloud ? await readCloudAuthStatus() : void 0;
|
|
5466
|
+
const scriptAvailable = cloud ? await resolveScriptAvailable() : void 0;
|
|
5351
5467
|
const errors = checkCloudConfig({
|
|
5352
5468
|
cloud,
|
|
5353
|
-
|
|
5469
|
+
scriptAvailable,
|
|
5354
5470
|
auth: status ? { status, baseUrl: process.env.ANTHROPIC_BASE_URL } : void 0
|
|
5355
5471
|
});
|
|
5356
5472
|
if (!labelReady) {
|
|
@@ -5452,6 +5568,10 @@ if (hasProjectFilter()) {
|
|
|
5452
5568
|
(async () => {
|
|
5453
5569
|
await update();
|
|
5454
5570
|
})();
|
|
5571
|
+
} else if (workerType === "cloud-setup") {
|
|
5572
|
+
(async () => {
|
|
5573
|
+
await cloudSetup({ force: process.argv.slice(3).includes("--force") });
|
|
5574
|
+
})();
|
|
5455
5575
|
} else if (workerType === "usage") {
|
|
5456
5576
|
(async () => {
|
|
5457
5577
|
const text = await buildTokenLimitText();
|