@tocca-systems/twp-cli 0.22.0 → 0.24.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/CHANGELOG.public.md +6 -0
- package/README.md +147 -6
- package/command-model/department.json +1 -1
- package/dist/{ai-dispatch-VSCKUY6J.js → ai-dispatch-36HRDRLF.js} +1 -1
- package/dist/{api-command-Q2CSB4PV.js → api-command-NMYYJKZH.js} +5 -17
- package/dist/{app-THTQX3A5.js → app-2KMY3QPM.js} +27 -26
- package/dist/{auto-update-FBZGOQFI.js → auto-update-CV2MM32C.js} +1 -1
- package/dist/{auto-update-worker-Z3XKBFMQ.js → auto-update-worker-AXBJIMFP.js} +2 -2
- package/dist/{backlog-X2MQTA6F.js → backlog-7MJIOT22.js} +2 -2
- package/dist/{charter-command-UPKTVL7H.js → charter-command-UBUE3KUO.js} +2 -2
- package/dist/{chunk-5ISIXBKD.js → chunk-4V4T5ZUS.js} +45 -18
- package/dist/chunk-5Q2CH4E7.js +3 -0
- package/dist/chunk-6NCY4NPV.js +62 -0
- package/dist/{chunk-M3GWY6NT.js → chunk-7WSNIXTQ.js} +2 -1
- package/dist/chunk-DDKZ5IPT.js +11 -0
- package/dist/{chunk-2VISRLWS.js → chunk-DMDVLOAY.js} +8 -8
- package/dist/chunk-EJ474UDB.js +3 -0
- package/dist/chunk-FTYJZFEK.js +10 -0
- package/dist/{chunk-E4H22AO5.js → chunk-GDM2QUBL.js} +1 -1
- package/dist/{chunk-X4RS5VBH.js → chunk-GMBJTG6A.js} +1 -1
- package/dist/{chunk-QVXZEUKN.js → chunk-HGTG5XQ7.js} +1 -1
- package/dist/{chunk-I2QFW7EK.js → chunk-HW3QGKYR.js} +1 -1
- package/dist/chunk-I3YPO7CY.js +57 -0
- package/dist/chunk-IJLJGDMZ.js +7 -0
- package/dist/{chunk-DSDVIU6A.js → chunk-ILKQDXI5.js} +1 -1
- package/dist/{chunk-O52CUEDO.js → chunk-IOGVQVGD.js} +1 -1
- package/dist/chunk-NAUH75MM.js +10 -0
- package/dist/chunk-NZ7WI4RZ.js +18 -0
- package/dist/{chunk-JB27KNCX.js → chunk-QOUFHYK5.js} +29 -25
- package/dist/{chunk-XLE4HW6B.js → chunk-UIWGEBWI.js} +1 -1
- package/dist/{chunk-JDMNIUVX.js → chunk-VCMVTC6B.js} +1 -1
- package/dist/chunk-WGVHYTZV.js +38 -0
- package/dist/{chunk-PI5DUWNZ.js → chunk-WOUKWOAR.js} +1 -1
- package/dist/{chunk-3XG457E3.js → chunk-YVAN3H5W.js} +5 -5
- package/dist/chunk-ZN5EFDH7.js +5 -0
- package/dist/chunk-ZWVYVS2A.js +4 -0
- package/dist/cli.js +78 -11
- package/dist/{commands-ET4F34OD.js → commands-6YTOVZ5P.js} +16 -16
- package/dist/{commands-NXBQ5OWL.js → commands-U36UTCKR.js} +8 -8
- package/dist/department-JOXXJKQB.js +33 -0
- package/dist/job-title-L47J6TZY.js +8 -0
- package/dist/{logout-guard-CMZZBRUL.js → logout-guard-FO7KZL3X.js} +1 -1
- package/dist/media-ZMDYHHNN.js +64 -0
- package/dist/{oneshot-QVFA2SUM.js → oneshot-KYATQPL7.js} +5 -5
- package/dist/position-FHWCMMBQ.js +8 -0
- package/dist/{project-2LJZW747.js → project-ZODASYER.js} +1 -1
- package/dist/query-EEALMOSO.js +3 -0
- package/dist/render-K45EOLHX.js +3 -0
- package/dist/run-QCDT35NT.js +4 -0
- package/dist/server-settings-CG3EM7R7.js +1 -1
- package/dist/{setup-UI6V2Q3V.js → setup-6CXUVCF5.js} +1 -1
- package/dist/storage-ANKKJJJO.js +3 -0
- package/dist/{task-GKNM3G4K.js → task-G5YWQ6L5.js} +7 -63
- package/dist/{update-3QHRK5BP.js → update-PZBUIYOL.js} +1 -1
- package/dist/user-DO4VNIBR.js +204 -0
- package/package.json +1 -1
- package/dist/chunk-BOBSH3QN.js +0 -9
- package/dist/chunk-GFC2ASHE.js +0 -6
- package/dist/chunk-JKSXUBND.js +0 -9
- package/dist/chunk-PEGUHUTD.js +0 -3
- package/dist/chunk-RKJ6B2KL.js +0 -56
- package/dist/query-NJMVSQR6.js +0 -3
- package/dist/render-XMVI3AKB.js +0 -3
- package/dist/run-IS46BQBB.js +0 -4
- package/dist/user-EU7Z3DAO.js +0 -24
package/CHANGELOG.public.md
CHANGED
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
`CHANGELOG.md` に残してあります。顧客向けの履歴は public 公開以降を対象とします。
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
|
+
## 0.23.0
|
|
15
|
+
|
|
16
|
+
会話の中で AI が TWP のデータを調べて使えるようになりました。AI は必要な操作を検索し、内容を確かめてから実行します。TWP のデータを読む・書く操作は、実行前に確認が表示されます(削除は毎回確認します)。
|
|
17
|
+
|
|
18
|
+
プロジェクトコードに小文字や空白を使っている場合でも、エージェントループがタスクの進み具合を正しく読み取れるようになりました。タスクが先に進んでいるのに同じ作業の再開が止められる、リリースを止めている不具合の修正が後回しになる、といったことが起きなくなります。
|
|
19
|
+
|
|
14
20
|
## 0.22.0
|
|
15
21
|
|
|
16
22
|
AI が git の差分や履歴を読むときに、リポジトリ側で設定された外部の差分表示コマンドを実行しないようになりました。信用できないリポジトリで「変更点を見て」と頼んだだけで、そのリポジトリが仕込んだコマンドが動いてしまうことを防ぎます。差分そのものは通常どおり表示されます。
|
package/README.md
CHANGED
|
@@ -20,7 +20,9 @@ TWP(Tocca Working Platform)を、ターミナルから使うための CLI
|
|
|
20
20
|
|---|---|
|
|
21
21
|
| **できる** | AI との会話(ストリーミング表示)。手元のファイルの読み書き・検索、コマンド実行、git の読み取り——いずれも**実行前に確認**します |
|
|
22
22
|
| **できる** | `twp project` / `twp task` によるプロジェクト・タスクの読み書き(一覧・取得・作成・更新・削除・コメント) |
|
|
23
|
-
| **できる** | `twp user`
|
|
23
|
+
| **できる** | `twp user` によるテナントのユーザーの作成・更新・失効(退社)と招待(1件・CSV 一括・再送・取消)、ユーザーと所属(部署・役職)の参照(一覧・取得・所属の履歴)、所属の付け替え(異動)・作成・更新・終了・削除。作成・更新・招待と取得、所属の書き込み、他人の所属の参照は組織管理者の権限が要ります |
|
|
24
|
+
| **できる** | `twp department` / `twp position` / `twp job-title` による組織マスタ(部署・役職・職位)の一覧・取得・作成・更新・削除と、部署ツリー・部署の所属者の表示。作成・更新・削除は管理者の権限が要ります |
|
|
25
|
+
| **できる** | `twp media` によるメディアライブラリのファイルのアップロード・一覧・ダウンロード・削除(ゴミ箱へ移す)・一括操作(公開・非公開・アーカイブ・移動・削除・復元・ZIP ダウンロード)、`twp storage get` によるストレージ使用量の確認(管理者) |
|
|
24
26
|
| **できる** | `twp task-loop` による、TWP のタスクキューを手元の AI CLI に実行させる常駐ループ |
|
|
25
27
|
| **できる** | スラッシュコマンド: `/help` `/mode` `/model` `/clear` `/context` `/doctor` `/exit` `/demo`(動作デモ) `/tasks` `/task` `/projects`。`/tasks` などの TWP 系は `twp task list` と同じ結果を画面に出すだけで、AI は動かしません(クレジットも消費しません)。スラッシュコマンドは TUI の中だけで使えます(`twp -p` では解釈しません) |
|
|
26
28
|
| **できる** | 自分用のスラッシュコマンドを markdown で追加すること(`.twp/commands/*.md` / `~/.twp/commands/*.md`・[下記](#スラッシュコマンドを自分で足す))。入力中の `@パス` でファイルを、`#ABC-123` でタスクの内容を AI へ添付できます |
|
|
@@ -108,7 +110,7 @@ twp task label list [--project <コード>]
|
|
|
108
110
|
- **フラグの値は `--flag 値` でも `--flag=値` でも書けます。** 空白を含む値は `--keyword "山田 太郎"` のように引用し、`-` で始まる値は `--keyword=-foo` の形で渡します
|
|
109
111
|
- **質問(`--ask-question`)は質問文(`--question` / `--question-file`)と選択肢(`--option キー=表示文`・1〜5個)が要ります。** 選択肢のキーは10文字以内で、回答(`--select`)に使う識別子です。複数選択は `--multi-select`、自由記述を禁じるなら `--no-free-text`
|
|
110
112
|
- **`twp task comment list` の `question` / `answer` 列で、回答済みかどうかが分かります**(同じページにある回答を質問の行へ突き合わせます。ページをまたぐ場合は `--all` を付けてください)
|
|
111
|
-
- **`twp task attachment upload` はアップロード用URLの発行・ファイルの転送・タスクへの紐づけを1コマンドで行います。** 既にある添付は残したまま追加します。紐づけに失敗したときは添付IDを stderr に出して失敗で終わります(紐づけていない添付はサーバが自動で削除するので、そのまま再実行して構いません)。`--dry-run`
|
|
113
|
+
- **`twp task attachment upload` はアップロード用URLの発行・ファイルの転送・タスクへの紐づけを1コマンドで行います。** 既にある添付は残したまま追加します。紐づけに失敗したときは添付IDを stderr に出して失敗で終わります(紐づけていない添付はサーバが自動で削除するので、そのまま再実行して構いません)。`--dry-run` はURLの発行リクエストだけを表示します(その前に送る容量検査は注記で知らせます)
|
|
112
114
|
- `twp task attachment download` は `twp backlog attachment download` と同じく **`--out` のパスへ実体を書き出し、既存ファイルは `--force` を付けたときだけ上書きします**。添付ID は `twp task attachment list` の `id` です
|
|
113
115
|
- ヘルプは `twp task help` / `twp task comment help` / `twp task create help` / `twp task attachment help`
|
|
114
116
|
|
|
@@ -139,7 +141,145 @@ twp user assignment list <ユーザー> [--current] # 本人・上長・組織
|
|
|
139
141
|
- `twp user assignment list` の `is_primary` は主務、`is_approval_route` はワークフローの上長承認に使われる所属です。部署名・役職名を表示するため、部署一覧と役職一覧も取得します
|
|
140
142
|
- 権限が無いときは HTTP 403 をそのまま出さず、誰の権限が要るかを案内します(終了コードは 3)
|
|
141
143
|
- 組織管理者でなくても `twp user list` は使えます(表示フラグが付いたユーザーだけが出ます)
|
|
142
|
-
- ヘルプは `twp user help` / `twp user assignment help`
|
|
144
|
+
- ヘルプは `twp user help` / `twp user assignment help` / `twp user invite help`
|
|
145
|
+
|
|
146
|
+
### ユーザーを作成・更新する(入社・退社)
|
|
147
|
+
|
|
148
|
+
組織管理者向けです。
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
twp user create --name <氏名> --email <メールアドレス> --password-file <パス|->
|
|
152
|
+
[--role admin|user] [--kana <フリガナ>] [--hire-date <YYYY-MM-DD>] [--employee-code <社員番号>]
|
|
153
|
+
[--display true|false] [--memberlist true|false] [--org-chart true|false] [--dashboard true|false]
|
|
154
|
+
twp user update <ユーザー> [上と同じ項目] [--auth-type all|password|oauth|disabled]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **パスワードはコマンド行に置けません**(シェルの履歴とプロセス一覧に残るため)。`--password-file` にファイルのパスを渡すか、`-` を渡して標準入力から渡します。末尾の改行1つは取り除きます。8文字以上です
|
|
158
|
+
- `--role` を省くと一般ユーザー(`user`)で作成します。表示フラグを省くと、すべて表示する(`true`)で作成します。機能権限はテナントの既定で付与され、ライセンスの空きが足りない機能は付与されずに stderr へ出ます
|
|
159
|
+
- **`twp user update` は指定した項目だけを変更します**(指定しなかった項目は変わりません)。何も指定しないとエラーになります
|
|
160
|
+
- **表示フラグを外したユーザーは社員番号では指定できません**(メールアドレスか ID で指定してください)。作成・更新の直後に社員番号で指定するときは `--refresh` を付けます(ユーザー一覧は10分キャッシュします)
|
|
161
|
+
- メールアドレスが既に使われているなどでサーバが断ったときは、その理由を出して終了コード 3 で終わります
|
|
162
|
+
|
|
163
|
+
#### 退社したユーザーを失効させる
|
|
164
|
+
|
|
165
|
+
退社は専用のコマンドを持たず、画面と同じく**認証タイプを `disabled`(画面の「無効(ログイン不可)」)にして失効させます**。一覧・組織図などから外すなら、表示フラグも `false` にします。
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
twp user update yamada@example.com --auth-type disabled \
|
|
169
|
+
--display false --memberlist false --org-chart false --dashboard false
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
- 失効させたユーザーは新しくログインできず、発行済みのトークン・API キーもサーバが失効させます
|
|
173
|
+
- ユーザーは削除できません。失効させた状態で残ります
|
|
174
|
+
- **取り消す(再入社・誤操作)ときも同じ `twp user update` で戻します。** 失効前の認証タイプは記録されないので、**失効させる前に `twp user get <ユーザー>` の `auth_type` を控えておき**、その値へ戻してください(`all` はパスワードと OAuth の両方を許します。SSO だけのユーザーを `all` に戻すとパスワードでもログインできるようになります)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# 失効前の auth_type が all だった場合
|
|
178
|
+
twp user update yamada@example.com --auth-type all \
|
|
179
|
+
--display true --memberlist true --org-chart true --dashboard true
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- 失効かどうかは `twp user get <ユーザー>` の `auth_type` で確認できます。退職日・所属の終了・ライセンスの回収はこのコマンドでは行いません(所属の終了は `twp user assignment end`)
|
|
183
|
+
|
|
184
|
+
### 所属を付け替える(異動)・作成する・終了する
|
|
185
|
+
|
|
186
|
+
組織管理者向けです。
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
twp user assignment move <ユーザー> --department <部署> --start-date <異動日> [--position <役職>] [--manager <ユーザー>] …
|
|
190
|
+
twp user assignment create <ユーザー> --department <部署> --position <役職> --start-date <YYYY-MM-DD> [--primary true|false] …
|
|
191
|
+
twp user assignment update <所属ID> --user <ユーザー> [--manager <ユーザー> | --no-manager] [--end-date <YYYY-MM-DD|none>] …
|
|
192
|
+
twp user assignment end <所属ID> --user <ユーザー> --end-date <YYYY-MM-DD>
|
|
193
|
+
twp user assignment delete <所属ID> --user <ユーザー> --yes
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- **異動は `move` を使います。** 現在の主所属を異動日の前日で終え、異動日から新しい主所属を作ります。サーバへは1本の要求で送り、送る前に「終了する所属」と「作る所属」を並べて表示します。`--dry-run` を付ければ送らずに確認できます
|
|
197
|
+
- `move` は**役職と職位を現在の主所属から引き継ぎます**(`--position` / `--job-title` を指定すればそちらを使い、`--no-job-title` で職位を外します)。**上長・観察者・面談者・メンターは引き継ぎません**——旧上長のまま承認経路が残らないよう、新しい所属では指定したものだけが設定されます
|
|
198
|
+
- 異動日が未来なら新しい所属は予約になり、開始日の日次処理で切り替わります(それまでは現在の主所属が有効です)。今日以前ならすぐに切り替わります。月初を異動日にすると、現在の主所属は前月末で終わります
|
|
199
|
+
- 送信が途中で失敗したときは、所属を読み直して「どこまで反映されたか」と元に戻すコマンドを出します。成功したときも、取り消すためのコマンドを stderr に出します
|
|
200
|
+
- 主所属として作るとき(`move` と、`--primary false` でない `create`)は、次の場合に送らずに止めます: 開始日が現在の主所属の開始日以前(開始日より前に終わる所属になる)/予約済みの主所属が別にある(主所属が2つ重なる)。兼務・代理は `create --primary false --type concurrent|acting` で足します
|
|
201
|
+
- **`create` は `--primary` を省くと主所属として作ります**(サーバの既定と同じ)。主所属として作ると現在の主所属は開始日の前日で終わるので、兼務なら `--primary false` を付けてください
|
|
202
|
+
- 所属 ID は `twp user assignment list <ユーザー>` の `id` 列です。`update` / `end` / `delete` は、所属を持つユーザーを `--user` で必ず指定します
|
|
203
|
+
- 退職・異動で所属を終えるときは、履歴が残る `end` を使います。`delete` は誤って作った所属を消すためのものです
|
|
204
|
+
- `--department` / `--position` / `--job-title` は名前・コード・ID、`--manager` / `--interviewer` / `--mentor` / `--observer`(複数回指定できる)はユーザーを ID・メールアドレス・社員番号・氏名で指定できます
|
|
205
|
+
- CSV での一括異動は未対応です
|
|
206
|
+
|
|
207
|
+
### ユーザーを招待する
|
|
208
|
+
|
|
209
|
+
組織管理者向けです。招待されたメールアドレスへ招待メールが届き、本人が氏名とパスワードを入力して登録します。
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
twp user invite create --email <メールアドレス> [--role user|admin|super_admin] [--name <氏名>]
|
|
213
|
+
twp user invite bulk --file <CSV> # 1回 50 件まで
|
|
214
|
+
twp user invite list # 期限内の未受諾だけ
|
|
215
|
+
twp user invite resend <メールアドレス>
|
|
216
|
+
twp user invite delete <メールアドレス> --yes
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
一括招待の CSV は「メールアドレス, 権限」の2列です(1行目のヘッダ `email,role` は省略できます)。**氏名の列は置けません**——一括招待では氏名は送られず、受諾時に本人が入力します。
|
|
220
|
+
|
|
221
|
+
```csv
|
|
222
|
+
email,role
|
|
223
|
+
new.member@example.com,user
|
|
224
|
+
leader@example.com,admin
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
- **送る前に全行を検査し、形の誤り・権限の誤り・列数の誤り・重複がある行が1つでもあれば1通も送りません。**(重複を拒むのは、サーバが同じアドレスの招待を後の行で置き換え、先の招待リンクが黙って無効になるためです) その行番号と理由をすべて出して終了コード 2 で終わります(サーバは1行の誤りで全件を拒むため)。`--dry-run` で送る内容の一覧を確認できます
|
|
228
|
+
- 送った後にサーバが一部の行を断ったとき(既に使われているメールアドレス等)は、**失敗した行と送信済みの行を行番号つきで stderr に出して終了コード 3** で終わります。送信済みの行は取り消されないので、打ち直す CSV に含めないでください
|
|
229
|
+
- 招待の件数が多いと、一部はサーバの送信待ちの列に入ります(stderr で知らせます)。届かなければ `twp user invite resend` で再送できます
|
|
230
|
+
- `twp user invite list` に出るのは**期限内の未受諾の招待だけ**です。期限が切れた招待は再送も取消もできないので、`twp user invite create` で招待し直してください
|
|
231
|
+
- `resend` / `delete` はメールアドレスで指定します(未受諾の招待が1件に絞れたときだけ受け付けます)。トークンは招待を受諾できる秘密なので、`twp user invite list` では伏字で出ます(`--no-redact` で表示)
|
|
232
|
+
|
|
233
|
+
### 組織マスタ(部署・役職・職位)を扱う
|
|
234
|
+
|
|
235
|
+
作成・更新・削除は管理者向けです。一覧・取得・ツリー・所属者は、ログインしていれば使えます。
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
twp department list [--status active|inactive] [--keyword <語>] [--limit <件数>]
|
|
239
|
+
twp department tree # 現在有効な部署だけ
|
|
240
|
+
twp department members <部署> [--include-past]
|
|
241
|
+
twp department get <部署>
|
|
242
|
+
twp department create --code <コード> --name <部署名> [--parent <部署>] [--valid-from <YYYY-MM-DD>] [--valid-to <YYYY-MM-DD>] …
|
|
243
|
+
twp department update <部署> [--name <部署名>] [--parent <部署> | --no-parent] [--valid-to <YYYY-MM-DD|none>] …
|
|
244
|
+
twp department delete <部署> --yes
|
|
245
|
+
|
|
246
|
+
twp position list | get <役職> | create --code <コード> --name <役職名> [--rank <0〜9999>] [--manager true|false] … | update <役職> … | delete <役職> --yes
|
|
247
|
+
twp job-title list | get <職位> | create --code <コード> --name <職位名> [--position <役職>] … | update <職位> [--position <役職> | --no-position] … | delete <職位> --yes
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
- **`<部署>` / `<役職>` / `<職位>`、`--parent`、`--position` は名前・コード・ID のどれでも指定できます。** 名前が複数に一致すれば候補を出して止まります。一覧は10分キャッシュするので、作成・改名の直後に名前で指定するときは `--refresh` を付けてください(ID ならそのまま通ります)
|
|
251
|
+
- `update` は指定した項目だけを変更します。何も指定しないとエラーになります
|
|
252
|
+
- **部署の有効・無効は有効期間から決まります**(状態は直接指定できません)。`--valid-to` を設定するとその日の翌日から無効になり、`--valid-to none` で取り消すと有効に戻ります(有効開始日が未来なら、その日までは無効のままです)。`twp department list --status` は保存済みの状態で絞るため、境目の直後は1日ずれることがあります(実際の状態は `effective_status` 列)。役職・職位は `--status active|inactive` で切り替えます
|
|
253
|
+
- `twp department members` の行は所属(assignment)で、`user_id` が所属者です(氏名は `twp user get <user_id>` で確認できます)。既定は現在の所属だけで、`--include-past` を付けると現在でない所属(終了した所属と、開始日前の予約)も後ろに続けて出します。実際の状態は `effective_status` 列(`active` / `ended` / `scheduled`)で見てください
|
|
254
|
+
- `twp department tree` は現在有効な部署だけを親子の順に出します(table / text / tsv では `depth` と字下げした名前、`--output json` はサーバの木構造のまま)。無効な部署も含めた全件は `twp department list` です
|
|
255
|
+
- 一覧は API がページングを持たず、`--limit` 件(既定 1000)で打ち切ります。打ち切ったときは stderr で知らせます
|
|
256
|
+
- **所属者がいる(過去の所属履歴を含む)・子部署がある部署、所属から参照されている役職・職位は削除できません**(サーバが断ります)。そのときはサーバの理由に続けて、次に打つコマンドを案内します(部署は `--valid-to` で無効化、子部署は `--parent` で移す、役職・職位は `--status inactive` で無効化)。終了コードは 3 です
|
|
257
|
+
- ヘルプは `twp department help` / `twp position help` / `twp job-title help`
|
|
258
|
+
|
|
259
|
+
### メディアライブラリのファイルを扱う
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
twp media list [--project <コード|ID>] [--folder <フォルダID>] [--keyword <語>] [--all]
|
|
263
|
+
twp media upload --file <パス> [--project <コード|ID>] [--folder <フォルダID>] [--name <ファイル名>] [--content-type <型>]
|
|
264
|
+
twp media download <ファイルID> --out <パス> [--force]
|
|
265
|
+
twp media delete <ファイルID> --yes
|
|
266
|
+
twp media bulk-publish | bulk-unpublish | bulk-archive | bulk-restore <ファイルID>...
|
|
267
|
+
twp media bulk-move <ファイルID>... [--project <コード|ID>] [--folder <フォルダID>]
|
|
268
|
+
twp media bulk-delete <ファイルID>... --yes [--permanent]
|
|
269
|
+
twp media bulk-download <ファイルID>... --out <パス.zip> [--force]
|
|
270
|
+
twp storage get
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- **`--project` を付けたときだけプロジェクトのファイル**、無ければ自分の個人ファイルが対象です(`TWP_PROJECT` などの既定プロジェクトは使いません)。フォルダはフォルダID(UUID)で指定します
|
|
274
|
+
- **`twp media upload` はアップロード用URLの発行・ファイルの転送・完了登録を1コマンドで行い、サーバが計算した sha256 をローカルのファイルと突き合わせます。** 一致しなければ失敗で終わります。`--dry-run` はURLの発行リクエストだけを表示します(その前に送る容量検査は注記で知らせます)
|
|
275
|
+
- **転送や完了登録に失敗したときは、ファイルIDと再登録・破棄のコマンドを stderr に出して失敗で終わります。** タスク添付と違い、URLを発行した時点でファイルが仮登録され**自動では消えない**ので、表示されたコマンドのどちらかを実行してください
|
|
276
|
+
- `twp media delete` はゴミ箱へ移すだけで、画面から復元できます
|
|
277
|
+
- **アップロードの前に、テナントのストレージ容量を確かめます**(`twp task attachment upload` も同じ)。容量を超えるなら何も登録せず終了コード 3 で止まり、警告の閾値を超えているときは stderr で知らせます
|
|
278
|
+
- **一括操作(`bulk-*`)は1件でも失敗すると終了コード 3 で終わり、失敗したファイルと理由・適用済みのファイルを stderr に出します**(サーバは失敗があっても HTTP 200 を返すため)。`bulk-publish` / `bulk-unpublish` / `bulk-archive` は存在しないファイルIDが1件でもあると他も適用しません。`bulk-restore` / `bulk-move` / `bulk-delete` は1件ずつ処理するので、失敗したもの以外は適用されます。`bulk-download` は ZIP に入った件数が指定より少なければ書き出さずに終了コード 3 で終わります。件数は 100 件まで(`bulk-download` は 50 件)
|
|
279
|
+
- `bulk-restore` はゴミ箱から戻す操作です(アーカイブの解除ではありません)。`bulk-delete --permanent` は**ゴミ箱にあるファイルだけ**を完全に削除します(先に `bulk-delete` でゴミ箱へ移してください)
|
|
280
|
+
- `twp storage get` は使用量・上限・残量と種類別の内訳を出します(管理者のみ。アップロード前の容量検査は誰でも自動で行われます)
|
|
281
|
+
- コマンド名は `twp task attachment` と同じ動詞(`upload` / `list` / `download`)に揃えています(`twp://` 形式のパスは採っていません)
|
|
282
|
+
- ヘルプは `twp media help`
|
|
143
283
|
|
|
144
284
|
### Backlog の課題を読む・書く
|
|
145
285
|
|
|
@@ -389,14 +529,14 @@ mode: dev
|
|
|
389
529
|
"permissions": {
|
|
390
530
|
"allow": ["Bash(git status:*)", "Bash(npm test)", "Write(src/**)", "git(log:*)"],
|
|
391
531
|
"ask": ["Bash(git push:*)"],
|
|
392
|
-
"deny": ["Bash(rm:*)", "
|
|
532
|
+
"deny": ["Bash(rm:*)", "twp_delete_project-task"]
|
|
393
533
|
}
|
|
394
534
|
}
|
|
395
535
|
```
|
|
396
536
|
|
|
397
537
|
| 書き方 | 意味 |
|
|
398
538
|
|---|---|
|
|
399
|
-
| `Bash` / `
|
|
539
|
+
| `Bash` / `twp_update_project-task` | そのツール全体 |
|
|
400
540
|
| `Bash(git status:*)` | `git status` で始まるコマンド(語の区切りで一致) |
|
|
401
541
|
| `Bash(npm test)` | そのコマンドと完全一致 |
|
|
402
542
|
| `Write(src/**)` / `Edit(src/*.ts)` / `Read(~/notes/**)` | パスの glob(素の相対と `/` 始まりは作業ディレクトリ基準・`//` 始まりは絶対パス・`~/` はホーム)。`Edit` は `write_file` も含む |
|
|
@@ -414,7 +554,8 @@ mode: dev
|
|
|
414
554
|
- **拒否ルールは「よくある書き方を止める網」であって、書いたコマンドを確実に止める境界ではない。** `sudo rm` `/bin/rm` `then rm` `$(rm …)` のような書き方には当たるが、`find -exec rm` のように引数の中から起動するものは拾えない。確実に止めたいならツールごと拒否する(`Bash`)か、業務・プランモードを使う
|
|
415
555
|
- `Read(...)` の拒否は `grep` / `glob` にも効くが、**探索の起点がその範囲の中にあるときだけ**(リポジトリ全体を起点にした `grep` は、拒否した範囲の中まで読む)。確実に読ませないなら `Read` ごと拒否するか業務・プランモードを使う
|
|
416
556
|
- 設定ファイルが読めない間は、読み取りも含めて**すべての自動許可が確認に変わる**(`-p` では確認できないので拒否になる)
|
|
417
|
-
- `twp_call
|
|
557
|
+
- `twp_call`(ツールを名前で呼ぶメタツール)は**中で実行されるツールの名前**(例: `twp_list_project-task`)で判定する。`twp_call` そのものを許可しても何も緩まない。TWP API のツールは読み取りも含めて既定で確認が出る(`-p` では拒否になる)ので、確認なしで使わせたいツールは名前で許可する(例: `--allowed-tools twp_list_project-task`)。**削除系(`destructive`)は許可ルールがあっても毎回確認する**
|
|
558
|
+
- モデルが TWP を調べる手順は `twp_search_tools`(名前と1行説明だけ)→ `twp_describe_tools`(スキーマ)→ `twp_call`(実行)。カタログはパッケージ同梱のコマンドモデルで、ネットワークに取りに行かない。同じドメインを続けて使うときは `twp_mount` で次のターンから常駐させられる
|
|
418
559
|
|
|
419
560
|
### 承認画面
|
|
420
561
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{failureHint,isAuthError,isCliFatalText,isRateLimited,isServerAiType,isUntrusted,maxTurnsReached,rateLimitWaitSeconds,tailForScan}from"./chunk-ZOOEH7ZE.js";import{detectAiClis}from"./chunk-24ZZFFA3.js";import{DEFAULT_CLAUDE_LAUNCHER,activeSlotPath,detectClaudeAutoSwitch,isClaudeAi,isUsableModelId,modelFitsRoute,resolveSpawnTarget,usesBedrock,wrapWithAutoSwitch}from"./chunk-TYNCXQSN.js";import{
|
|
3
|
+
import{failureHint,isAuthError,isCliFatalText,isRateLimited,isServerAiType,isUntrusted,maxTurnsReached,rateLimitWaitSeconds,tailForScan}from"./chunk-ZOOEH7ZE.js";import{detectAiClis}from"./chunk-24ZZFFA3.js";import{isForceOnly,killProcessTree,system32}from"./chunk-N2UVRM3Z.js";import{DEFAULT_CLAUDE_LAUNCHER,activeSlotPath,detectClaudeAutoSwitch,isClaudeAi,isUsableModelId,modelFitsRoute,resolveSpawnTarget,usesBedrock,wrapWithAutoSwitch}from"./chunk-TYNCXQSN.js";import{findExecutable,
|
|
4
4
|
isWindowsDriveAbsolute}from"./chunk-PMOUHEJQ.js";import"./chunk-5WGOHFAS.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import{spawnSync}from"child_process";import fs2 from"fs";import path2 from"path";import{spawn}from"child_process";import fs from"fs";import path from"path";var FINAL_REPORT_BEGIN="<<<AI_FINAL_REPORT>>>";var FINAL_REPORT_END="<<<END_AI_FINAL_REPORT>>>";var ClaudeStreamRenderer=class{constructor(now=()=>new Date){this.now=now}now;toolNames=new Map;toolCount=0;result={subtype:null,isError:null,numTurns:null,costUsd:null,durationMs:null,tokensIn:null,tokensOut:null,rateLimited:false,resetsAt:null,finalText:""};push(line){const trimmed=line.trim();if(trimmed==="")return[];let event;try{const parsed=JSON.parse(trimmed);if(parsed===null||typeof parsed!=="\
|
|
5
5
|
object"||Array.isArray(parsed)){return[line]}event=parsed}catch{return[line]}switch(event["type"]){case"rate_limit_event":return this.onRateLimit(event);case"assistant":return this.onAssistant(event);case"user":return this.onUser(event);case"result":return this.onResult(event);default:return event["type"]==="system"?[]:[line]}}sawRateLimit(){return this.result.rateLimited}lastRateLimitNote="";onRateLimit(event){const info=event["rate_limit_info"];if(info===null||typeof info!=="object")return[];const rec=info;
|
|
6
6
|
const status=typeof rec["status"]==="string"?rec["status"]:"";const resets=typeof rec["resetsAt"]==="number"?rec["resetsAt"]:null;if(status==="")return[];const at=isSaneEpochSec(resets)?` resets=${new Date(resets*1e3).toISOString()}`:"";if(status.startsWith("allowed")){if(status==="allowed")return[];const seen=`${status}|${resets??""}`;if(seen===this.lastRateLimitNote)return[];this.lastRateLimitNote=seen;return[this.line(`\u2139\uFE0F \u4E0A\u9650\u306B\u63A5\u8FD1\uFF08status=${status}${at}\uFF09\u2014 \u5B9F\
|
|
@@ -1,26 +1,14 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
\u958B\u767A\u6642\u306F \`npm run generate:command-model -- --spec <api.json>\` \u3067\u751F\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);this.name="CommandModelMissingError"}};var domainCache=new Map;var routesCache=null;async function readJson(file){const dir=commandModelDir();if(dir===null)throw new CommandModelMissingError("\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u3042\u308A\u307E\u305B\u3093");const path=join(dir,file);try{return JSON.parse(await readFile(path,"utf8"))}catch(cause){throw new CommandModelMissingError(`${path} \u3092\u8AAD\u3081\u307E\u305B\u3093\uFF08${cause.message}\uFF09`)}}async function loadCommandModelRoutes(){if(routesCache!==null)return routesCache;const file=await readJson("_routes.json");if(typeof file?.routes!=="object"||file.routes===null||Array.isArray(file.routes)){throw new CommandModelMissingError("_routes.json \u306E\u5F62\u304C\u9055\u3044\u307E\u3059\uFF08routes \u304C\u8AAD\u3081\u307E\u305B\u3093\uFF09")}routesCache=file;return routesCache}async function loadCommandModelDomain(domain){const cached=domainCache.get(domain);if(cached!==void 0)return cached;
|
|
8
|
-
if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(domain)){throw new CommandModelMissingError(`\u30C9\u30E1\u30A4\u30F3\u540D\u3068\u3057\u3066\u4E0D\u6B63\u3067\u3059: ${domain}`)}const file=await readJson(`${domain}.json`);if(typeof file?.domain!=="string"||!Array.isArray(file?.operations)){throw new CommandModelMissingError(`${domain}.json \u306E\u5F62\u304C\u9055\u3044\u307E\u3059\uFF08domain / operations \u304C\u8AAD\u3081\u307E\u305B\u3093\uFF09`)}domainCache.set(domain,file);return file}var MIN_SEGMENT_CHARS=3;var parsedCache=new WeakMap;function splitSegments(path){return path.split("/").filter(segment=>segment!=="")}function parseRoutes(routes){const cached=parsedCache.get(routes);if(cached!==void 0)return cached;const parsed=[];for(const[key,domain]of Object.entries(routes.routes)){const space=key.indexOf(" ");if(space<=0)continue;const template=key.slice(space+1);parsed.push({method:key.slice(0,space),template,domain,segments:splitSegments(template).map(segment=>/^\{[^/{}]+\}$/.
|
|
3
|
+
import{CommandModelMissingError,MAX_REPORTED_VIOLATIONS,loadCommandModelDomain,loadCommandModelRoutes,validateBody,validateQuery}from"./chunk-NZ7WI4RZ.js";import{NO_REDACT_FLAG,NO_REDACT_NOTICE,exitCodeFor,fetchAllPages,reportError}from"./chunk-6NCY4NPV.js";import{parseOperationArgs,repeatedValues}from"./chunk-IOGVQVGD.js";import{renderOutput}from"./chunk-5Q2CH4E7.js";import{redactSecretValues,withDebug}from"./chunk-YVAN3H5W.js";import{readBody}from"./chunk-HGTG5XQ7.js";
|
|
4
|
+
import"./chunk-QOUFHYK5.js";import"./chunk-II5RVJQN.js";import{ApiError,TwpApiClient,appendQuery}from"./chunk-FTYJZFEK.js";import{DEFAULT_MAX_ITEMS,DEFAULT_MAX_PAGES,envelopePaging,positiveInteger,readEnvelopeCursor,shellQuote}from"./chunk-DMDVLOAY.js";import"./chunk-GMBJTG6A.js";import{GLOBAL_OPTIONS_HELP}from"./chunk-TAN5I2DP.js";import{HELP_TOKEN}from"./chunk-EJ474UDB.js";import"./chunk-QQRJLH6B.js";import{AuthSession,NotLoggedInError,SessionExpiredError,
|
|
5
|
+
loadCredentials}from"./chunk-XNLIEUAW.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import{effectiveApiUrl,resolveConfiguredOutput,resolveProfile}from"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";import{OUTPUT_FORMATS,resolveOutputFormat}from"./chunk-K2ONOH3L.js";import"./chunk-WVS4W5FY.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import{evaluateQuery}from"./chunk-GDM2QUBL.js";import{EXIT_OK,NetworkError,UsageError}from"./chunk-7WSNIXTQ.js";
|
|
6
|
+
import"./chunk-VSJBJXZO.js";var MIN_SEGMENT_CHARS=3;var parsedCache=new WeakMap;function splitSegments(path){return path.split("/").filter(segment=>segment!=="")}function parseRoutes(routes){const cached=parsedCache.get(routes);if(cached!==void 0)return cached;const parsed=[];for(const[key,domain]of Object.entries(routes.routes)){const space=key.indexOf(" ");if(space<=0)continue;const template=key.slice(space+1);parsed.push({method:key.slice(0,space),template,domain,segments:splitSegments(template).map(segment=>/^\{[^/{}]+\}$/.
|
|
9
7
|
test(segment)?null:segment)})}parsedCache.set(routes,parsed);return parsed}function matches(route,segments){if(route.segments.length!==segments.length)return false;return route.segments.every((literal,i)=>literal===null||literal===segments[i])}function compareSpecificity(a,b){const literals=route=>route.segments.filter(segment=>segment!==null).length;const diff=literals(b)-literals(a);if(diff!==0)return diff;for(let i=0;i<a.segments.length;i+=1){const aLiteral=a.segments[i]!==null;const bLiteral=b.
|
|
10
8
|
segments[i]!==null;if(aLiteral!==bLiteral)return aLiteral?-1:1}return 0}function lookupRoute(routes,method,path){const segments=splitSegments(path);const hits=parseRoutes(routes).filter(route=>matches(route,segments));const sameMethod=hits.filter(route=>route.method===method).sort(compareSpecificity);const best=sameMethod[0];if(best!==void 0)return{kind:"matched",domain:best.domain,template:best.template};if(hits.length>0){const[top]=[...hits].sort(compareSpecificity);const template=top.template;
|
|
11
9
|
const methods=[...new Set(hits.filter(route=>route.template===template).map(route=>route.method))].sort();return{kind:"method-mismatch",template,methods}}return{kind:"unknown"}}function pickOperation(operations,method,template){return operations.find(op=>op.method===method&&op.path===template)??null}async function suggestRoutes(routes,path,limit=5){const{default:fuzzysort}=await import("./fuzzysort-DFVKV4B4.js");const parsed=parseRoutes(routes);const templates=[...new Set(parsed.map(route=>route.
|
|
12
10
|
template))];const literals=new Set(parsed.flatMap(route=>route.segments.filter(segment=>segment!==null)));const kept=splitSegments(path).filter(segment=>literals.has(segment)||!/\d/.test(segment));for(let length=kept.length;length>=2;length-=1){const head=kept.slice(0,length-1);const last=kept[length-1];for(let cut=last.length;cut>=Math.min(MIN_SEGMENT_CHARS,last.length);cut-=1){const results=fuzzysort.go(`/${[...head,last.slice(0,cut)].join("/")}`,templates,{limit});if(results.length>0)return results.
|
|
13
|
-
map(result=>result.target)}}return[]}var
|
|
14
|
-
null":return value===null;case"string":return typeof value==="string";case"integer":return typeof value==="number"&&Number.isInteger(value)||typeof value==="string"&&INTEGER_STRING.test(value);case"number":return typeof value==="number"&&Number.isFinite(value)||typeof value==="string"&&NUMBER_STRING.test(value);case"boolean":return typeof value==="boolean"||value===0||value===1||typeof value==="string"&&BOOLEAN_STRINGS.has(value.toLowerCase());case"array":case"object":return typeof value==="obje\
|
|
15
|
-
ct"&&value!==null;default:return true}}function describe(value){if(value===null)return"null";if(Array.isArray(value))return"\u914D\u5217";if(typeof value==="object")return"\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8";if(typeof value==="string")return`\u6587\u5B57\u5217\uFF08${[...value].length} \u6587\u5B57\uFF09`;return`${typeof value==="number"?"\u6570\u5024":typeof value==="boolean"?"\u771F\u507D\u5024":typeof value} ${String(value)}`}function numericValue(value){if(typeof value==="number")return value;
|
|
16
|
-
if(typeof value==="string"&&NUMBER_STRING.test(value))return Number(value);return null}var PHP_DELIMITED=/^([^A-Za-z0-9\\\s^])[\s\S]*\1[A-Za-z]*$/;function compilePattern(pattern){if(PHP_DELIMITED.test(pattern))return null;try{return new RegExp(pattern,"u")}catch{return null}}function walk(schema,value,at,out){if(!isRecord(schema))return;const types=typesOf(schema);if(types!==null&&!types.some(type=>matchesType(type,value))){out.push(`${at}: ${types.join(" / ")} \u3092\u671F\u5F85\u3057\u307E\u3057\u305F\u304C ${describe(
|
|
17
|
-
value)} \u3067\u3059`);return}if(value===null)return;const enumValues=schema["enum"];if(Array.isArray(enumValues)&&enumValues.length>0){const allowed=enumValues.filter(item=>item!==null).map(item=>String(item));if(!allowed.includes(String(value))){out.push(`${at}: ${allowed.join(" / ")} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u53D7\u3051\u53D6\u3063\u305F\u5024: ${describe(value)}\uFF09`)}}if(typeof value==="string"){const length=[...value].length;
|
|
18
|
-
const max=schema["maxLength"];const min=schema["minLength"];if(typeof max==="number"&&length>max)out.push(`${at}: ${max} \u6587\u5B57\u4EE5\u5185\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${length} \u6587\u5B57\uFF09`);if(typeof min==="number"&&length<min)out.push(`${at}: ${min} \u6587\u5B57\u4EE5\u4E0A\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${length} \u6587\u5B57\uFF09`);const pattern=schema["pattern"];if(typeof pattern==="string"){const re=compilePattern(pattern);if(re!==null&&!re.
|
|
19
|
-
test(value))out.push(`${at}: \u5F62\u5F0F\u304C\u9055\u3044\u307E\u3059\uFF08${pattern}\uFF09`)}}const numeric=types?.some(type=>type==="integer"||type==="number")?numericValue(value):null;if(numeric!==null){const minimum=schema["minimum"];const maximum=schema["maximum"];if(typeof minimum==="number"&&numeric<minimum)out.push(`${at}: ${minimum} \u4EE5\u4E0A\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${numeric}\uFF09`);if(typeof maximum==="number"&&numeric>maximum)out.push(`${at}: ${maximum} \u4EE5\
|
|
20
|
-
\u4E0B\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${numeric}\uFF09`)}if(Array.isArray(value)){const maxItems=schema["maxItems"];const minItems=schema["minItems"];if(typeof maxItems==="number"&&value.length>maxItems)out.push(`${at}: \u8981\u7D20\u306F ${maxItems} \u4EF6\u4EE5\u5185\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${value.length} \u4EF6\uFF09`);if(typeof minItems==="number"&&value.length<minItems)out.push(`${at}: \u8981\u7D20\u306F ${minItems} \u4EF6\u4EE5\u4E0A\u306B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08${value.
|
|
21
|
-
length} \u4EF6\uFF09`);if(isRecord(schema["items"]))value.forEach((item,i)=>walk(schema["items"],item,`${at}[${i}]`,out));return}if(isRecord(value)){const required=schema["required"];if(Array.isArray(required)){for(const key of required){if(typeof key==="string"&&!Object.prototype.hasOwnProperty.call(value,key))out.push(`${at}.${key}: \u5FC5\u9808\u3067\u3059`)}}const properties=schema["properties"];if(isRecord(properties)){for(const[key,child]of Object.entries(properties)){if(Object.prototype.hasOwnProperty.
|
|
22
|
-
call(value,key))walk(child,value[key],`${at}.${key}`,out)}}}}function validateBody(schema,body){const out=[];walk(schema,body,"body",out);return out}function validateQuery(params,query){const out=[];for(const param of params){const has=Object.prototype.hasOwnProperty.call(query,param.name)&&query[param.name]!==void 0;if(!has){if(param.required)out.push(`query.${param.name}: \u5FC5\u9808\u3067\u3059`);continue}if(param.source!=="spec")continue;const declared=param.type;const types=typeof declared===
|
|
23
|
-
"string"?[declared]:Array.isArray(declared)?declared.filter(t=>typeof t==="string"):[];const checked=types.filter(type=>type==="integer"||type==="number"||type==="boolean");if(checked.length===0||types.includes("string"))continue;const raw=query[param.name];if(types.includes("null")&&raw==="")continue;if(!checked.some(type=>matchesType(type,raw))){out.push(`query.${param.name}: ${checked.join(" / ")} \u3092\u671F\u5F85\u3057\u307E\u3057\u305F\u304C ${describe(raw)} \u3067\u3059`)}}return out}var API_COMMAND_HELP=`twp api \u2014 API \u306E\u30D1\u30B9\u3092\u76F4\u63A5\u53E9\u304F\uFF08\u30A8\u30B9\u30B1\u30FC\u30D7\u30CF\u30C3\u30C1\uFF09
|
|
11
|
+
map(result=>result.target)}}return[]}var API_COMMAND_HELP=`twp api \u2014 API \u306E\u30D1\u30B9\u3092\u76F4\u63A5\u53E9\u304F\uFF08\u30A8\u30B9\u30B1\u30FC\u30D7\u30CF\u30C3\u30C1\uFF09
|
|
24
12
|
|
|
25
13
|
\u4F7F\u3044\u65B9:
|
|
26
14
|
twp api <\u30D1\u30B9> [\u30AA\u30D7\u30B7\u30E7\u30F3]
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{buildDiffLines,diffStat}from"./chunk-VRBI2NPI.js";import{RESIDENT_TOKEN_CAP,activateModeFiles,activatePermissionSettings,buildResidentSet,buildSystemPrompt,createAuditLogger,currentBranch,describeAuditLog,displayCwd,executeTool,findProjectTwpSubdir,localTools,lstatOrNull,parseFrontMatter,parseRule,persistProjectAllow,projectPermissionsPath,projectRootFor,readFileTool,resolveGitExecutable,runTurn,secretReason}from"./chunk-
|
|
4
|
-
import
|
|
5
|
-
|
|
3
|
+
import{buildDiffLines,diffStat}from"./chunk-VRBI2NPI.js";import{RESIDENT_TOKEN_CAP,activateModeFiles,activatePermissionSettings,buildResidentSet,buildSystemPrompt,createAuditLogger,createTwpToolkit,currentBranch,describeAuditLog,displayCwd,executeTool,findProjectTwpSubdir,localTools,lstatOrNull,parseFrontMatter,parseRule,persistProjectAllow,projectPermissionsPath,projectRootFor,readFileTool,residentInputs,resolveGitExecutable,runTurn,secretReason}from"./chunk-4V4T5ZUS.js";import"./chunk-NZ7WI4RZ.js";
|
|
4
|
+
import"./chunk-N2UVRM3Z.js";import"./chunk-YVAN3H5W.js";import"./chunk-QOUFHYK5.js";import"./chunk-II5RVJQN.js";import"./chunk-FTYJZFEK.js";import"./chunk-GMBJTG6A.js";import{parseArgv}from"./chunk-HW3QGKYR.js";import{applyPermissionMode,checkPermission,describePermissionMode,getMode,isModeId,modeSource,nextMode}from"./chunk-NAUH75MM.js";import"./chunk-EJ474UDB.js";import"./chunk-QQRJLH6B.js";import{RelayError,builtinCatalog,createRuntime,
|
|
5
|
+
loadCachedCatalog,modelLabel,pickModel,toModelInfos}from"./chunk-WOUKWOAR.js";import"./chunk-XNLIEUAW.js";import"./chunk-PMOUHEJQ.js";import{proxyDiagnostics}from"./chunk-J7QYPKVK.js";import{checkMinSupportedVersion,isBelowMinSupported,minSupportedBlockMessage}from"./chunk-DXXFUNYN.js";import"./chunk-NERYSBA4.js";import{configReadDirs,twpHomeDir}from"./chunk-RZVI6PMW.js";import{require_fuzzysort}from"./chunk-DIMZRTLE.js";import{isFullWidth,isWide,stringWidth,
|
|
6
|
+
stripAnsi}from"./chunk-WVS4W5FY.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-7WSNIXTQ.js";import{__commonJS,__export,__require,__toESM}from"./chunk-VSJBJXZO.js";var require_react_production=__commonJS({"node_modules/react/cjs/react.production.js"(exports){"use strict";var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element");var REACT_PORTAL_TYPE=Symbol.for("react.portal");var REACT_FRAGMENT_TYPE=Symbol.for("react.fragment");var REACT_STRICT_MODE_TYPE=Symbol.for("react.strict_mode");var REACT_PROFILER_TYPE=Symbol.for("react.profiler");var REACT_CONSUMER_TYPE=Symbol.for("react.consumer");var REACT_CONTEXT_TYPE=Symbol.for("react.context");var REACT_FORWARD_REF_TYPE=Symbol.
|
|
6
7
|
for("react.forward_ref");var REACT_SUSPENSE_TYPE=Symbol.for("react.suspense");var REACT_MEMO_TYPE=Symbol.for("react.memo");var REACT_LAZY_TYPE=Symbol.for("react.lazy");var REACT_ACTIVITY_TYPE=Symbol.for("react.activity");var REACT_VIEW_TRANSITION_TYPE=Symbol.for("react.view_transition");var MAYBE_ITERATOR_SYMBOL=Symbol.iterator;function getIteratorFn(maybeIterable){if(null===maybeIterable||"object"!==typeof maybeIterable)return null;maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||
|
|
7
8
|
maybeIterable["@@iterator"];return"function"===typeof maybeIterable?maybeIterable:null}var ReactNoopUpdateQueue={isMounted:function(){return false},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};var assign=Object.assign;var emptyObject={};function Component(props,context,updater){this.props=props;this.context=context;this.refs=emptyObject;this.updater=updater||ReactNoopUpdateQueue}Component.prototype.isReactComponent={};Component.prototype.setState=
|
|
8
9
|
function(partialState,callback){if("object"!==typeof partialState&&"function"!==typeof partialState&&null!=partialState)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,partialState,callback,"setState")};Component.prototype.forceUpdate=function(callback){this.updater.enqueueForceUpdate(this,callback,"forceUpdate")};function ComponentDummy(){}ComponentDummy.prototype=Component.prototype;function PureComponent2(props,context,updater){
|
|
@@ -1211,7 +1212,7 @@ cwd()){const listed=await gitListFiles(cwd2);const raw=listed??await walkFiles(c
|
|
|
1211
1212
|
1;const after=/^[^\s]*/.exec(text.slice(cursor))?.[0]??"";return{query,start,end:cursor+after.length}}var TWP_SLASH_ROUTES={"/tasks":{domain:"task",operation:"list"},"/task":{domain:"task",operation:"get"},"/projects":{domain:"project",operation:"list"}};function isTwpSlashCommand(name){return Object.hasOwn(TWP_SLASH_ROUTES,name)}async function runTwpSlashCommand(name,args,deps){const route=TWP_SLASH_ROUTES[name];if(!Object.hasOwn(TWP_SLASH_ROUTES,name)||route===void 0){return{code:2,out:"",err:`\u4E0D\u660E\u306A\u30B3\u30DE\u30F3\u30C9: ${name}
|
|
1212
1213
|
`}}const parsed=parseArgv([route.domain,route.operation,...args]);if(parsed.command!=="domain"||parsed.domain!==route.domain){return{code:2,out:"",err:`${name}: \u3053\u306E\u5F15\u6570\u306F\u4F7F\u3048\u307E\u305B\u3093\uFF08${args.join(" ")}\uFF09
|
|
1213
1214
|
`}}if(parsed.unknown.length>0){return{code:2,out:"",err:`\u4E0D\u660E\u306A\u5F15\u6570: ${parsed.unknown.join(" ")}
|
|
1214
|
-
`}}let out="";let err="";const io={out:text=>void(out+=text),err:text=>void(err+=text),isTty:true};const globals={profile:parsed.profile??deps.profile,...parsed.output!==void 0?{output:parsed.output}:{},...parsed.query!==void 0?{query:parsed.query}:{},dryRun:parsed.dryRun,debug:parsed.debug,yes:parsed.yes,refresh:parsed.refresh};const{runDomain}=await import("./run-
|
|
1215
|
+
`}}let out="";let err="";const io={out:text=>void(out+=text),err:text=>void(err+=text),isTty:true};const globals={profile:parsed.profile??deps.profile,...parsed.output!==void 0?{output:parsed.output}:{},...parsed.query!==void 0?{query:parsed.query}:{},dryRun:parsed.dryRun,debug:parsed.debug,yes:parsed.yes,refresh:parsed.refresh};const{runDomain}=await import("./run-QCDT35NT.js");try{const code=await runDomain({domain:route.domain,...parsed.operation!==void 0?{operation:parsed.operation}:
|
|
1215
1216
|
{},argv:parsed.domainArgv,help:parsed.domainHelp,globals,version:deps.version,io,...deps.fetchImpl!==void 0?{fetchImpl:deps.fetchImpl}:{}});return{code,out,err}}catch(e){return{code:1,out,err:`${err}${e.message}
|
|
1216
1217
|
`}}}var GIT_LOG_OUTPUT=["9f3c1a2 feat(ui): \u4E00\u89A7\u306E\u30D5\u30A3\u30EB\u30BF\u3092 URL \u30AF\u30A8\u30EA\u3068\u540C\u671F\u3059\u308B","4b8e0d7 fix(ui): \u4EEE\u60F3\u30B9\u30AF\u30ED\u30FC\u30EB\u306E\u884C\u9AD8\u3055\u3092\u5B9F\u6E2C\u5024\u306B\u5408\u308F\u305B\u308B","c15a99e refactor(api): \u4E00\u89A7\u53D6\u5F97\u306E\u30DA\u30FC\u30B8\u30F3\u30B0\u51E6\u7406\u3092\u5171\u901A\u5316\u3059\u308B","2d70f4b test: \u4E00\u89A7\u30D5\u30A3\u30EB\u30BF\u306E\u56DE\u5E30\u30C6\u30B9\u30C8\u3092\u8FFD\u52A0\u3059\u308B",
|
|
1217
1218
|
"a6e2b38 fix(api): \u7A7A\u306E\u691C\u7D22\u6761\u4EF6\u3067\u5168\u4EF6\u8FD4\u3089\u306A\u3044\u3088\u3046\u306B\u3059\u308B","7c40d51 chore(deps): \u958B\u767A\u4F9D\u5B58\u3092\u6700\u65B0\u3078\u66F4\u65B0\u3059\u308B","e83b1c6 docs: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806\u306B Node 22 \u306E\u524D\u63D0\u3092\u8FFD\u8A18\u3059\u308B","b91f7a4 fix(ui): \u30E2\u30FC\u30C0\u30EB\u306E\u91CD\u306A\u308A\u9806\u3092\u6307\u5B9A\u3059\u308B","5a2c8e0 perf(api): \u4E00\u89A7\u306E N+1 \u3092\u89E3\u6D88\u3059\u308B",
|
|
@@ -1289,25 +1290,25 @@ const bufferRef=(0,import_react38.useRef)({text:"",cursor:0});const[buffer,setBu
|
|
|
1289
1290
|
null);const[overlay,setOverlay]=(0,import_react38.useState)(startInDoctor?"doctor":"none");const[pendingPermission,setPendingPermissionState]=(0,import_react38.useState)(null);const pendingPermissionRef=(0,import_react38.useRef)(null);const setPendingPermission=(0,import_react38.useCallback)(next=>{pendingPermissionRef.current=next;setPendingPermissionState(next)},[]);const[keyLog,setKeyLog]=(0,import_react38.useState)([]);const[ctrlCArmed,setCtrlCArmed]=(0,import_react38.useState)(false);const[
|
|
1290
1291
|
pasting,setPasting]=(0,import_react38.useState)(false);const[fileIndex,setFileIndex]=(0,import_react38.useState)(null);const fileIndexRef=(0,import_react38.useRef)(null);fileIndexRef.current=fileIndex;const fileIndexLoading=(0,import_react38.useRef)(false);const setBuffer=(0,import_react38.useCallback)(fn=>{bufferRef.current=fn(bufferRef.current);setBufferState(bufferRef.current)},[]);const clearBuffer=(0,import_react38.useCallback)(()=>setBuffer(()=>({text:"",cursor:0})),[setBuffer]);const selectedRef=(0,import_react38.useRef)(
|
|
1291
1292
|
0);const[selectedState,setSelectedState]=(0,import_react38.useState)(0);const setSelected=(0,import_react38.useCallback)(next=>{selectedRef.current=typeof next==="function"?next(selectedRef.current):next;setSelectedState(selectedRef.current)},[]);const modeRef=(0,import_react38.useRef)(mode);modeRef.current=mode;const modelRef=(0,import_react38.useRef)(model);modelRef.current=model;const busyRef=(0,import_react38.useRef)(false);const abortRef=(0,import_react38.useRef)(false);const streamAbortRef=(0,import_react38.useRef)(
|
|
1292
|
-
null);const sleepRef=(0,import_react38.useRef)(null);const permissionResolver=(0,import_react38.useRef)(null);const permStateRef=(0,import_react38.useRef)(INITIAL_DIALOG_STATE);const[permState,setPermStateRaw]=(0,import_react38.useState)(INITIAL_DIALOG_STATE);const setPermState=(0,import_react38.useCallback)(next=>{permStateRef.current=next;setPermStateRaw(next)},[]);const sessionAllow=(0,import_react38.useRef)(new Set);const
|
|
1293
|
-
new Set);const lastToolRef=(0,import_react38.useRef)(null);(0,import_react38.useEffect)(()=>()=>{abortRef.current=true;streamAbortRef.current?.abort();const s=sleepRef.current;if(s){clearTimeout(s.timer);sleepRef.current=null;s.resolve()}},[]);const modeDef=getMode(mode);const branch=(0,import_react38.useMemo)(()=>currentBranch(),[]);const cwd2=(0,import_react38.useMemo)(
|
|
1294
|
-
1:0)+(pasting?1:0)+1+1;const liveTotal=Math.max(MIN_LIVE_ROWS,size.rows-1);const inputContentWidth=Math.max(1,size.columns-6);const inputMaxRows=Math.max(1,Math.min(6,liveTotal-fixedChrome-1));const inputWindow=layoutInputWindow(buffer.text,buffer.cursor,inputContentWidth,inputMaxRows);const budget=liveAreaBudget(size.rows,fixedChrome+inputWindow.shownRows);const commit=(0,import_react38.useCallback)(
|
|
1295
|
-
null);const blockOnMinSupported=(0,import_react38.useCallback)(floor=>{const text=minSupportedBlockMessage(version,floor??"");commit({kind:"notice",tone:"error",text});process.exitCode=1;exit();process.stderr.write(stripTerminalControls(text))},[commit,exit,version]);(0,import_react38.useEffect)(()=>{if(!runtime.loggedIn){commit({kind:"notice",tone:"warn",text:"\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u4F1A\u8A71\u3092\u59CB\u3081\u308B\u306B\u306F\u5225\u306E\u7AEF\u672B\u3067 `
|
|
1296
|
-
return}if(initialModelWarning!==null){commit({kind:"notice",tone:"warn",text:initialModelWarning})}let cancelled=false;const pending=runtime.loadCatalog();catalogFetchRef.current=pending;void pending.then(fetched=>{if(cancelled)return;if(isBelowMinSupported(version,fetched.minSupportedVersion)){blockOnMinSupported(fetched.minSupportedVersion);return}setCatalog(fetched);const picked=pickModel(fetched,modelRef.current);if(picked.
|
|
1297
|
-
void 0)commit({kind:"notice",tone:"warn",text:picked.warning})}});return()=>{cancelled=true}},[blockOnMinSupported,commit,initialModelWarning,runtime,version]);const sleep=ms=>new Promise(resolve=>{const timer=setTimeout(()=>{sleepRef.current=null;resolve()},ms);sleepRef.current={timer,resolve}});const abortSleep=()=>{const s=sleepRef.current;if(!s)return;clearTimeout(s.timer);sleepRef.current=null;s.resolve()};const askPermission=spec=>new Promise(
|
|
1298
|
-
0);setPermState(INITIAL_DIALOG_STATE);setOverlay("permission");permissionResolver.current=choice=>{setOverlay("none");setPendingPermission(null);permissionResolver.current=null;resolve(choice)}});const persistAllow=isAbsolute(twpHomeDir())?rule=>{const result=persistProjectAllow(rule,{cwd:process.cwd()});if(result.ok){commit({kind:"notice",tone:"info",text:`\u300C${stripTerminalControls(rule)}\u300D\u3092 ${stripTerminalControls(result.file)} \u306B\u4FDD\u5B58\u3057\
|
|
1299
|
-
result.root)} \u3067\u306F\u4ECA\u5F8C\u805E\u304D\u307E\u305B\u3093\uFF09`})}else{commit({kind:"notice",tone:"warn",text:`\u4ECA\u5F8C\u805E\u304B\u306A\u3044\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08\u4ECA\u56DE\u3060\u3051\u8A31\u53EF\u3057\u307E\u3057\u305F\uFF09: ${stripTerminalControls(result.reason)}`})}return result.ok}:void 0;const runTurn2=(0,import_react38.useCallback)(async(text,opts={})=>{if(busyRef.current){commit(
|
|
1300
|
-
C \u3067\u4E2D\u65AD\u3057\u3066\u304B\u3089\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"});return}busyRef.current=true;abortRef.current=false;setBusy(true);commit({kind:"user",text:opts.display??text});const startupCatalog=await catalogFetchRef.current;if(startupCatalog&&isBelowMinSupported(version,startupCatalog.minSupportedVersion)){blockOnMinSupported(startupCatalog.minSupportedVersion);return}const controller=new AbortController;
|
|
1301
|
-
modeRef.current);const expandDeps={aborted:()=>abortRef.current,isFile:p=>{const cwdNow=process.cwd();if(isAbsolute(p)||p.startsWith("~")||/^[\\/]{2}/.test(p))return false;const abs=resolvePath(cwdNow,p);const rel=relativePath(cwdNow,abs);if(rel===""||rel===".."||rel.startsWith(`..${sep}`)||isAbsolute(rel))return false;try{return statSync(abs).isFile()}catch{return false}},readFile:async p=>{try{const size2=statSync(resolvePath(process.
|
|
1302
|
-
\u30D0\u30A4\u30C8\u3042\u308A\u3001\u6DFB\u4ED8\u306E\u4E0A\u9650 ${MAX_ATTACHED_BYTES} \u30D0\u30A4\u30C8\u3092\u8D85\u3048\u307E\u3059`}}catch{}const result2=await executeTool(readFileTool,{path:p},{mode:expandMode,ctx:{cwd:process.cwd()},sessionAllow:sessionAllow.current,sessionRules:sessionRules.current,...persistAllow?{persistAllow}:{},permissionLayers,...permissionMode!==void 0?{permissionMode}:{},audit,askPermission:request=>askPermission(
|
|
1303
|
-
isError===true||result2.denied===true){const reason=stripTerminalControls(result2.content.split("\n")[0]??"").slice(0,200);return{ok:false,reason:reason===""?"\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F":reason}}return{ok:true,content:result2.content,truncated:/\[truncated/.test(result2.content)}},fetchTask:async key=>{const got=await runTwpSlashCommand("/task",[key,"--output","json"],{profile:runtime.profileName,version});if(got.code!==
|
|
1304
|
-
"\n")[0]??"").slice(0,200);return{ok:false,reason:reason===""?`\u7D42\u4E86\u30B3\u30FC\u30C9 ${got.code}`:reason}}try{const parsed=JSON.parse(got.out);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){return{ok:true,task:parsed}}}catch{}return{ok:false,reason:"\u5FDC\u7B54\u3092\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F"}}};const expanded=await expandInput(text,expandDeps);for(const note of expanded.notices)commit(
|
|
1305
|
-
commit({kind:"notice",tone:"warn",text:"\u4E2D\u65AD\u3057\u307E\u3057\u305F\uFF08Ctrl+C\uFF09\u2014 \u9001\u4FE1\u3057\u3066\u3044\u307E\u305B\u3093"});return}stream.begin();const turnMode=getMode(modeRef.current);const resident=buildResidentSet(turnMode,{...permissionMode!==void 0?{permissionMode}:{},permissionLayers});const turnTools=opts.allowedTools===void 0?resident.tools:resident.tools.filter(t=>opts.allowedTools?.
|
|
1306
|
-
context,{input:expanded.input,model:modelRef.current,system:buildSystemPrompt({cwd:cwd2,branch,modeLabel:turnMode.label,cliVersion:version,toolNames:turnTools.map(t=>t.name),...turnMode.prompt!==void 0?{modePrompt:turnMode.prompt}:{}}),signal:controller.signal,onTextDelta:delta=>stream.push(stripTerminalControls(delta)),tools:turnTools,execute:{mode:turnMode,ctx:{cwd:process.cwd()},sessionAllow:sessionAllow.current,sessionRules:sessionRules.
|
|
1307
|
-
|
|
1308
|
-
summary??call.name);const run={name:stripTerminalControls(call.name),summary:label,input:label,output:stripTerminalControls(toolResult.content),status:toolResult.denied===true?"denied":toolResult.isError===true?"error":"done",...toolResult.diff?{diff:toolResult.diff}:{}};lastToolRef.current=run;commit({kind:"tool",run});stream.begin()}});const full=stream.end();stream.
|
|
1309
|
-
\u30C4\u30FC\u30EB\u5B9F\u884C\u306E\u5F80\u5FA9\u304C\u4E0A\u9650\u306B\u9054\u3057\u305F\u305F\u3081\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002\u7D9A\u304D\u306F\u540C\u3058\u4F1A\u8A71\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044"})}if(result.droppedMessages>0){commit({kind:"notice",tone:"warn",text:`\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u4E0A\u9650\u306B\u8FD1\u3065\u3044\u305F\u305F\u3081\u3001\u53E4\u3044\u3084\u308A\u53D6\u308A ${result.
|
|
1310
|
-
\u793A\u7684\u306B\u6D88\u305B\u307E\u3059\uFF09`})}if(result.upstreamError!==null){commit({kind:"notice",tone:"error",text:`\u30E2\u30C7\u30EB\u306E\u5FDC\u7B54\u304C\u9014\u4E2D\u3067\u7D42\u308F\u308A\u307E\u3057\u305F: ${result.upstreamError}`})}if(result.aborted){commit({kind:"notice",tone:"warn",text:"\u4E2D\u65AD\u3057\u307E\u3057\u305F\uFF08Ctrl+C\uFF09\u2014 \u3053\u3053\u307E\u3067\u306E\u6D88\u8CBB\u306F\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u306B\u8A08\u4E0A\u3055\u308C\u307E\u3059"})}else if(result.
|
|
1293
|
+
null);const sleepRef=(0,import_react38.useRef)(null);const permissionResolver=(0,import_react38.useRef)(null);const permStateRef=(0,import_react38.useRef)(INITIAL_DIALOG_STATE);const[permState,setPermStateRaw]=(0,import_react38.useState)(INITIAL_DIALOG_STATE);const setPermState=(0,import_react38.useCallback)(next=>{permStateRef.current=next;setPermStateRaw(next)},[]);const sessionAllow=(0,import_react38.useRef)(new Set);const toolkitRef=(0,import_react38.useRef)(null);toolkitRef.current??=createTwpToolkit(
|
|
1294
|
+
runtime,version);const toolkit=toolkitRef.current;const sessionRules=(0,import_react38.useRef)([]);const demoSessionAllow=(0,import_react38.useRef)(new Set);const lastToolRef=(0,import_react38.useRef)(null);(0,import_react38.useEffect)(()=>()=>{abortRef.current=true;streamAbortRef.current?.abort();const s=sleepRef.current;if(s){clearTimeout(s.timer);sleepRef.current=null;s.resolve()}},[]);const modeDef=getMode(mode);const branch=(0,import_react38.useMemo)(()=>currentBranch(),[]);const cwd2=(0,import_react38.useMemo)(
|
|
1295
|
+
()=>displayCwd(),[]);const networkDiagnostics=(0,import_react38.useMemo)(()=>proxyDiagnostics(),[]);const fixedChrome=1+2+(busy?1:0)+(pasting?1:0)+1+1;const liveTotal=Math.max(MIN_LIVE_ROWS,size.rows-1);const inputContentWidth=Math.max(1,size.columns-6);const inputMaxRows=Math.max(1,Math.min(6,liveTotal-fixedChrome-1));const inputWindow=layoutInputWindow(buffer.text,buffer.cursor,inputContentWidth,inputMaxRows);const budget=liveAreaBudget(size.rows,fixedChrome+inputWindow.shownRows);const commit=(0,import_react38.useCallback)(
|
|
1296
|
+
item=>{setItems(prev=>[...prev,{...item,id:nextId()}])},[]);const catalogFetchRef=(0,import_react38.useRef)(null);const blockOnMinSupported=(0,import_react38.useCallback)(floor=>{const text=minSupportedBlockMessage(version,floor??"");commit({kind:"notice",tone:"error",text});process.exitCode=1;exit();process.stderr.write(stripTerminalControls(text))},[commit,exit,version]);(0,import_react38.useEffect)(()=>{if(!runtime.loggedIn){commit({kind:"notice",tone:"warn",text:"\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u4F1A\u8A71\u3092\u59CB\u3081\u308B\u306B\u306F\u5225\u306E\u7AEF\u672B\u3067 `tw\
|
|
1297
|
+
p login` \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"});return}if(initialModelWarning!==null){commit({kind:"notice",tone:"warn",text:initialModelWarning})}let cancelled=false;const pending=runtime.loadCatalog();catalogFetchRef.current=pending;void pending.then(fetched=>{if(cancelled)return;if(isBelowMinSupported(version,fetched.minSupportedVersion)){blockOnMinSupported(fetched.minSupportedVersion);return}setCatalog(fetched);const picked=pickModel(fetched,modelRef.current);if(picked.
|
|
1298
|
+
model!==modelRef.current){setModel(picked.model);if(picked.warning!==void 0)commit({kind:"notice",tone:"warn",text:picked.warning})}});return()=>{cancelled=true}},[blockOnMinSupported,commit,initialModelWarning,runtime,version]);const sleep=ms=>new Promise(resolve=>{const timer=setTimeout(()=>{sleepRef.current=null;resolve()},ms);sleepRef.current={timer,resolve}});const abortSleep=()=>{const s=sleepRef.current;if(!s)return;clearTimeout(s.timer);sleepRef.current=null;s.resolve()};const askPermission=spec=>new Promise(
|
|
1299
|
+
resolve=>{setPendingPermission(spec);setSelected(0);setPermState(INITIAL_DIALOG_STATE);setOverlay("permission");permissionResolver.current=choice=>{setOverlay("none");setPendingPermission(null);permissionResolver.current=null;resolve(choice)}});const persistAllow=isAbsolute(twpHomeDir())?rule=>{const result=persistProjectAllow(rule,{cwd:process.cwd()});if(result.ok){commit({kind:"notice",tone:"info",text:`\u300C${stripTerminalControls(rule)}\u300D\u3092 ${stripTerminalControls(result.file)} \u306B\u4FDD\u5B58\u3057\
|
|
1300
|
+
\u307E\u3057\u305F\uFF08${stripTerminalControls(result.root)} \u3067\u306F\u4ECA\u5F8C\u805E\u304D\u307E\u305B\u3093\uFF09`})}else{commit({kind:"notice",tone:"warn",text:`\u4ECA\u5F8C\u805E\u304B\u306A\u3044\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08\u4ECA\u56DE\u3060\u3051\u8A31\u53EF\u3057\u307E\u3057\u305F\uFF09: ${stripTerminalControls(result.reason)}`})}return result.ok}:void 0;const runTurn2=(0,import_react38.useCallback)(async(text,opts={})=>{if(busyRef.current){commit(
|
|
1301
|
+
{kind:"notice",tone:"warn",text:"\u5B9F\u884C\u4E2D\u3067\u3059\u3002Ctrl+C \u3067\u4E2D\u65AD\u3057\u3066\u304B\u3089\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"});return}busyRef.current=true;abortRef.current=false;setBusy(true);commit({kind:"user",text:opts.display??text});const startupCatalog=await catalogFetchRef.current;if(startupCatalog&&isBelowMinSupported(version,startupCatalog.minSupportedVersion)){blockOnMinSupported(startupCatalog.minSupportedVersion);return}const controller=new AbortController;
|
|
1302
|
+
streamAbortRef.current=controller;try{const expandMode=getMode(modeRef.current);const expandDeps={aborted:()=>abortRef.current,isFile:p=>{const cwdNow=process.cwd();if(isAbsolute(p)||p.startsWith("~")||/^[\\/]{2}/.test(p))return false;const abs=resolvePath(cwdNow,p);const rel=relativePath(cwdNow,abs);if(rel===""||rel===".."||rel.startsWith(`..${sep}`)||isAbsolute(rel))return false;try{return statSync(abs).isFile()}catch{return false}},readFile:async p=>{try{const size2=statSync(resolvePath(process.
|
|
1303
|
+
cwd(),p)).size;if(size2>MAX_ATTACHED_BYTES)return{ok:false,reason:`${size2} \u30D0\u30A4\u30C8\u3042\u308A\u3001\u6DFB\u4ED8\u306E\u4E0A\u9650 ${MAX_ATTACHED_BYTES} \u30D0\u30A4\u30C8\u3092\u8D85\u3048\u307E\u3059`}}catch{}const result2=await executeTool(readFileTool,{path:p},{mode:expandMode,ctx:{cwd:process.cwd()},sessionAllow:sessionAllow.current,sessionRules:sessionRules.current,...persistAllow?{persistAllow}:{},permissionLayers,...permissionMode!==void 0?{permissionMode}:{},audit,askPermission:request=>askPermission(
|
|
1304
|
+
{...promptFor(request),allowInstead:false})});if(result2.isError===true||result2.denied===true){const reason=stripTerminalControls(result2.content.split("\n")[0]??"").slice(0,200);return{ok:false,reason:reason===""?"\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F":reason}}return{ok:true,content:result2.content,truncated:/\[truncated/.test(result2.content)}},fetchTask:async key=>{const got=await runTwpSlashCommand("/task",[key,"--output","json"],{profile:runtime.profileName,version});if(got.code!==
|
|
1305
|
+
0){const reason=stripTerminalControls(got.err.trim().split("\n")[0]??"").slice(0,200);return{ok:false,reason:reason===""?`\u7D42\u4E86\u30B3\u30FC\u30C9 ${got.code}`:reason}}try{const parsed=JSON.parse(got.out);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){return{ok:true,task:parsed}}}catch{}return{ok:false,reason:"\u5FDC\u7B54\u3092\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F"}}};const expanded=await expandInput(text,expandDeps);for(const note of expanded.notices)commit(
|
|
1306
|
+
{kind:"notice",tone:"info",text:note});if(abortRef.current){commit({kind:"notice",tone:"warn",text:"\u4E2D\u65AD\u3057\u307E\u3057\u305F\uFF08Ctrl+C\uFF09\u2014 \u9001\u4FE1\u3057\u3066\u3044\u307E\u305B\u3093"});return}stream.begin();const turnMode=getMode(modeRef.current);const resident=buildResidentSet(turnMode,{...residentInputs(toolkit),...permissionMode!==void 0?{permissionMode}:{},permissionLayers});const turnTools=opts.allowedTools===void 0?resident.tools:resident.tools.filter(t=>opts.allowedTools?.
|
|
1307
|
+
includes(t.name)===true);const result=await runTurn(runtime.client,runtime.context,{input:expanded.input,model:modelRef.current,system:buildSystemPrompt({cwd:cwd2,branch,modeLabel:turnMode.label,cliVersion:version,toolNames:turnTools.map(t=>t.name),...turnMode.prompt!==void 0?{modePrompt:turnMode.prompt}:{}}),signal:controller.signal,onTextDelta:delta=>stream.push(stripTerminalControls(delta)),tools:turnTools,execute:{mode:turnMode,ctx:{cwd:process.cwd()},sessionAllow:sessionAllow.current,sessionRules:sessionRules.
|
|
1308
|
+
current,...persistAllow?{persistAllow}:{},permissionLayers,...permissionMode!==void 0?{permissionMode}:{},resolveTool:toolkit.resolveTool,prepareIndirect:toolkit.prepareIndirect,audit,askPermission:request=>askPermission(promptFor(request)),onStart:(tool,preview)=>{const safe=stripTerminalControls(preview);setRunningTool({name:stripTerminalControls(tool.name),summary:safe,input:safe,output:"",status:"running"})}},onToolUse:()=>{const partial=stream.end();stream.clear();if(partial.trim()!=="")commit(
|
|
1309
|
+
{kind:"assistant",text:partial})},onToolResult:(call,toolResult)=>{setRunningTool(null);const label=stripTerminalControls(toolResult.summary??call.name);const run={name:stripTerminalControls(call.name),summary:label,input:label,output:stripTerminalControls(toolResult.content),status:toolResult.denied===true?"denied":toolResult.isError===true?"error":"done",...toolResult.diff?{diff:toolResult.diff}:{}};lastToolRef.current=run;commit({kind:"tool",run});stream.begin()}});const full=stream.end();stream.
|
|
1310
|
+
clear();if(full.trim()!=="")commit({kind:"assistant",text:full});if(result.maxStepsReached){commit({kind:"notice",tone:"warn",text:"\u30C4\u30FC\u30EB\u5B9F\u884C\u306E\u5F80\u5FA9\u304C\u4E0A\u9650\u306B\u9054\u3057\u305F\u305F\u3081\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002\u7D9A\u304D\u306F\u540C\u3058\u4F1A\u8A71\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044"})}if(result.droppedMessages>0){commit({kind:"notice",tone:"warn",text:`\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u4E0A\u9650\u306B\u8FD1\u3065\u3044\u305F\u305F\u3081\u3001\u53E4\u3044\u3084\u308A\u53D6\u308A ${result.
|
|
1311
|
+
droppedMessages} \u4EF6\u3092\u5C65\u6B74\u304B\u3089\u843D\u3068\u3057\u307E\u3057\u305F\uFF08/clear \u3067\u660E\u793A\u7684\u306B\u6D88\u305B\u307E\u3059\uFF09`})}if(result.upstreamError!==null){commit({kind:"notice",tone:"error",text:`\u30E2\u30C7\u30EB\u306E\u5FDC\u7B54\u304C\u9014\u4E2D\u3067\u7D42\u308F\u308A\u307E\u3057\u305F: ${result.upstreamError}`})}if(result.aborted){commit({kind:"notice",tone:"warn",text:"\u4E2D\u65AD\u3057\u307E\u3057\u305F\uFF08Ctrl+C\uFF09\u2014 \u3053\u3053\u307E\u3067\u306E\u6D88\u8CBB\u306F\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u306B\u8A08\u4E0A\u3055\u308C\u307E\u3059"})}else if(result.
|
|
1311
1312
|
emptyResponse){commit({kind:"notice",tone:"warn",text:"\u30E2\u30C7\u30EB\u304B\u3089\u30C6\u30AD\u30B9\u30C8\u5FDC\u7B54\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F"})}}catch(err){const partial=stream.end();stream.clear();if(partial.trim()!=="")commit({kind:"assistant",text:partial});commit({kind:"notice",tone:"error",text:err instanceof RelayError?err.message:`\u30E2\u30C7\u30EB\u53D6\u6B21\u3067\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: ${err.message}`})}finally{streamAbortRef.
|
|
1312
1313
|
current=null;setRunningTool(null);setContext(runtime.context.snapshot());busyRef.current=false;setBusy(false)}},[audit,blockOnMinSupported,branch,commit,cwd2,permissionLayers,permissionMode,runtime,stream,version]);const runDemo=(0,import_react38.useCallback)(async text=>{if(busyRef.current){commit({kind:"notice",tone:"warn",text:"\u5B9F\u884C\u4E2D\u3067\u3059\u3002Ctrl+C \u3067\u4E2D\u65AD\u3057\u3066\u304B\u3089\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"});return}busyRef.current=true;abortRef.
|
|
1313
1314
|
current=false;setBusy(true);commit({kind:"user",text});for(const step of buildScenario(text)){if(abortRef.current)break;if(step.type==="text"){await stream.start(step.text);stream.clear();if(!abortRef.current)commit({kind:"assistant",text:step.text});continue}const spec=step.spec;const policy=applyPermissionMode(checkPermission(spec.name,getMode(modeRef.current)),spec.risk??"exec",permissionMode).decision;const decision=policy!=="deny"&&demoSessionAllow.current.has(spec.name)?"allow":policy;if(decision===
|
|
@@ -1321,9 +1322,9 @@ void 0&&!isAvailableInMode(cmd,modeRef.current)){commit({kind:"notice",tone:"war
|
|
|
1321
1322
|
\u30E2\u30FC\u30C9\u3092 ${getMode(to).label}\uFF08${to}\uFF09\u306B\u5207\u308A\u66FF\u3048\u307E\u3057\u305F \u2014 ${getMode(to).description}`});return}case"/help":commit({kind:"notice",tone:"info",text:["\u4F1A\u8A71\u306F\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u3067\u5B9F\u969B\u306B\u30E2\u30C7\u30EB\u3078\u9001\u3089\u308C\u307E\u3059",`\u4F7F\u3048\u308B\u30B3\u30DE\u30F3\u30C9: ${commandsForMode(modeRef.current).map(c=>c.name).join(" ")}\uFF08/exit \u306F /quit \u3082\u53EF\uFF09`,
|
|
1322
1323
|
...commandsForMode(modeRef.current).filter(c=>c.source!==void 0).map(c=>` ${c.name} \u2014 ${c.origin==="project"?"\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u5B9A\u7FA9":"\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9"}: ${c.source??""}`),"\u30B3\u30DE\u30F3\u30C9\u306F .twp/commands/*.md\uFF08\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09\u3068 ~/.twp/commands/*.md\uFF08\u30E6\u30FC\u30B6\u30FC\uFF09\u306B\u7F6E\u3051\u307E\u3059 \xB7 @\u30D1\u30B9 \u3067\u30D5\u30A1\u30A4\u30EB\u6DFB\u4ED8 \xB7 #ABC-123 \u306E\u3088\u3046\u306A\u30BF\u30B9\u30AF\u30AD\u30FC\u3067\u30BF\u30B9\u30AF\u6DFB\u4ED8",
|
|
1323
1324
|
...(()=>{const pending=PENDING_COMMANDS.filter(c=>findCommand(c.name)===void 0);return pending.length>0?[`\u672A\u5B9F\u88C5\u306E\u305F\u3081\u767B\u9332\u3057\u3066\u3044\u306A\u3044\u30B3\u30DE\u30F3\u30C9: ${pending.map(c=>c.name).join(" ")}`]:[]})(),"\u30AD\u30FC: Shift+Tab \u307E\u305F\u306F Alt+M \u3067\u30E2\u30FC\u30C9\u5DE1\u56DE \xB7 Ctrl+R \u3067\u76F4\u524D\u306E\u30C4\u30FC\u30EB\u51FA\u529B\u3092\u5C55\u958B","\u6539\u884C: Shift+Enter\uFF08kitty \u5BFE\u5FDC\u7AEF\u672B\uFF09\xB7 Ctrl+J\uFF08\u5168\u7AEF\u672B\uFF09\xB7 \\ \u3092\u6253\u3063\u3066\u304B\u3089 Enter \u3067\u3082\u53EF"].
|
|
1324
|
-
join("\n")});return;case"/context":{const snapshot=runtime.context.snapshot();const t=snapshot.totals;const resident=buildResidentSet(getMode(modeRef.current),{...permissionMode!==void 0?{permissionMode}:{},permissionLayers});commit({kind:"notice",tone:"info",text:[`\u30E2\u30C7\u30EB: ${modelLabel(model)}\uFF08\u30E2\u30FC\u30C9\u3068\u306F\u72EC\u7ACB\uFF09`,`\u30E2\u30FC\u30C9: ${getMode(modeRef.current).label} \u2014 \u6709\u52B9\u30C4\u30FC\u30EB glob: ${getMode(modeRef.
|
|
1325
|
-
" ")}`,`\u30E2\u30FC\u30C9\u5B9A\u7FA9: ${modeSource(modeRef.current)??"\u7D44\u307F\u8FBC\u307F\uFF08\u5B9A\u7FA9\u30D5\u30A1\u30A4\u30EB\u306A\u3057\uFF09"}`,`\u63A5\u7D9A\u5148: ${runtime.relayUrl}\uFF08\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${runtime.profileName}\uFF09`,`\u30BF\u30FC\u30F3\u6570: ${snapshot.turns} \xB7 \u76F4\u8FD1\u306E\u30D7\u30ED\u30F3\u30D7\u30C8\u9577: ${snapshot.lastPromptTokens} tok`,`\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u6B8B\u91CF: ${snapshot.remainingPercent}
|
|
1326
|
-
,000 tok \u306E\u6982\u7B97\uFF09`,`\u5B9F\u6E2C\u30C8\u30FC\u30AF\u30F3\u5408\u8A08: input ${t.inputTokens} / cache_read ${t.cacheReadTokens} / cache_write ${t.cacheWriteTokens} / output ${t.outputTokens}`,...snapshot.droppedMessages>0?[`\u4E0A\u9650\u306E\u305F\u3081\u843D\u3068\u3057\u305F\u3084\u308A\u53D6\u308A: ${snapshot.droppedMessages} \u4EF6`]:[],`permission-mode: ${describePermissionMode(permissionMode)}`,`\u76E3\u67FB\u30ED\u30B0: ${describeAuditLog(audit)}`,`\u5E38\u99D0\u30C4\u30FC\u30EB: ${resident.
|
|
1325
|
+
join("\n")});return;case"/context":{const snapshot=runtime.context.snapshot();const t=snapshot.totals;const resident=buildResidentSet(getMode(modeRef.current),{...residentInputs(toolkit),...permissionMode!==void 0?{permissionMode}:{},permissionLayers});commit({kind:"notice",tone:"info",text:[`\u30E2\u30C7\u30EB: ${modelLabel(model)}\uFF08\u30E2\u30FC\u30C9\u3068\u306F\u72EC\u7ACB\uFF09`,`\u30E2\u30FC\u30C9: ${getMode(modeRef.current).label} \u2014 \u6709\u52B9\u30C4\u30FC\u30EB glob: ${getMode(modeRef.
|
|
1326
|
+
current).tools.join(" ")}`,`\u30E2\u30FC\u30C9\u5B9A\u7FA9: ${modeSource(modeRef.current)??"\u7D44\u307F\u8FBC\u307F\uFF08\u5B9A\u7FA9\u30D5\u30A1\u30A4\u30EB\u306A\u3057\uFF09"}`,`\u63A5\u7D9A\u5148: ${runtime.relayUrl}\uFF08\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${runtime.profileName}\uFF09`,`\u30BF\u30FC\u30F3\u6570: ${snapshot.turns} \xB7 \u76F4\u8FD1\u306E\u30D7\u30ED\u30F3\u30D7\u30C8\u9577: ${snapshot.lastPromptTokens} tok`,`\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u6B8B\u91CF: ${snapshot.remainingPercent}\
|
|
1327
|
+
%\uFF08\u7A93 200,000 tok \u306E\u6982\u7B97\uFF09`,`\u5B9F\u6E2C\u30C8\u30FC\u30AF\u30F3\u5408\u8A08: input ${t.inputTokens} / cache_read ${t.cacheReadTokens} / cache_write ${t.cacheWriteTokens} / output ${t.outputTokens}`,...snapshot.droppedMessages>0?[`\u4E0A\u9650\u306E\u305F\u3081\u843D\u3068\u3057\u305F\u3084\u308A\u53D6\u308A: ${snapshot.droppedMessages} \u4EF6`]:[],`permission-mode: ${describePermissionMode(permissionMode)}`,`\u76E3\u67FB\u30ED\u30B0: ${describeAuditLog(audit)}`,`\u5E38\u99D0\u30C4\u30FC\u30EB: ${resident.
|
|
1327
1328
|
tools.length} \u672C / \u30B9\u30AD\u30FC\u30DE\u6982\u7B97 ${resident.tokens} tok\uFF08\u4E0A\u9650 ${RESIDENT_TOKEN_CAP} tok\uFF09`,` ${resident.tools.map(t2=>t2.name).join(" ")||"\uFF08\u306A\u3057\uFF09"}`,...resident.dropped.length>0?[` \u4E0A\u9650\u8D85\u904E\u3067\u5916\u3057\u305F\u30C4\u30FC\u30EB: ${resident.dropped.join(" ")}`]:[],"TWP API \u306E\u30C4\u30FC\u30EB\uFF08\u30E1\u30BF\u30C4\u30FC\u30EB\u30FB\u30AB\u30BF\u30ED\u30B0\u914D\u4FE1\uFF09\u306F\u5225\u30BF\u30B9\u30AF\u3067\u8F09\u308A\u307E\u3059"].
|
|
1328
1329
|
join("\n")});return}case"/demo":void runDemo("\uFF08\u30C7\u30E2\u518D\u751F\uFF09\u30C4\u30FC\u30EB\u30AB\u30FC\u30C9\u3068\u6A29\u9650\u30C0\u30A4\u30A2\u30ED\u30B0");return;default:commit({kind:"notice",tone:"warn",text:`\u4E0D\u660E\u306A\u30B3\u30DE\u30F3\u30C9: ${name}`})}},[audit,catalog,commit,exit,model,permissionMode,runDemo,runPromptCommand,runTwp,runtime]);const submit=(0,import_react38.useCallback)(()=>{if(busyRef.current){commit({kind:"notice",tone:"warn",text:"\u5B9F\u884C\u4E2D\u3067\u3059\u3002Ctrl+C \u3067\u4E2D\u65AD\u3057\u3066\u304B\u3089\
|
|
1329
1330
|
\u9001\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5165\u529B\u306F\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF09"});return}const text=bufferRef.current.text.trim();clearBuffer();setOverlay("none");if(text==="")return;if(text.startsWith("/")){runCommand(text);return}void runTurn2(text)},[clearBuffer,commit,runCommand,runTurn2]);const paletteItems=(0,import_react38.useMemo)(()=>paletteFor(buffer.text,mode),[buffer.text,mode]);const dismissedMentionRef=(0,import_react38.useRef)(null);const fileCompletion=(0,import_react38.useMemo)(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{CHECK_INTERVAL_MS,DISABLE_ENV,PARENT_PID_ENV,WORKER_ENV,autoUpdateDisabledReason,classifyInstall,describeAutoUpdate,isCheckDue,listRegisteredPids,lockFilePath,onStartup,pickNotice,readUpdateState,registerRunning,resolveCliPath,runDirPath,sameNpmPath,stateFilePath,workerEnv,writeUpdateState}from"./chunk-
|
|
3
|
+
import{CHECK_INTERVAL_MS,DISABLE_ENV,PARENT_PID_ENV,WORKER_ENV,autoUpdateDisabledReason,classifyInstall,describeAutoUpdate,isCheckDue,listRegisteredPids,lockFilePath,onStartup,pickNotice,readUpdateState,registerRunning,resolveCliPath,runDirPath,sameNpmPath,stateFilePath,workerEnv,writeUpdateState}from"./chunk-ILKQDXI5.js";import"./chunk-DXXFUNYN.js";import"./chunk-5WGOHFAS.js";import"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";import"./chunk-NHYMHCAT.js";
|
|
4
4
|
import"./chunk-VSJBJXZO.js";export{CHECK_INTERVAL_MS,DISABLE_ENV,PARENT_PID_ENV,WORKER_ENV,autoUpdateDisabledReason,classifyInstall,describeAutoUpdate,isCheckDue,listRegisteredPids,lockFilePath,onStartup,pickNotice,readUpdateState,registerRunning,resolveCliPath,runDirPath,sameNpmPath,stateFilePath,workerEnv,writeUpdateState};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{fetchLatestVersion,isBehindLatest,resolveNpmCommand}from"./chunk-
|
|
4
|
-
import"./chunk-
|
|
3
|
+
import{fetchLatestVersion,isBehindLatest,resolveNpmCommand}from"./chunk-VCMVTC6B.js";import"./chunk-WOUKWOAR.js";import"./chunk-XNLIEUAW.js";import"./chunk-PMOUHEJQ.js";import"./chunk-J7QYPKVK.js";import{PARENT_PID_ENV,WORKER_ENV,autoUpdateDisabledReason,classifyInstall,isCheckDue,listRegisteredPids,lockFilePath,readUpdateState,resolveCliPath,runDirPath,writeUpdateState}from"./chunk-ILKQDXI5.js";import{PACKAGE_NAME,parseVersionCore}from"./chunk-DXXFUNYN.js";
|
|
4
|
+
import"./chunk-5WGOHFAS.js";import"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import{execFile}from"child_process";import fs from"fs";import path from"path";var PARENT_WAIT_MAX_MS=12*60*60*1e3;var PARENT_POLL_MS=1e3;var LOCK_STALE_MS=PARENT_WAIT_MAX_MS+60*60*1e3;var INSTALL_TIMEOUT_MS=0;function childEnv(env){const next={...env};delete next[WORKER_ENV];delete next[PARENT_PID_ENV];return next}function createNpmRunner(env=process.env){const cmd=resolveNpmCommand({env});if(cmd===null)return null;return(args,timeoutMs)=>new Promise(resolve=>{execFile(cmd.file,[...cmd.prefix,...args],{timeout:timeoutMs,windowsHide:true,maxBuffer:8*1024*1024,cwd:path.dirname(lockFilePath(env)),env:childEnv(env)},(error,stdout,stderr)=>{if(error===null){resolve({ok:true,stdout:String(stdout),stderr:String(
|
|
5
5
|
stderr)});return}const e=error;resolve({ok:false,stdout:String(stdout??""),stderr:String(stderr??""),...e.killed?{error:"\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F"}:typeof e.code==="string"?{error:e.code}:{}})})})}function summarizeNpmFailure(result){const text=`${result.stderr}
|
|
6
6
|
${result.stdout}`;const code=/npm (?:ERR!|error) code (\S+)/.exec(text)?.[1]??result.error;let reason;if(code==="EACCES"||code==="EPERM"){reason=`\u30B0\u30ED\u30FC\u30D0\u30EB\u306E\u5C0E\u5165\u5148\u306B\u66F8\u304D\u8FBC\u3080\u6A29\u9650\u304C\u3042\u308A\u307E\u305B\u3093\uFF08${code}\uFF09`}else if(code!==void 0&&/^(ENOTFOUND|ETIMEDOUT|ECONNREFUSED|ECONNRESET|EAI_AGAIN|ENETUNREACH)$/.test(code)){reason=`npm registry \u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${code}\
|
|
7
7
|
\uFF09`}else if(code!==void 0){reason=`npm \u304C\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${code}\uFF09`}else{const line=text.split("\n").map(l=>l.trim()).find(l=>l!=="")??"\u4E0D\u660E\u306A\u30A8\u30E9\u30FC";reason=`npm \u304C\u5931\u6557\u3057\u307E\u3057\u305F: ${line}`}return stripTerminalControls(reason).slice(0,200)}function readInstalledVersion(cliPath){try{const pkgRoot=path.dirname(path.dirname(cliPath));const pkg=JSON.parse(fs.readFileSync(path.join(pkgRoot,"package.json"),"utf8"));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{
|
|
4
|
-
import{ApiResponseError,UsageError}from"./chunk-
|
|
3
|
+
import{readBody}from"./chunk-HGTG5XQ7.js";import{BACKLOG_BASE_PATH,BACKLOG_PROJECT_SCOPE_LABEL,BACKLOG_SCOPE_LABEL,backlogSpacePath,resolveNamed}from"./chunk-QOUFHYK5.js";import"./chunk-II5RVJQN.js";import"./chunk-FTYJZFEK.js";import{requireResolved,singleRef,withResolved}from"./chunk-ZN5EFDH7.js";import"./chunk-GMBJTG6A.js";import{isRecord,pick}from"./chunk-ZWVYVS2A.js";import"./chunk-J7QYPKVK.js";import"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";
|
|
4
|
+
import"./chunk-NHYMHCAT.js";import{ApiResponseError,UsageError}from"./chunk-7WSNIXTQ.js";import"./chunk-VSJBJXZO.js";var DEFAULT_COUNT=20;var MAX_COUNT=100;var NUMERIC=/^[0-9]+$/;function isExactNumericId(value){return NUMERIC.test(value)&&String(Number(value))===value}var ISSUE_REF=/^(?:[A-Za-z0-9_]+-[0-9]+|[0-9]+)$/;var DATE=/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;var SPACE_COLUMNS=["id","space_url"];var PROJECT_COLUMNS=["id","projectKey","name"];var ISSUE_LIST_COLUMNS=["issueKey","summary","status","assignee","priority","dueDate","updated","descriptionTruncated"];var ISSUE_GET_COLUMNS=["id","issueKey","projectId","s\
|
|
5
5
|
ummary","description","descriptionTruncated","status","issueType","priority","assignee","createdUser","parentIssueId","startDate","dueDate","estimatedHours","actualHours","created","updated"];var COMMENT_COLUMNS=["id","created","createdUserId","createdUser","content","changeLog"];function commentRow(row){const source=isRecord(row)?row:{};const user=isRecord(source["createdUser"])?source["createdUser"]:{};return pick({...source,createdUserId:user["id"]??null,createdUser:user["name"]??null},COMMENT_COLUMNS)}
|
|
6
6
|
var ATTACHMENT_COLUMNS=["id","name","size","contentType","createdUserId","createdUser","created"];var STATUS_COLUMNS=["id","name","color"];var USER_COLUMNS=["id","userId","name","mailAddress","roleType"];var SPACE_FLAG={name:"--space",summary:"Backlog \u30B9\u30DA\u30FC\u30B9\uFF08ID / \u30B9\u30DA\u30FC\u30B9URL / \u30B5\u30D6\u30C9\u30E1\u30A4\u30F3\uFF09\u3002\u767B\u9332\u304C1\u4EF6\u306A\u3089\u7701\u7565\u3067\u304D\u307E\u3059",takesValue:true,placeholder:"<ID|URL>"};var BODY_MAX_CHARS=1e5;
|
|
7
7
|
var BODY_FLAGS=[{name:"--body-file",summary:"\u672C\u6587\u3092\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u8AAD\u3080\uFF08- \u3067\u6A19\u6E96\u5165\u529B\uFF09\u3002\u6539\u884C\u30FBMarkdown \u3092\u58CA\u3055\u306A\u3044\u4E3B\u7D4C\u8DEF",takesValue:true,placeholder:"<\u30D1\u30B9|->"},{name:"--body",summary:"\u672C\u6587\u3092\u76F4\u63A5\u6307\u5B9A\u3059\u308B\uFF08\u4E00\u884C\u5411\u3051\u3002--body-file \u3068\u306E\u4F75\u7528\u306F\u30A8\u30E9\u30FC\uFF09",takesValue:true,placeholder:"<\u6587\u5B57\
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{buildDiffLines,diffStat}from"./chunk-VRBI2NPI.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import{EXIT_API_CLIENT,EXIT_API_SERVER,EXIT_AUTH,EXIT_FAILURE,EXIT_OK,EXIT_USAGE}from"./chunk-
|
|
3
|
+
import{buildDiffLines,diffStat}from"./chunk-VRBI2NPI.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import{EXIT_API_CLIENT,EXIT_API_SERVER,EXIT_AUTH,EXIT_FAILURE,EXIT_OK,EXIT_USAGE}from"./chunk-7WSNIXTQ.js";import"./chunk-VSJBJXZO.js";import*as fs from"fs";var DEFAULT_CHARTER_FILE="CONSTITUTION.md";async function runCharterCommand(deps,opts){const out=deps.out??(t=>void process.stdout.write(stripTerminalControls(t)));const err=deps.err??(t=>void process.stderr.write(stripTerminalControls(t)));const readFile=deps.readFile??(p=>new TextDecoder("utf-8",{fatal:true,ignoreBOM:true}).decode(fs.readFileSync(p)));const writeFile=deps.writeFile??((p,c)=>fs.writeFileSync(p,c,"utf8"));const exists=deps.exists??(p=>fs.existsSync(p));return opts.op==="push"?push(
|
|
4
4
|
deps.api,opts,{out,err,readFile}):pull(deps.api,opts,{out,err,readFile,writeFile,exists})}async function push(api,opts,io){if(opts.file===void 0){io.err("--file <\u30D1\u30B9> \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: --file CONSTITUTION.md\uFF09\n");return EXIT_USAGE}let expected;if(opts.revision!==void 0){if(!/^\d+$/.test(opts.revision)){io.err(`--revision \u306F0\u4EE5\u4E0A\u306E\u6574\u6570\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044: ${opts.revision}
|
|
5
5
|
`);return EXIT_USAGE}if(!opts.yes){io.err("--revision \u306F --yes \u3068\u4E00\u7DD2\u306B\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08--yes \u306A\u3057\u3067\u306F\u767B\u9332\u3057\u307E\u305B\u3093\uFF09\n");return EXIT_USAGE}expected=Number(opts.revision)}let local;try{local=io.readFile(opts.file)}catch(e){io.err(`\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u3081\u307E\u305B\u3093: ${opts.file}\uFF08${e.message}\uFF09
|
|
6
6
|
`);return EXIT_USAGE}const current=await fetchState(api,io.err);if(typeof current==="number")return current;const before=current.charter??"";if(current.charter!==null&¤t.charter===local){io.out(`\u5DEE\u5206\u306F\u3042\u308A\u307E\u305B\u3093\uFF08revision ${current.revision}\uFF09\u3002\u767B\u9332\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002
|
|
@@ -26,7 +26,7 @@ ${target} \u3092\u4E0A\u66F8\u304D\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u4E
|
|
|
26
26
|
`);return EXIT_API_SERVER}return state}function apiExit(res){if(res.status===401)return EXIT_AUTH;if(res.status!==null&&res.status>=400&&res.status<500)return EXIT_API_CLIENT;return EXIT_API_SERVER}function body(res){const json=res.json??{};const data=json["data"];if(data&&typeof data==="object"&&!Array.isArray(data)&&"revision"in data){return data}return json}function parseState(res){const b=body(res);const revision=pickNumber(b,"revision");if(revision===null)return null;const prompts=b["prompt\
|
|
27
27
|
s"];let charter=null;if(prompts&&typeof prompts==="object"){const v=prompts["charter"];if(typeof v==="string")charter=v}return{charter,revision,updatedByName:typeof b["updated_by_name"]==="string"?b["updated_by_name"]:"",updatedAt:typeof b["updated_at"]==="string"?b["updated_at"]:""}}function pickNumber(b,key){const v=b[key];return typeof v==="number"&&Number.isInteger(v)&&v>=0?v:null}function errorDetail(res){if(res.status===null)return`transport_error=${res.transportError??"\u4E0D\u660E"}`;const json=res.
|
|
28
28
|
json??{};const data=json["data"]&&typeof json["data"]==="object"?json["data"]:{};const errorField=json["error"];const errorObj=errorField&&typeof errorField==="object"?errorField:{};const reason=(typeof errorField==="string"?errorField:"")||str(errorObj["code"])||str(json["reason"])||str(data["reason"]);const message=str(json["error_description"])||str(errorObj["message"])||str(json["message"])||str(data["message"]);const parts=[`http=${res.status}`];if(reason)parts.push(`reason=${reason}`);if(message)
|
|
29
|
-
parts.push(message.slice(0,300));const errors=json["errors"]??data["errors"];if(errors&&typeof errors==="object")parts.push(JSON.stringify(errors).slice(0,300));if(!reason&&!message)parts.push(`\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,160)}`);return parts.join(" ")}function str(v){return typeof v==="string"?v:""}var HIDDEN_CHARS=/[\x00-\x08\x0B-\x1F\x7F-\x9F\u200B-\u200F\u202A-\u202E\u2060-\u2069\uFEFF]/g;function printDiff(out,fromLabel,toLabel,before,after){const lines=buildDiffLines(
|
|
29
|
+
parts.push(message.slice(0,300));const errors=json["errors"]??data["errors"]??json["error_list"];if(errors&&typeof errors==="object")parts.push(JSON.stringify(errors).slice(0,300));if(!reason&&!message)parts.push(`\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,160)}`);return parts.join(" ")}function str(v){return typeof v==="string"?v:""}var HIDDEN_CHARS=/[\x00-\x08\x0B-\x1F\x7F-\x9F\u200B-\u200F\u202A-\u202E\u2060-\u2069\uFEFF]/g;function printDiff(out,fromLabel,toLabel,before,after){const lines=buildDiffLines(
|
|
30
30
|
before,after);const{added,removed}=diffStat(lines);out(`--- ${fromLabel}
|
|
31
31
|
+++ ${toLabel}
|
|
32
32
|
`);for(const l of lines)out(`${l.sign} ${l.text}
|