@tocca-systems/twp-cli 0.23.0 → 0.25.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.
Files changed (71) hide show
  1. package/CHANGELOG.public.md +14 -0
  2. package/README.md +240 -6
  3. package/command-model/department.json +1 -1
  4. package/dist/agent-loop-ZP47LTUE.js +75 -0
  5. package/dist/{api-command-CLARDKAL.js → api-command-VWJXBUCJ.js} +3 -3
  6. package/dist/{app-X3IKIAKB.js → app-3JIU5OUX.js} +49 -48
  7. package/dist/attendance-42XLURM7.js +21 -0
  8. package/dist/{auto-update-FBZGOQFI.js → auto-update-CV2MM32C.js} +1 -1
  9. package/dist/{auto-update-worker-SI7TVSCN.js → auto-update-worker-OBFGN6FY.js} +2 -2
  10. package/dist/{backlog-X2MQTA6F.js → backlog-KSMQIC2R.js} +2 -2
  11. package/dist/charter-command-ULFOEZWE.js +26 -0
  12. package/dist/{chunk-APYYF7H6.js → chunk-5Q2CH4E7.js} +1 -1
  13. package/dist/{chunk-M3GWY6NT.js → chunk-7WSNIXTQ.js} +2 -1
  14. package/dist/chunk-BKZGBJWT.js +15 -0
  15. package/dist/chunk-DDKZ5IPT.js +11 -0
  16. package/dist/chunk-FTYJZFEK.js +10 -0
  17. package/dist/{chunk-2VISRLWS.js → chunk-G4OO4M44.js} +9 -9
  18. package/dist/{chunk-E4H22AO5.js → chunk-GDM2QUBL.js} +1 -1
  19. package/dist/{chunk-X4RS5VBH.js → chunk-GMBJTG6A.js} +1 -1
  20. package/dist/{chunk-QVXZEUKN.js → chunk-HGTG5XQ7.js} +1 -1
  21. package/dist/{chunk-DSDVIU6A.js → chunk-ILKQDXI5.js} +1 -1
  22. package/dist/{chunk-O52CUEDO.js → chunk-IOGVQVGD.js} +1 -1
  23. package/dist/chunk-IRAZ27WL.js +38 -0
  24. package/dist/{chunk-7PRQ7JW2.js → chunk-KEP5QSS4.js} +40 -15
  25. package/dist/chunk-KUIFIN7P.js +57 -0
  26. package/dist/{chunk-JB27KNCX.js → chunk-NIAOX77K.js} +29 -25
  27. package/dist/chunk-P4AEFKLM.js +13 -0
  28. package/dist/{chunk-SJRK4AVE.js → chunk-PK6CUUAQ.js} +1 -1
  29. package/dist/chunk-SP27PYHC.js +3 -0
  30. package/dist/chunk-UDPJ2IGK.js +7 -0
  31. package/dist/chunk-VCZVITWG.js +13 -0
  32. package/dist/{chunk-XLE4HW6B.js → chunk-VGMWPPGD.js} +12 -10
  33. package/dist/{chunk-UG2I6VRD.js → chunk-VYDEUFGU.js} +1 -1
  34. package/dist/{chunk-Y2QAP6SU.js → chunk-WQ66EYZS.js} +1 -1
  35. package/dist/chunk-X45SJNT2.js +62 -0
  36. package/dist/{chunk-EQWW2F5V.js → chunk-YVAN3H5W.js} +4 -4
  37. package/dist/chunk-YWGYRISN.js +34 -0
  38. package/dist/{chunk-WOUKWOAR.js → chunk-Z2MNO3FT.js} +10 -9
  39. package/dist/chunk-ZN5EFDH7.js +5 -0
  40. package/dist/chunk-ZWVYVS2A.js +4 -0
  41. package/dist/cli.js +100 -8
  42. package/dist/{commands-BE67IDNQ.js → commands-OFLBUP6O.js} +8 -8
  43. package/dist/{commands-JNG5TZ77.js → commands-RG7M6E5K.js} +79 -84
  44. package/dist/department-GH475WCF.js +33 -0
  45. package/dist/job-title-FC2GWDE7.js +8 -0
  46. package/dist/{logout-guard-CMZZBRUL.js → logout-guard-3PB3VMGP.js} +1 -1
  47. package/dist/media-TD7D4TXF.js +64 -0
  48. package/dist/{oneshot-NA756EBO.js → oneshot-QQOOZZDT.js} +5 -5
  49. package/dist/position-4RHTV3IK.js +8 -0
  50. package/dist/{project-2LJZW747.js → project-DBNWB47J.js} +1 -1
  51. package/dist/query-EEALMOSO.js +3 -0
  52. package/dist/{render-ICZOK3HV.js → render-K45EOLHX.js} +1 -1
  53. package/dist/{run-XCAJDHFU.js → run-VNHAQO24.js} +2 -2
  54. package/dist/{schedule-command-GKXKNMLG.js → schedule-command-FJU7JFNR.js} +1 -1
  55. package/dist/{server-settings-CG3EM7R7.js → server-settings-YL6KALXG.js} +1 -1
  56. package/dist/{setup-UI6V2Q3V.js → setup-BJKIHANC.js} +1 -1
  57. package/dist/skill-command-V26WGVXU.js +61 -0
  58. package/dist/storage-ANKKJJJO.js +3 -0
  59. package/dist/{task-GKNM3G4K.js → task-7VOYCG26.js} +7 -63
  60. package/dist/{update-TVVBJNN7.js → update-RLKK6N7U.js} +1 -1
  61. package/dist/user-UU2SLVC4.js +336 -0
  62. package/package.json +1 -1
  63. package/dist/charter-command-UPKTVL7H.js +0 -36
  64. package/dist/chunk-7LTTKKQA.js +0 -56
  65. package/dist/chunk-GFC2ASHE.js +0 -6
  66. package/dist/chunk-JKSXUBND.js +0 -9
  67. package/dist/chunk-LD3AKGH6.js +0 -30
  68. package/dist/chunk-ODLJ2LNQ.js +0 -13
  69. package/dist/chunk-PEGUHUTD.js +0 -3
  70. package/dist/query-NJMVSQR6.js +0 -3
  71. package/dist/user-EU7Z3DAO.js +0 -24
@@ -11,6 +11,20 @@
11
11
  `CHANGELOG.md` に残してあります。顧客向けの履歴は public 公開以降を対象とします。
12
12
  -->
13
13
 
14
+ ## 0.25.0
15
+
16
+ `twp user assignment move --file <CSV>` で、4月の定期異動のような多人数の異動を一度に流せるようになりました。送る前に全行を確認し、誤りのある行が1つでもあれば何も変更せずに、その行番号と理由をすべて表示します。`--dry-run` を付けると、各行で終了する所属と新しく作る所属を確認できます。途中で失敗した場合はそこで止め、どの行まで反映されたかと元に戻すコマンドを表示します。
17
+
18
+ `twp attendance` で自分の勤怠を確認できるようになりました。`twp attendance status` でいまの打刻状態と次に打てる打刻を、`twp attendance list` で打刻の履歴を、`twp attendance timesheet` で月の勤怠表(日別の出退勤・労働時間・残業と月の合計)を表示します。年月は `--month 2026-08`、日付は `--date 2026-08-31` の形で指定します。
19
+
20
+ `twp task-loop` の定期実行で、「このステータスのタスクが0件なら実行する」という条件の数え方を、ループ設定の `operations.count_hooks` で独自のコマンドに差し替えられるようになりました。コマンドが失敗したときは、従来どおりステータスの件数で判定します。
21
+
22
+ エージェントループの実行記録が、長いセッションでも最初から最後まで残るようになりました。これまでは長い実行の序盤が記録から欠けることがありました。記録の保存に失敗した場合も、ループはこれまでどおり動き続けます。
23
+
24
+ エージェントループのキューを `twp agent-loop` で扱えるようになりました。`twp agent-loop list` で並んでいるアイテムを確認し、`twp agent-loop create --prompt "/twp-fix-bug ABC-123"` でアイテムを投入できます。`move <アイテムID> --yes` でキューの先頭へ移し、`update` / `delete` で内容の変更・削除ができます(この3つはテナントの管理者だけが行えます)。`twp agent-loop history list --since 2026-09-01` で期間を指定して実行履歴を確認できます。
25
+
26
+ エージェントループ用のスキル定義を、プロジェクト単位でサーバに登録・展開できるようになりました。`twp task-loop skill push --project <キー> <名前>`(全件は `--all`)で `.claude/commands/<名前>.md` を登録します。最初の実行では差分だけを表示し、案内されたコマンドで確定します。その間にサーバ側で更新されたスキルがあれば、上書きせずに止まります。`twp task-loop skill pull --project <キー> <名前>`(全件は `--all`)でサーバの定義をファイルへ書き出します。既存のファイルと内容が違うときは差分を表示し、`--yes` を付けたときだけ上書きします。どちらの向きでも、片側にしか無いスキルは削除しません。シンボリックリンクになっているファイルは読み書きしません。
27
+
14
28
  ## 0.23.0
15
29
 
16
30
  会話の中で AI が TWP のデータを調べて使えるようになりました。AI は必要な操作を検索し、内容を確かめてから実行します。TWP のデータを読む・書く操作は、実行前に確認が表示されます(削除は毎回確認します)。
package/README.md CHANGED
@@ -20,8 +20,12 @@ 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 一括・再送・取消)、ユーザーと所属(部署・役職)の参照(一覧・取得・所属の履歴)、所属の付け替え(異動)・作成・更新・終了・削除、在籍者の棚卸と人事台帳 CSV との突き合わせ。作成・更新・招待と取得、所属の書き込み、他人の所属の参照、棚卸は組織管理者の権限が要ります |
24
+ | **できる** | `twp department` / `twp position` / `twp job-title` による組織マスタ(部署・役職・職位)の一覧・取得・作成・更新・削除と、部署ツリー・部署の所属者の表示。作成・更新・削除は管理者の権限が要ります |
25
+ | **できる** | `twp media` によるメディアライブラリのファイルのアップロード・一覧・ダウンロード・削除(ゴミ箱へ移す)・一括操作(公開・非公開・アーカイブ・移動・削除・復元・ZIP ダウンロード)、`twp storage get` によるストレージ使用量の確認(管理者) |
26
+ | **できる** | `twp attendance` による自分の勤怠の参照(いまの打刻状態・打刻の履歴・月の勤怠表) |
24
27
  | **できる** | `twp task-loop` による、TWP のタスクキューを手元の AI CLI に実行させる常駐ループ |
28
+ | **できる** | `twp agent-loop` による、エージェントループのキューの一覧・投入・更新・先頭への移動・削除と、期間を指定した実行履歴の参照。更新・移動・削除はテナントの管理者の権限が要ります |
25
29
  | **できる** | スラッシュコマンド: `/help` `/mode` `/model` `/clear` `/context` `/doctor` `/exit` `/demo`(動作デモ) `/tasks` `/task` `/projects`。`/tasks` などの TWP 系は `twp task list` と同じ結果を画面に出すだけで、AI は動かしません(クレジットも消費しません)。スラッシュコマンドは TUI の中だけで使えます(`twp -p` では解釈しません) |
26
30
  | **できる** | 自分用のスラッシュコマンドを markdown で追加すること(`.twp/commands/*.md` / `~/.twp/commands/*.md`・[下記](#スラッシュコマンドを自分で足す))。入力中の `@パス` でファイルを、`#ABC-123` でタスクの内容を AI へ添付できます |
27
31
  | **まだできない** | **会話中の AI が自分から TWP のデータを参照・操作すること。** AI に読ませたいタスクは `#ABC-123` と書いて添付してください。起票・更新などの操作は `twp task` コマンドをお使いください |
@@ -108,7 +112,7 @@ twp task label list [--project <コード>]
108
112
  - **フラグの値は `--flag 値` でも `--flag=値` でも書けます。** 空白を含む値は `--keyword "山田 太郎"` のように引用し、`-` で始まる値は `--keyword=-foo` の形で渡します
109
113
  - **質問(`--ask-question`)は質問文(`--question` / `--question-file`)と選択肢(`--option キー=表示文`・1〜5個)が要ります。** 選択肢のキーは10文字以内で、回答(`--select`)に使う識別子です。複数選択は `--multi-select`、自由記述を禁じるなら `--no-free-text`
110
114
  - **`twp task comment list` の `question` / `answer` 列で、回答済みかどうかが分かります**(同じページにある回答を質問の行へ突き合わせます。ページをまたぐ場合は `--all` を付けてください)
111
- - **`twp task attachment upload` はアップロード用URLの発行・ファイルの転送・タスクへの紐づけを1コマンドで行います。** 既にある添付は残したまま追加します。紐づけに失敗したときは添付IDを stderr に出して失敗で終わります(紐づけていない添付はサーバが自動で削除するので、そのまま再実行して構いません)。`--dry-run` は最初のリクエスト(URLの発行)だけを表示します
115
+ - **`twp task attachment upload` はアップロード用URLの発行・ファイルの転送・タスクへの紐づけを1コマンドで行います。** 既にある添付は残したまま追加します。紐づけに失敗したときは添付IDを stderr に出して失敗で終わります(紐づけていない添付はサーバが自動で削除するので、そのまま再実行して構いません)。`--dry-run` はURLの発行リクエストだけを表示します(その前に送る容量検査は注記で知らせます)
112
116
  - `twp task attachment download` は `twp backlog attachment download` と同じく **`--out` のパスへ実体を書き出し、既存ファイルは `--force` を付けたときだけ上書きします**。添付ID は `twp task attachment list` の `id` です
113
117
  - ヘルプは `twp task help` / `twp task comment help` / `twp task create help` / `twp task attachment help`
114
118
 
@@ -134,12 +138,205 @@ twp user assignment list <ユーザー> [--current] # 本人・上長・組織
134
138
  - **`<ユーザー>` は ID・メールアドレス・社員番号・氏名・`me`(自分)で指定できます。** 氏名は完全一致で1人に絞れたときだけ受け付け、同姓同名なら候補を出して止まります(メールアドレスか社員番号で指定し直してください)
135
139
  - **表示フラグを外したユーザーは、ID・メールアドレス・氏名で指定してください**(社員番号では引けません。組織管理者でない場合は ID だけです)。一覧に出すときは `--include-hidden` を付けます(組織管理者のときだけ効きます)
136
140
  - **`--department` / `--position` は名前・コード・ID のどれでも指定できます**(主所属で絞り込みます)。候補が絞れないときは候補を出して止まります
137
- - **失効(ログイン不可)したユーザーも一覧に出ます。** 失効かどうかは `twp user get` の `auth_type`(`disabled` なら失効)で確認できます
141
+ - **失効(ログイン不可)したユーザーも一覧に出ます。** 失効かどうかは `twp user get` の `auth_type`(`disabled` なら失効)で確認できます。全員の認証タイプを一覧で見るなら `twp user export --include-disabled`
138
142
  - `twp user get` の要約(table / text / tsv)には個人連絡先を出しません。`--output json` は API が返す全フィールドを出します
139
143
  - `twp user assignment list` の `is_primary` は主務、`is_approval_route` はワークフローの上長承認に使われる所属です。部署名・役職名を表示するため、部署一覧と役職一覧も取得します
140
144
  - 権限が無いときは HTTP 403 をそのまま出さず、誰の権限が要るかを案内します(終了コードは 3)
141
145
  - 組織管理者でなくても `twp user list` は使えます(表示フラグが付いたユーザーだけが出ます)
142
- - ヘルプは `twp user help` / `twp user assignment help`
146
+ - ヘルプは `twp user help` / `twp user assignment help` / `twp user invite help`
147
+
148
+ ### ユーザーを作成・更新する(入社・退社)
149
+
150
+ 組織管理者向けです。
151
+
152
+ ```
153
+ twp user create --name <氏名> --email <メールアドレス> --password-file <パス|->
154
+ [--role admin|user] [--kana <フリガナ>] [--hire-date <YYYY-MM-DD>] [--employee-code <社員番号>]
155
+ [--display true|false] [--memberlist true|false] [--org-chart true|false] [--dashboard true|false]
156
+ twp user update <ユーザー> [上と同じ項目] [--auth-type all|password|oauth|disabled]
157
+ ```
158
+
159
+ - **パスワードはコマンド行に置けません**(シェルの履歴とプロセス一覧に残るため)。`--password-file` にファイルのパスを渡すか、`-` を渡して標準入力から渡します。末尾の改行1つは取り除きます。8文字以上です
160
+ - `--role` を省くと一般ユーザー(`user`)で作成します。表示フラグを省くと、すべて表示する(`true`)で作成します。機能権限はテナントの既定で付与され、ライセンスの空きが足りない機能は付与されずに stderr へ出ます
161
+ - **`twp user update` は指定した項目だけを変更します**(指定しなかった項目は変わりません)。何も指定しないとエラーになります
162
+ - **表示フラグを外したユーザーは社員番号では指定できません**(メールアドレスか ID で指定してください)。作成・更新の直後に社員番号で指定するときは `--refresh` を付けます(ユーザー一覧は10分キャッシュします)
163
+ - メールアドレスが既に使われているなどでサーバが断ったときは、その理由を出して終了コード 3 で終わります
164
+
165
+ #### 退社したユーザーを失効させる
166
+
167
+ 退社は専用のコマンドを持たず、画面と同じく**認証タイプを `disabled`(画面の「無効(ログイン不可)」)にして失効させます**。一覧・組織図などから外すなら、表示フラグも `false` にします。
168
+
169
+ ```bash
170
+ twp user update yamada@example.com --auth-type disabled \
171
+ --display false --memberlist false --org-chart false --dashboard false
172
+ ```
173
+
174
+ - 失効させたユーザーは新しくログインできず、発行済みのトークン・API キーもサーバが失効させます
175
+ - ユーザーは削除できません。失効させた状態で残ります
176
+ - **取り消す(再入社・誤操作)ときも同じ `twp user update` で戻します。** 失効前の認証タイプは記録されないので、**失効させる前に `twp user get <ユーザー>` の `auth_type` を控えておき**、その値へ戻してください(`all` はパスワードと OAuth の両方を許します。SSO だけのユーザーを `all` に戻すとパスワードでもログインできるようになります)
177
+
178
+ ```bash
179
+ # 失効前の auth_type が all だった場合
180
+ twp user update yamada@example.com --auth-type all \
181
+ --display true --memberlist true --org-chart true --dashboard true
182
+ ```
183
+
184
+ - 失効かどうかは `twp user get <ユーザー>` の `auth_type` で確認できます。退職日・所属の終了・ライセンスの回収はこのコマンドでは行いません(所属の終了は `twp user assignment end`)
185
+
186
+ ### 所属を付け替える(異動)・作成する・終了する
187
+
188
+ 組織管理者向けです。
189
+
190
+ ```
191
+ twp user assignment move <ユーザー> --department <部署> --start-date <異動日> [--position <役職>] [--manager <ユーザー>] …
192
+ twp user assignment move --file <CSV>
193
+ twp user assignment create <ユーザー> --department <部署> --position <役職> --start-date <YYYY-MM-DD> [--primary true|false] …
194
+ twp user assignment update <所属ID> --user <ユーザー> [--manager <ユーザー> | --no-manager] [--end-date <YYYY-MM-DD|none>] …
195
+ twp user assignment end <所属ID> --user <ユーザー> --end-date <YYYY-MM-DD>
196
+ twp user assignment delete <所属ID> --user <ユーザー> --yes
197
+ ```
198
+
199
+ - **異動は `move` を使います。** 現在の主所属を異動日の前日で終え、異動日から新しい主所属を作ります。サーバへは1本の要求で送り、送る前に「終了する所属」と「作る所属」を並べて表示します。`--dry-run` を付ければ送らずに確認できます
200
+ - `move` は**役職と職位を現在の主所属から引き継ぎます**(`--position` / `--job-title` を指定すればそちらを使い、`--no-job-title` で職位を外します)。**上長・観察者・面談者・メンターは引き継ぎません**——旧上長のまま承認経路が残らないよう、新しい所属では指定したものだけが設定されます
201
+ - 異動日が未来なら新しい所属は予約になり、開始日の日次処理で切り替わります(それまでは現在の主所属が有効です)。今日以前ならすぐに切り替わります。月初を異動日にすると、現在の主所属は前月末で終わります
202
+ - 送信が途中で失敗したときは、所属を読み直して「どこまで反映されたか」と元に戻すコマンドを出します。成功したときも、取り消すためのコマンドを stderr に出します
203
+ - **多人数の異動(4月の定期異動など)は `move --file <CSV>` で一度に流せます。** CSV の1行が1人で、列は「ユーザー, 部署, 異動日, 役職, 職位, 上長, 観察者」です(後ろの4列は省略・空欄にでき、役職・職位の空欄は現在の主所属から引き継ぎ、職位に `none` で外します。観察者は `;` 区切りで複数。1行目のヘッダは省略できます)
204
+
205
+ ```
206
+ user,department,start_date,position,job_title,manager,observers
207
+ yamada@example.com,開発部,2027-04-01,,,suzuki@example.com,
208
+ sato@example.com,営業部,2027-04-01,主任,none,,tanaka@example.com;ito@example.com
209
+ ```
210
+
211
+ - **送る前に全行を検査し、不正な行が1つでもあれば1件も送りません**(名前解決・日付・1行ずつの `move` と同じ開始日と予約済み主所属の検査・同じユーザーの重複)。不正な行は行番号と理由をすべて出して終了コード 2 で終わります
212
+ - `--dry-run` で全行の「終了する所属」「作る所属」を確認できます
213
+ - サーバに一括の API は無いので、1行ずつ送ります。**送信中に失敗したらそこで止め**、成功した行・失敗した行・未送信の行を行番号つきで出し、成功した行を元に戻すコマンドを出します(終了コード 3)。続きは成功した行を CSV から除いて流し直します
214
+ - 主所属として作るとき(`move` と、`--primary false` でない `create`)は、次の場合に送らずに止めます: 開始日が現在の主所属の開始日以前(開始日より前に終わる所属になる)/予約済みの主所属が別にある(主所属が2つ重なる)。兼務・代理は `create --primary false --type concurrent|acting` で足します
215
+ - **`create` は `--primary` を省くと主所属として作ります**(サーバの既定と同じ)。主所属として作ると現在の主所属は開始日の前日で終わるので、兼務なら `--primary false` を付けてください
216
+ - 所属 ID は `twp user assignment list <ユーザー>` の `id` 列です。`update` / `end` / `delete` は、所属を持つユーザーを `--user` で必ず指定します
217
+ - 退職・異動で所属を終えるときは、履歴が残る `end` を使います。`delete` は誤って作った所属を消すためのものです
218
+ - `--department` / `--position` / `--job-title` は名前・コード・ID、`--manager` / `--interviewer` / `--mentor` / `--observer`(複数回指定できる)はユーザーを ID・メールアドレス・社員番号・氏名で指定できます
219
+ - CSV での一括異動は未対応です
220
+
221
+ ### 在籍者を棚卸する(人事台帳との突き合わせ)
222
+
223
+ 組織管理者向けです。在籍者(認証タイプが `disabled` でないユーザー)を1人1行で出し、人事台帳の CSV と突き合わせます。
224
+
225
+ ```
226
+ twp user export [--include-disabled] [--exclude-hidden] # 在籍者の一覧
227
+ twp user export --file <台帳CSV> [--inactive-days <日数>] # 台帳との差分
228
+ twp user export --output tsv > inventory.tsv # 表計算ソフトへ
229
+ ```
230
+
231
+ - **列**: `user_id` / 氏名 / メールアドレス / 社員番号 / 入社日 / 主所属の部署・役職 / 上長 / 権限(機能ごとのレベル。`none` は省く)/ パートナーか / 認証タイプ / 表示フラグ / 最終ログイン。**個人連絡先(個人メール・緊急連絡先など)は出しません**。tsv / table では `=` `+` `-` `@` で始まる値の先頭に `'` を付けます(表計算ソフトが式として読まないように)
232
+ - **表示フラグを外したユーザーも既定で含めます**(表示フラグだけ外して失効させていない人を見つけるため)。表示中のユーザーだけにするなら `--exclude-hidden`。失効済みも出すなら `--include-disabled`
233
+ - **最終ログインはログイン履歴から取ります。** ログイン履歴は90日で消えるので「90日以内の記録なし」は一度もログインしていないという意味ではありません。また **Google / Microsoft の SSO でのログインは記録されない**ため、認証タイプが `oauth` の人は「判定不能」と出し、長期未ログインの判定から外します
234
+ - `--file` を付けると差分だけを出します。`kind` 列は次のとおりです
235
+
236
+ | `kind` | 意味 |
237
+ |---|---|
238
+ | `not_in_ledger` | TWP で失効していないが台帳にいない(退社時の失効漏れ。パートナーや共用アカウントも出ます) |
239
+ | `missing_in_twp` | 台帳にいるが TWP にいない(登録漏れ) |
240
+ | `disabled_in_twp` | 台帳にいるが TWP で失効している(誤失効) |
241
+ | `ambiguous` | 台帳の1行が TWP の複数のユーザーに一致し、決められない |
242
+ | `department_mismatch` / `position_mismatch` | 部署・役職が違う(異動の反映漏れ。台帳にその列があるときだけ) |
243
+ | `inactive` | ログインできるのに `--inactive-days` 日(既定60・最大90)ログインの記録が無い(入社直後の人と `oauth` の人は出しません) |
244
+
245
+ - **台帳 CSV は1行目が見出し**で、UTF-8 と Shift_JIS(Excel の既定)を読めます。`社員番号` / `氏名` / `メールアドレス` / `部署` / `役職` などの列名を自動で探し、違うときは `--code-column` / `--name-column` / `--email-column` / `--department-column` / `--position-column` で指定します(見出しが単に「メール」の列は個人メールのことがあるので自動では使いません)。使う列は実行前に表示するので、`--dry-run` で確かめられます
246
+ - 人は**社員番号 → メールアドレス → 氏名の順に試し、最初に TWP の誰かに当たった列**で突き合わせます(Excel で社員番号の先頭の0が落ちても、メールアドレスで救えます)
247
+ - 各行の `user_id` は `twp user update` / `twp user assignment` へ渡せます。`suggestion` 列は次に打つコマンドの**案**です(失効・異動・役職変更・招待)。`'<異動日>'` などの `<…>` は埋めてから、対象が自分自身や共用の管理アカウントでないことを確かめて実行してください。`twp user assignment move` は上長を引き継がないので、必要なら `--manager` も付けます
248
+ - 1人あたり最大3往復します。本番の API レート制限に合わせて1分あたり200本までに抑えて送るため、数百人のテナントでは数分かかります。対象が `--max-users`(既定 2,000 人)を超えると、詳細を読む前に止まります
249
+
250
+ ### ユーザーを招待する
251
+
252
+ 組織管理者向けです。招待されたメールアドレスへ招待メールが届き、本人が氏名とパスワードを入力して登録します。
253
+
254
+ ```
255
+ twp user invite create --email <メールアドレス> [--role user|admin|super_admin] [--name <氏名>]
256
+ twp user invite bulk --file <CSV> # 1回 50 件まで
257
+ twp user invite list # 期限内の未受諾だけ
258
+ twp user invite resend <メールアドレス>
259
+ twp user invite delete <メールアドレス> --yes
260
+ ```
261
+
262
+ 一括招待の CSV は「メールアドレス, 権限」の2列です(1行目のヘッダ `email,role` は省略できます)。**氏名の列は置けません**——一括招待では氏名は送られず、受諾時に本人が入力します。
263
+
264
+ ```csv
265
+ email,role
266
+ new.member@example.com,user
267
+ leader@example.com,admin
268
+ ```
269
+
270
+ - **送る前に全行を検査し、形の誤り・権限の誤り・列数の誤り・重複がある行が1つでもあれば1通も送りません。**(重複を拒むのは、サーバが同じアドレスの招待を後の行で置き換え、先の招待リンクが黙って無効になるためです) その行番号と理由をすべて出して終了コード 2 で終わります(サーバは1行の誤りで全件を拒むため)。`--dry-run` で送る内容の一覧を確認できます
271
+ - 送った後にサーバが一部の行を断ったとき(既に使われているメールアドレス等)は、**失敗した行と送信済みの行を行番号つきで stderr に出して終了コード 3** で終わります。送信済みの行は取り消されないので、打ち直す CSV に含めないでください
272
+ - 招待の件数が多いと、一部はサーバの送信待ちの列に入ります(stderr で知らせます)。届かなければ `twp user invite resend` で再送できます
273
+ - `twp user invite list` に出るのは**期限内の未受諾の招待だけ**です。期限が切れた招待は再送も取消もできないので、`twp user invite create` で招待し直してください
274
+ - `resend` / `delete` はメールアドレスで指定します(未受諾の招待が1件に絞れたときだけ受け付けます)。トークンは招待を受諾できる秘密なので、`twp user invite list` では伏字で出ます(`--no-redact` で表示)
275
+
276
+ ### 組織マスタ(部署・役職・職位)を扱う
277
+
278
+ 作成・更新・削除は管理者向けです。一覧・取得・ツリー・所属者は、ログインしていれば使えます。
279
+
280
+ ```
281
+ twp department list [--status active|inactive] [--keyword <語>] [--limit <件数>]
282
+ twp department tree # 現在有効な部署だけ
283
+ twp department members <部署> [--include-past]
284
+ twp department get <部署>
285
+ twp department create --code <コード> --name <部署名> [--parent <部署>] [--valid-from <YYYY-MM-DD>] [--valid-to <YYYY-MM-DD>] …
286
+ twp department update <部署> [--name <部署名>] [--parent <部署> | --no-parent] [--valid-to <YYYY-MM-DD|none>] …
287
+ twp department delete <部署> --yes
288
+
289
+ twp position list | get <役職> | create --code <コード> --name <役職名> [--rank <0〜9999>] [--manager true|false] … | update <役職> … | delete <役職> --yes
290
+ twp job-title list | get <職位> | create --code <コード> --name <職位名> [--position <役職>] … | update <職位> [--position <役職> | --no-position] … | delete <職位> --yes
291
+ ```
292
+
293
+ - **`<部署>` / `<役職>` / `<職位>`、`--parent`、`--position` は名前・コード・ID のどれでも指定できます。** 名前が複数に一致すれば候補を出して止まります。一覧は10分キャッシュするので、作成・改名の直後に名前で指定するときは `--refresh` を付けてください(ID ならそのまま通ります)
294
+ - `update` は指定した項目だけを変更します。何も指定しないとエラーになります
295
+ - **部署の有効・無効は有効期間から決まります**(状態は直接指定できません)。`--valid-to` を設定するとその日の翌日から無効になり、`--valid-to none` で取り消すと有効に戻ります(有効開始日が未来なら、その日までは無効のままです)。`twp department list --status` は保存済みの状態で絞るため、境目の直後は1日ずれることがあります(実際の状態は `effective_status` 列)。役職・職位は `--status active|inactive` で切り替えます
296
+ - `twp department members` の行は所属(assignment)で、`user_id` が所属者です(氏名は `twp user get <user_id>` で確認できます)。既定は現在の所属だけで、`--include-past` を付けると現在でない所属(終了した所属と、開始日前の予約)も後ろに続けて出します。実際の状態は `effective_status` 列(`active` / `ended` / `scheduled`)で見てください
297
+ - `twp department tree` は現在有効な部署だけを親子の順に出します(table / text / tsv では `depth` と字下げした名前、`--output json` はサーバの木構造のまま)。無効な部署も含めた全件は `twp department list` です
298
+ - 一覧は API がページングを持たず、`--limit` 件(既定 1000)で打ち切ります。打ち切ったときは stderr で知らせます
299
+ - **所属者がいる(過去の所属履歴を含む)・子部署がある部署、所属から参照されている役職・職位は削除できません**(サーバが断ります)。そのときはサーバの理由に続けて、次に打つコマンドを案内します(部署は `--valid-to` で無効化、子部署は `--parent` で移す、役職・職位は `--status inactive` で無効化)。終了コードは 3 です
300
+ - ヘルプは `twp department help` / `twp position help` / `twp job-title help`
301
+
302
+ ### メディアライブラリのファイルを扱う
303
+
304
+ ```bash
305
+ twp media list [--project <コード|ID>] [--folder <フォルダID>] [--keyword <語>] [--all]
306
+ twp media upload --file <パス> [--project <コード|ID>] [--folder <フォルダID>] [--name <ファイル名>] [--content-type <型>]
307
+ twp media download <ファイルID> --out <パス> [--force]
308
+ twp media delete <ファイルID> --yes
309
+ twp media bulk-publish | bulk-unpublish | bulk-archive | bulk-restore <ファイルID>...
310
+ twp media bulk-move <ファイルID>... [--project <コード|ID>] [--folder <フォルダID>]
311
+ twp media bulk-delete <ファイルID>... --yes [--permanent]
312
+ twp media bulk-download <ファイルID>... --out <パス.zip> [--force]
313
+ twp storage get
314
+ ```
315
+
316
+ - **`--project` を付けたときだけプロジェクトのファイル**、無ければ自分の個人ファイルが対象です(`TWP_PROJECT` などの既定プロジェクトは使いません)。フォルダはフォルダID(UUID)で指定します
317
+ - **`twp media upload` はアップロード用URLの発行・ファイルの転送・完了登録を1コマンドで行い、サーバが計算した sha256 をローカルのファイルと突き合わせます。** 一致しなければ失敗で終わります。`--dry-run` はURLの発行リクエストだけを表示します(その前に送る容量検査は注記で知らせます)
318
+ - **転送や完了登録に失敗したときは、ファイルIDと再登録・破棄のコマンドを stderr に出して失敗で終わります。** タスク添付と違い、URLを発行した時点でファイルが仮登録され**自動では消えない**ので、表示されたコマンドのどちらかを実行してください
319
+ - `twp media delete` はゴミ箱へ移すだけで、画面から復元できます
320
+ - **アップロードの前に、テナントのストレージ容量を確かめます**(`twp task attachment upload` も同じ)。容量を超えるなら何も登録せず終了コード 3 で止まり、警告の閾値を超えているときは stderr で知らせます
321
+ - **一括操作(`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 件)
322
+ - `bulk-restore` はゴミ箱から戻す操作です(アーカイブの解除ではありません)。`bulk-delete --permanent` は**ゴミ箱にあるファイルだけ**を完全に削除します(先に `bulk-delete` でゴミ箱へ移してください)
323
+ - `twp storage get` は使用量・上限・残量と種類別の内訳を出します(管理者のみ。アップロード前の容量検査は誰でも自動で行われます)
324
+ - コマンド名は `twp task attachment` と同じ動詞(`upload` / `list` / `download`)に揃えています(`twp://` 形式のパスは採っていません)
325
+ - ヘルプは `twp media help`
326
+
327
+ ### 自分の勤怠を見る
328
+
329
+ ```bash
330
+ twp attendance status
331
+ twp attendance list [--month <YYYY-MM> | --date <YYYY-MM-DD>]
332
+ twp attendance timesheet [--month <YYYY-MM>]
333
+ ```
334
+
335
+ - 対象はログインしている本人の勤怠だけです。打刻・打刻の修正・申請はまだできません
336
+ - `--month` / `--date` を省くと今月です。「今月」はテナントの業務日の区切りでサーバが決めます
337
+ - 存在しない日付(`2026-02-30` など)や `YYYY-MM` 以外の年月は、送る前に引数エラー(終了コード 2)にします
338
+ - `twp attendance list` は新しい順です。`twp attendance timesheet` の時間は `H:MM` で、月の合計は stderr に出します。締め済みの月は、締めた時点の集計であることを知らせます
339
+ - ヘルプは `twp attendance help`
143
340
 
144
341
  ### Backlog の課題を読む・書く
145
342
 
@@ -197,6 +394,22 @@ twp task-loop stop
197
394
 
198
395
  実行前に「[⚠️ 実行する前に理解しておくこと(信頼境界)](#️-実行する前に理解しておくこと信頼境界)」を必ずお読みください。
199
396
 
397
+ キューに並ぶアイテムそのものは `twp agent-loop` で扱います(`twp task-loop` は実行機を動かすコマンドで、別物です)。
398
+
399
+ ```
400
+ twp agent-loop list [--status pending|processing|completed|failed] [--all]
401
+ twp agent-loop get <アイテムID>
402
+ twp agent-loop create --prompt "/twp-fix-bug ABC-123" [--priority P1] [--label "<ラベル>"] [--ai-effort high]
403
+ twp agent-loop update <アイテムID> [--label "<ラベル>"] [--ai-effort low|none] [--ai-type claude|none]
404
+ twp agent-loop move <アイテムID> --yes # キューの先頭へ(pending だけ)
405
+ twp agent-loop delete <アイテムID> --yes
406
+ twp agent-loop history list --since 2026-09-01 [--until <日付>] [--task-key ABC-123] [--full]
407
+ ```
408
+
409
+ - `create` のラベル(`[<優先度>] <ラベル> #ai:<カテゴリ>`)とカテゴリ・1番手の AI は、ループが計画から投入するときと同じ規則で、この端末のループ設定(`twp task-loop setup` が作る `~/.twp/loops/<プロジェクトID>.json`)から決まります。設定が無い端末では既定のカテゴリになり、その旨を表示します
410
+ - `create` は同じタスクのアイテムが既に並んでいても弾きません。確かめるには `twp agent-loop list --status pending --query "[?task_key=='ABC-123']"`
411
+ - `update` / `move` / `delete` はテナントの管理者だけが行えます(実行記録は監査の正本のため)。`create` はプロジェクトのメンバーなら行えます
412
+
200
413
  **モデル取次には `cli` 権限付きトークンが必要。** `twp login`(ブラウザ委譲)と `twp login --password` が発行する。`twp login --token` で保存した通常トークンは TWP API には使えるが会話は 401 になる。
201
414
 
202
415
  ### 自動アップデート
@@ -351,7 +564,7 @@ permissions:
351
564
  - front-matter より後ろの本文は、そのモードでの指示としてモデルへ渡る
352
565
  - **リポジトリ側(`.twp/modes/`)の定義は権限を緩められない。** 他人のリポジトリを clone しただけで確認なしにコマンドが走る状態を作らないため、`.twp/modes/` に書いた `allow` は無視して警告する(**厳しくする指定は効く**)。緩めるときは自分の `~/.twp/modes/` に書く
353
566
  - **書き間違えても起動は止まらない。** 読めなかった項目は警告を出して既定へ戻る。起動時に `⚠ モード定義:` が出たらその行を直す
354
- - いま何が効いているかは `/context` で確認できる(どのファイルが効いているか・有効ツール glob・常駐ツールの実体が出る)
567
+ - いま何が効いているかは `/context` で確認できる(どのファイルが効いているか・有効ツール glob・常駐ツールの実体・TWP ツールカタログの出どころ(サーバ配信か同梱版か)が出る)
355
568
 
356
569
  ### スラッシュコマンドを自分で足す
357
570
 
@@ -415,7 +628,7 @@ mode: dev
415
628
  - `Read(...)` の拒否は `grep` / `glob` にも効くが、**探索の起点がその範囲の中にあるときだけ**(リポジトリ全体を起点にした `grep` は、拒否した範囲の中まで読む)。確実に読ませないなら `Read` ごと拒否するか業務・プランモードを使う
416
629
  - 設定ファイルが読めない間は、読み取りも含めて**すべての自動許可が確認に変わる**(`-p` では確認できないので拒否になる)
417
630
  - `twp_call`(ツールを名前で呼ぶメタツール)は**中で実行されるツールの名前**(例: `twp_list_project-task`)で判定する。`twp_call` そのものを許可しても何も緩まない。TWP API のツールは読み取りも含めて既定で確認が出る(`-p` では拒否になる)ので、確認なしで使わせたいツールは名前で許可する(例: `--allowed-tools twp_list_project-task`)。**削除系(`destructive`)は許可ルールがあっても毎回確認する**
418
- - モデルが TWP を調べる手順は `twp_search_tools`(名前と1行説明だけ)→ `twp_describe_tools`(スキーマ)→ `twp_call`(実行)。カタログはパッケージ同梱のコマンドモデルで、ネットワークに取りに行かない。同じドメインを続けて使うときは `twp_mount` で次のターンから常駐させられる
631
+ - モデルが TWP を調べる手順は `twp_search_tools`(名前と1行説明だけ)→ `twp_describe_tools`(スキーマ)→ `twp_call`(実行)。カタログはサーバから配信される「ログイン中のアカウントが呼べる操作」の一覧で、起動後にバックグラウンドで取り直して `~/.twp/` にキャッシュする(起動は待たせない)。オフライン・未ログイン・配信していないサーバでは CLI 同梱のカタログを使う。同じドメインを続けて使うときは `twp_mount` で次のターンから常駐させられる
419
632
 
420
633
  ### 承認画面
421
634
 
@@ -511,6 +724,27 @@ twp task-loop charter pull --project <キー|UUID> [--out CONSTITUTION.md] #
511
724
  - 終了コードは他のコマンドと同じ規約です: `0` 反映した/差分なし / `1` pull でサーバに憲章が無い・ファイルを書けない / `2` 引数の誤り・差分があり `--yes` なし / `3` サーバが 4xx を返した(403・409 等)/ `4` 5xx・通信失敗 / `5` 認証失敗
512
725
  - 個人タスクのキュー(`--project __private__`)には憲章の設定がありません
513
726
 
727
+ ### スキル定義をファイルとサーバで受け渡す
728
+
729
+ ループ用のスキル定義(`.claude/commands/<名前>.md` と同じ markdown)を、プロジェクト単位でサーバに登録・展開できます。サーバのスキル名 `<名前>` はファイル `<ディレクトリ>/<名前>.md` に対応します(既定のディレクトリは `.claude/commands`、`--dir` で変更)。
730
+
731
+ ```bash
732
+ twp task-loop skill push --project <キー|UUID> <名前> # ファイル → サーバ(1件)
733
+ twp task-loop skill push --project <キー|UUID> --all # ディレクトリ直下の全件
734
+ twp task-loop skill pull --project <キー|UUID> <名前> # サーバ → ファイル(1件)
735
+ twp task-loop skill pull --project <キー|UUID> --all # サーバの全件
736
+ ```
737
+
738
+ - **push は `--yes` なしでは登録しません。** 差分と revision を表示し、確定用のコマンドを案内します(1件は `--yes --revision <番号>`、`--all` は `--yes --revision <名前>=<番号>,...`。新規は 0)。案内どおりに確定すると、差分を見た後に更新されたスキルは 409 で止まり、上書きしません
739
+ - `--all` の確定時に、案内に無いスキルに差分がある、または案内した revision から更新されたスキルがある(表示後にファイルかサーバが変わった)ときは1件も登録しません。サーバの登録上限(1プロジェクト200件)を超える場合も同じです。登録の途中で失敗したらそこで止め、登録済みと未登録の名前を表示します。**サーバにだけあるスキルは削除しません**
740
+ - **pull は既存ファイルと内容が違うとき差分を表示し、`--yes` を付けたときだけ上書きします。** `--all` で上書きを含むときは、`--yes` なしでは新規分も含めて1件も書きません。手元にだけあるファイルは消しません
741
+ - **シンボリックリンク(リンク切れを含む)とディレクトリは読み書きしません。** push はリンクのスキルファイルを送らず(`--all` では「対象外」と表示)、pull は展開先がリンクなら書きません。pull は一時ファイルに書いてから置き換えます
742
+ - 新規に展開する本文や差分に、画面に表示されない文字(制御文字・双方向制御・ゼロ幅・Unicode タグ文字等)が含まれていれば件数を警告します
743
+ - 対象になる名前は英小文字で始まり、英小文字・数字・ハイフンだけの64文字以内です(`--all` はこの形のファイルだけを対象にし、サブディレクトリは見ません)。空のファイルと 350,000 バイトを超えるファイルは登録できません
744
+ - 比較は改行を含む完全一致です。書き込みには、そのプロジェクトのループ設定を変更する権限が必要です。終了コードは憲章(`charter`)と同じ規約で、pull でサーバに未登録のときは `1` です
745
+ - 個人タスクのキュー(`--project __private__`)にはスキル定義の設定がありません
746
+ - **このコマンドは登録と展開だけを行います。** ループがキュー項目の実行時にサーバ版のスキルを使う機能は別途提供予定で、それまではこれまでどおり作業ディレクトリのファイルが使われます
747
+
514
748
  ### 必要なもの
515
749
 
516
750
  - 使う AI CLI が**インストール済みかつログイン済み**であること(`twp task-loop setup` が検出し、使えないものは理由を出して止まります)
@@ -255,7 +255,7 @@
255
255
  "name": "current_only",
256
256
  "type": "boolean",
257
257
  "required": false,
258
- "description": "現在所属しているメンバーだけにする(既定 true。false で過去の所属者も含める)",
258
+ "description": "true で現在の所属、false で現在でない所属(終了・開始前の予約)だけ(既定 true)",
259
259
  "source": "curation"
260
260
  }
261
261
  ],
@@ -0,0 +1,75 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{stepToItem}from"./chunk-VCZVITWG.js";import{loadLocalConfig}from"./chunk-VGMWPPGD.js";import{loadAiConfig}from"./chunk-TYNCXQSN.js";import"./chunk-N2UVRM3Z.js";import"./chunk-GY7KI5E5.js";import{LIST_FLAGS,LIST_PAGING_HELP,envelopePaging,nonEmpty,positiveInteger}from"./chunk-G4OO4M44.js";import{requireResolved,singleRef,withResolved}from"./chunk-ZN5EFDH7.js";import"./chunk-II5RVJQN.js";import{acknowledgement,isRecord,pick}from"./chunk-ZWVYVS2A.js";
4
+ import"./chunk-PMOUHEJQ.js";import"./chunk-5WGOHFAS.js";import"./chunk-RZVI6PMW.js";import{ApiResponseError,UsageError}from"./chunk-7WSNIXTQ.js";import"./chunk-VSJBJXZO.js";var LABEL="\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30EB\u30FC\u30D7\u306E\u30A2\u30A4\u30C6\u30E0";var STATUSES=["pending","processing","completed","failed"];var AI_TYPES=["claude","gemini","codex","copilot"];var EFFORTS=["low","medium","high","xhigh","max"];var PRIORITIES=["P0","P1","P2","P3"];var LIST_COLUMNS=["item_id","status","task_key","label","ai_type","ai_effort","runner_id","created_at"];var GET_COLUMNS=["item_id","status","task_key","label","prompt","ai_type","ai_model","ai_effort","runn\
5
+ er_id","attempt_count","reclaim_count","error_message","created_by_name","created_at","started_at","completed_at"];var HISTORY_COLUMNS=["item_id","status","task_key","skill","ai_type","runner_id","duration_ms","cost_usd","created_at"];var PROJECT_FLAG={name:"--project",summary:"\u30AD\u30E5\u30FC\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF08\u30B3\u30FC\u30C9\u307E\u305F\u306F ID\u3002\u7701\u7565\u6642\u306F TWP_PROJECT / .twp/config.json / ~/.twp/config.json\uFF09",takesValue:true,placeholder:"\
6
+ <\u30B3\u30FC\u30C9|ID>"};var ITEM_FLAG={name:"--item",summary:"\u30A2\u30A4\u30C6\u30E0\u306E ID\uFF08item_id\uFF09\u3002\u4F4D\u7F6E\u5F15\u6570\u3068\u540C\u3058\u610F\u5473\uFF08\u4E21\u65B9\u6307\u5B9A\u306F\u30A8\u30E9\u30FC\uFF09",takesValue:true,placeholder:"<\u30A2\u30A4\u30C6\u30E0ID>"};var FORBIDDEN_CORE="\u30C6\u30CA\u30F3\u30C8\u306E\u7BA1\u7406\u8005\uFF08admin \u30ED\u30FC\u30EB\uFF09\u306E\u6A29\u9650\u304C\u5FC5\u8981\u3067\u3059\uFF08\u500B\u4EBA\u30AD\u30E5\u30FC\u3092\u9664\u304F\uFF09";
7
+ var CREATE_HINT="\u30A2\u30A4\u30C6\u30E0\u306E\u6295\u5165\uFF08twp agent-loop create\uFF09\u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30E1\u30F3\u30D0\u30FC\u306A\u3089\u7BA1\u7406\u8005\u3067\u306A\u304F\u3066\u3082\u884C\u3048\u307E\u3059";var FORBIDDEN_UPDATE=`\u30AD\u30E5\u30FC\u306E\u30A2\u30A4\u30C6\u30E0\u306E\u66F4\u65B0\u306B\u306F${FORBIDDEN_CORE}\u3002\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u3078\u306E\u66F8\u304D\u623B\u3057\u3060\u3051\u306F\u3001\u305D\u306E\u30A2\u30A4\u30C6\u30E0\u3092 claim \u3057\u305F\u30EB\u30FC\u30D7\u81EA\u8EAB\u304C run_id \u3092\u6DFB\u3048\u3066\u884C\u3048\u307E\u3059\u3002`+
8
+ CREATE_HINT;var FORBIDDEN_MOVE=`\u30AD\u30E5\u30FC\u306E\u4E26\u3073\u66FF\u3048\u306B\u306F${FORBIDDEN_CORE}\u3002${CREATE_HINT}`;var FORBIDDEN_DELETE=`\u30AD\u30E5\u30FC\u306E\u30A2\u30A4\u30C6\u30E0\u306E\u524A\u9664\u306B\u306F${FORBIDDEN_CORE}\u3002${CREATE_HINT}`;var PROJECT_HELP="\u30AD\u30E5\u30FC\u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3054\u3068\u306B\u3042\u308A\u307E\u3059\u3002--project \u3092\u7701\u304F\u3068\u65E2\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF08TWP_PROJECT / .twp/config.json / ~/.twp/config.json\uFF09\u306E\u30AD\u30E5\u30FC\u3092\u64CD\u4F5C\u3057\u307E\u3059\u3002";
9
+ function basePath(input){return`/api/v2/projects/${encodeURIComponent(requireResolved(input,"projectId"))}/agent-loop`}function itemPath(input){return`${basePath(input)}/${encodeURIComponent(requireResolved(input,"itemId"))}`}async function prepareProject(input,ctx){return withResolved(input,{projectId:await ctx.projectId(input.flags.get("--project"))})}async function prepareItem(input,ctx,usage){const itemId=singleRef(input,{flag:ITEM_FLAG.name,label:"\u30A2\u30A4\u30C6\u30E0",usage});return withResolved(
10
+ await prepareProject(input,ctx),{itemId})}function rejectArgs(input,operation){if(input.args.length>0){throw new UsageError(`${operation} \u306F\u4F4D\u7F6E\u5F15\u6570\u3092\u53D6\u308A\u307E\u305B\u3093: ${input.args.join(" ")}`,`twp agent-loop ${operation} help`)}}function oneOf(flags,name,values){const raw=nonEmpty(flags,name);if(raw===void 0)return void 0;if(!values.includes(raw)){throw new UsageError(`${name} \u306B\u306F ${values.join(" / ")} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u53D7\u3051\u53D6\u3063\u305F\u5024: ${raw}\
11
+ \uFF09`)}return raw}function oneOfOrNone(flags,name,values){if(flags.get(name)?.trim()==="none")return null;return oneOf(flags,name,values)}function itemObject(body){const item=isRecord(body)?body["item"]:void 0;if(!isRecord(item)){throw new ApiResponseError(`${LABEL}\u306E\u5FDC\u7B54\u306B item \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}return item}var listPaging=envelopePaging({label:`${LABEL}\u4E00\u89A7`});var historyPaging=envelopePaging(
12
+ {label:"\u5B9F\u884C\u5C65\u6B74"});function parseSkillPrompt(prompt){const m=/^\/twp-([a-z0-9][a-z0-9-]*)(?:\s+([\s\S]*))?$/.exec(prompt.trim());if(!m){throw new UsageError(`--prompt \u306F /twp-<\u30B9\u30AD\u30EB\u540D> \u3067\u59CB\u3081\u3066\u304F\u3060\u3055\u3044\uFF08\u53D7\u3051\u53D6\u3063\u305F\u5024: ${prompt}\uFF09`,'\u4F8B: twp agent-loop create --prompt "/twp-fix-bug ABC-123"')}return{skill:m[1]??"",args:(m[2]??"").trim()}}function fixedAssignment(category,primary){return{categoryForSkill:()=>category,
13
+ selectPrimary:()=>primary}}function assignFromLocalConfig(projectId,step){const local=loadLocalConfig(projectId);const configured=local.ai!==void 0||(local.ai_config_file??"").trim()!=="";const{config,warnings}=loadAiConfig(local.ai,local.ai_config_file,local.workspace??process.cwd());const category=config.categoryForSkill(step.skill);const item=stepToItem(step,{categoryForSkill:()=>category,selectPrimary:(c,s,p,display)=>config.selectPrimary(c,s,p,display)});return{category,primary:item?.ai_type??
14
+ "",configured,warnings}}function createStep(input){const prompt=nonEmpty(input.flags,"--prompt");if(prompt===void 0){throw new UsageError("--prompt \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",'twp agent-loop create --prompt "/twp-<\u30B9\u30AD\u30EB\u540D> <\u5F15\u6570>"')}const{skill,args}=parseSkillPrompt(prompt);return{skill,args,priority:oneOf(input.flags,"--priority",PRIORITIES)??"P2",label:nonEmpty(input.flags,"--label")??""}}function createBody(input){const step=createStep(input);
15
+ const category=requireResolved(input,"category");const primary=input.resolved?.["primary"]??"";const item=stepToItem(step,fixedAssignment(category,primary));if(item===null)throw new Error("\u5185\u90E8\u30A8\u30E9\u30FC: \u30B9\u30AD\u30EB\u540D\u304C\u7A7A\u306E\u307E\u307E stepToItem \u306B\u6E21\u308A\u307E\u3057\u305F");const body={label:item.label,prompt:item.prompt};if(item.task_key!=="")body["task_key"]=item.task_key;if(item.ai_type!==void 0)body["ai_type"]=item.ai_type;const effort=oneOf(
16
+ input.flags,"--ai-effort",EFFORTS);if(effort!==void 0)body["ai_effort"]=effort;return body}var createOperation={name:"create",summary:"\u30AD\u30E5\u30FC\u306B\u30A2\u30A4\u30C6\u30E0\u3092\u6295\u5165\u3059\u308B",usage:'twp agent-loop create --prompt "/twp-<\u30B9\u30AD\u30EB\u540D> <\u5F15\u6570>" [--priority P2] [--label <\u30E9\u30D9\u30EB>] [--ai-effort <effort>] [--project <\u30B3\u30FC\u30C9|ID>]',description:`\u30EB\u30FC\u30D7\u306E\u8A08\u753B\u6295\u5165\u3068\u540C\u3058\u898F\u5247\u3067\u30A2\u30A4\u30C6\u30E0\u3092\u4F5C\u308A\u307E\u3059\uFF08\u30E9\u30D9\u30EB\u66F8\u5F0F\u30FBtask_key \u306E\u62BD\u51FA\u306F\u8A08\u753B\u6295\u5165\u3068\u5171\u901A\uFF09:
17
+ \u30E9\u30D9\u30EB [<\u512A\u5148\u5EA6>] <\u30BF\u30B9\u30AF\u30AD\u30FC> <\u30E9\u30D9\u30EB> #ai:<\u30AB\u30C6\u30B4\u30EA>\uFF08200\u5B57\u3067\u5207\u308B\u3002--label \u7701\u7565\u6642\u306F\u30D7\u30ED\u30F3\u30D7\u30C8\uFF09
18
+ task_key \u30D7\u30ED\u30F3\u30D7\u30C8\u306E\u5F15\u6570\u306E\u5148\u982D\u306B\u3042\u308B\u30BF\u30B9\u30AF\u30AD\u30FC\uFF08\u4F8B ABC-123\uFF09
19
+ 1\u756A\u624B \u3053\u306E\u6A5F\u4F53\u306E\u30EB\u30FC\u30D7\u8A2D\u5B9A\uFF08~/.twp/loops/<\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID>.json\uFF09\u306E\u30AB\u30C6\u30B4\u30EA\u8868\u3068 primary_rotation \u3067\u6C7A\u3081\u308B
20
+ \uFF08\u30B3\u30DE\u30F3\u30C91\u56DE\u3054\u3068\u306B\u8A2D\u5B9A\u3092\u8AAD\u307F\u76F4\u3059\u306E\u3067\u3001\u91CD\u307F\u4ED8\u304D\u30ED\u30FC\u30C6\u30FC\u30B7\u30E7\u30F3\u306F\u56DE\u3089\u305A\u6BCE\u56DE\u305D\u306E\u5148\u982D\u306E\u4F7F\u3048\u308B AI \u306B\u306A\u308A\u307E\u3059\uFF09
21
+ ai_model \u9001\u308A\u307E\u305B\u3093\uFF08claim \u3057\u305F\u5B9F\u884C\u6A5F\u304C\u81EA\u5206\u306E\u8A2D\u5B9A\u3067\u89E3\u6C7A\u3057\u307E\u3059\uFF09
22
+
23
+ \u540C\u3058\u30BF\u30B9\u30AF\u306E\u30A2\u30A4\u30C6\u30E0\u304C\u65E2\u306B\u4E26\u3093\u3067\u3044\u3066\u3082\u5F3E\u304D\u307E\u305B\u3093\u3002\u78BA\u304B\u3081\u308B\u306B\u306F:
24
+ twp agent-loop list --status pending --query "[?task_key=='ABC-123']"
25
+
26
+ ${PROJECT_HELP}`,flags:[{name:"--prompt",summary:"\u5B9F\u884C\u3059\u308B\u30B9\u30AD\u30EB\u3068\u5F15\u6570\uFF08/twp-<\u30B9\u30AD\u30EB\u540D> \u3067\u59CB\u3081\u308B\uFF09",takesValue:true,placeholder:'"/twp-<\u30B9\u30AD\u30EB\u540D> <\u5F15\u6570>"'},{name:"--priority",summary:`\u512A\u5148\u5EA6\uFF08${PRIORITIES.join(" / ")}\u3002\u65E2\u5B9A P2\uFF09\u3002\u30E9\u30D9\u30EB\u306E\u5148\u982D\u306B\u5165\u308B`,takesValue:true,placeholder:"<P0-P3>"},{name:"--label",summary:"\u30E9\u30D9\u30EB\u306E\u672C\u6587\uFF08\u7701\u7565\u6642\
27
+ \u306F\u30D7\u30ED\u30F3\u30D7\u30C8\uFF09",takesValue:true,placeholder:"<\u30E9\u30D9\u30EB>"},{name:"--ai-effort",summary:`\u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306E effort\uFF08${EFFORTS.join(" / ")}\uFF09\u3002\u30AB\u30C6\u30B4\u30EA\u65E2\u5B9A\u3088\u308A\u512A\u5148\u3059\u308B`,takesValue:true,placeholder:"<effort>"},PROJECT_FLAG],async prepare(input,ctx){rejectArgs(input,"create");const step=createStep(input);const projectId=await ctx.projectId(input.flags.get("--project"));const assign=assignFromLocalConfig(
28
+ projectId,step);return withResolved(input,{projectId,category:assign.category,primary:assign.primary,aiConfigured:assign.configured?"yes":"no",aiWarnings:assign.warnings.join("\n")})},plan:input=>({method:"POST",path:basePath(input),body:createBody(input)}),plannedNotes(input){const notes=[];const warnings=input.resolved?.["aiWarnings"]??"";if(warnings!=="")notes.push(`\u30EB\u30FC\u30D7\u8A2D\u5B9A\u306E\u8AAD\u307F\u8FBC\u307F\u3067\u554F\u984C\u304C\u3042\u308A\u307E\u3057\u305F: ${warnings}`);
29
+ if(input.resolved?.["aiConfigured"]==="no"){notes.push(`\u3053\u306E\u6A5F\u4F53\u306B\u30EB\u30FC\u30D7\u8A2D\u5B9A\uFF08ai / ai_config_file\uFF09\u304C\u7121\u3044\u305F\u3081\u3001\u30AB\u30C6\u30B4\u30EA\u306F\u7D44\u307F\u8FBC\u307F\u65E2\u5B9A\uFF08${input.resolved?.["category"]??"?"}\uFF09\u3067\u6C7A\u3081\u307E\u3057\u305F\u3002\u5B9F\u884C\u6A5F\u306F claim \u6642\u306B\u81EA\u5206\u306E\u8A2D\u5B9A\u3067\u30AB\u30C6\u30B4\u30EA\u3092\u5F15\u304D\u76F4\u3057\u307E\u3059\u304C\u3001\u30E9\u30D9\u30EB\u306E #ai: \u30BF\u30B0\u306F\u6295\u5165\u6642\u306E\u5024\u306E\u307E\u307E\u3067\u3059\u3002`)}
30
+ return notes},summarize:body=>pick(itemObject(body),GET_COLUMNS),raw:itemObject};function updateBody(input){const body={};const label=nonEmpty(input.flags,"--label");if(label!==void 0)body["label"]=label;const prompt=nonEmpty(input.flags,"--prompt");if(prompt!==void 0){parseSkillPrompt(prompt);body["prompt"]=prompt.trim()}const taskKey=input.flags.get("--task-key");if(taskKey!==void 0)body["task_key"]=taskKey.trim()==="none"?null:nonEmpty(input.flags,"--task-key");const aiType=oneOfOrNone(input.
31
+ flags,"--ai-type",AI_TYPES);if(aiType!==void 0)body["ai_type"]=aiType;const effort=oneOfOrNone(input.flags,"--ai-effort",EFFORTS);if(effort!==void 0)body["ai_effort"]=effort;if(Object.keys(body).length===0){throw new UsageError("\u66F4\u65B0\u3059\u308B\u9805\u76EE\u304C\u3042\u308A\u307E\u305B\u3093\uFF08--label / --prompt / --task-key / --ai-type / --ai-effort \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF09","twp agent-loop update help")}return body}var updateOperation={
32
+ name:"update",summary:"\u30A2\u30A4\u30C6\u30E0\u306E\u30E9\u30D9\u30EB\u30FB\u30D7\u30ED\u30F3\u30D7\u30C8\u30FBAI \u6307\u5B9A\u3092\u66F4\u65B0\u3059\u308B\uFF08\u7BA1\u7406\u8005\u306E\u307F\uFF09",usage:"twp agent-loop update <\u30A2\u30A4\u30C6\u30E0ID> [--label <\u30E9\u30D9\u30EB>] [--prompt <\u30D7\u30ED\u30F3\u30D7\u30C8>] [--task-key <\u30AD\u30FC|none>] [--ai-type <AI|none>] [--ai-effort <effort|none>]",description:`\u6307\u5B9A\u3057\u305F\u9805\u76EE\u3060\u3051\u3092\u9001\u308A\u307E\u3059\u3002none \u3092\u6E21\u3059\u3068\u305D\u306E\u9805\u76EE\u3092\u6D88\u3057\u307E\u3059\uFF08--task-key / --ai-type / --ai-effor\
33
+ t\uFF09\u3002
34
+ --label \u306F\u66F8\u5F0F\u3092\u7D44\u307F\u7ACB\u3066\u76F4\u3055\u305A\u3001\u6E21\u3057\u305F\u6587\u5B57\u5217\u3092\u305D\u306E\u307E\u307E\u4FDD\u5B58\u3057\u307E\u3059\uFF08#ai: \u30BF\u30B0\u3082\u81EA\u5206\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF09\u3002
35
+
36
+ \u66F4\u65B0\u306B\u306F\u66F8\u304D\u8FBC\u307F\u30B2\u30FC\u30C8\u304C\u639B\u304B\u308A\u307E\u3059: ${FORBIDDEN_UPDATE}\u3002
37
+
38
+ `+PROJECT_HELP,forbidden:FORBIDDEN_UPDATE,flags:[ITEM_FLAG,{name:"--label",summary:"\u30E9\u30D9\u30EB\uFF08\u305D\u306E\u307E\u307E\u4FDD\u5B58\u3059\u308B\uFF09",takesValue:true,placeholder:"<\u30E9\u30D9\u30EB>"},{name:"--prompt",summary:"\u30D7\u30ED\u30F3\u30D7\u30C8\uFF08/twp-<\u30B9\u30AD\u30EB\u540D> \u3067\u59CB\u3081\u308B\uFF09",takesValue:true,placeholder:'"/twp-<\u30B9\u30AD\u30EB\u540D> <\u5F15\u6570>"'},{name:"--task-key",summary:"\u30BF\u30B9\u30AF\u30AD\u30FC\uFF08none \u3067\u6D88\u3059\uFF09",
39
+ takesValue:true,placeholder:"<\u30AD\u30FC|none>"},{name:"--ai-type",summary:`1\u756A\u624B\u306E AI\uFF08${AI_TYPES.join(" / ")}\u3002none \u3067\u6D88\u3059\uFF09`,takesValue:true,placeholder:"<AI|none>"},{name:"--ai-effort",summary:`effort\uFF08${EFFORTS.join(" / ")}\u3002none \u3067\u6D88\u3059\uFF09`,takesValue:true,placeholder:"<effort|none>"},PROJECT_FLAG],async prepare(input,ctx){updateBody(input);return prepareItem(input,ctx,"twp agent-loop update help")},plan:input=>({method:"PUT",path:itemPath(
40
+ input),body:updateBody(input)}),summarize:body=>pick(itemObject(body),GET_COLUMNS),raw:itemObject};function movedItems(body){const items=isRecord(body)?body["items"]:void 0;if(!Array.isArray(items)){throw new ApiResponseError("\u4E26\u3073\u66FF\u3048\u306E\u5FDC\u7B54\u306B items \u914D\u5217\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002")}return items}var moveOperation={name:"move",summary:"\u30A2\u30A4\u30C6\u30E0\u3092\u30AD\u30E5\u30FC\u306E\u5148\u982D\u3078\u79FB\u3059\uFF08--yes \u304C\u8981\u308B\u30FB\u7BA1\u7406\u8005\u306E\u307F\
41
+ \uFF09",usage:"twp agent-loop move <\u30A2\u30A4\u30C6\u30E0ID> --yes [--project <\u30B3\u30FC\u30C9|ID>]",description:`\u6B21\u306B claim \u3055\u308C\u308B\u306E\u304C\u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306B\u306A\u308A\u307E\u3059\uFF08\u7A3C\u50CD\u4E2D\u306E\u30EB\u30FC\u30D7\u306E\u5B9F\u884C\u9806\u304C\u5909\u308F\u308B\u306E\u3067 --yes \u304C\u8981\u308A\u307E\u3059\uFF09\u3002
42
+ \u52D5\u304B\u305B\u308B\u306E\u306F pending \u306E\u30A2\u30A4\u30C6\u30E0\u3060\u3051\u3067\u3059\u3002processing / completed / failed \u306E\u30A2\u30A4\u30C6\u30E0\u306F\u4F4D\u7F6E\u304C\u5909\u308F\u308A\u307E\u305B\u3093
43
+ \uFF08\u305D\u306E\u5834\u5408\u306F stderr \u3067\u305D\u3046\u4F1D\u3048\u307E\u3059\uFF09\u3002
44
+
45
+ \u4E26\u3073\u66FF\u3048\u306B\u306F\u66F8\u304D\u8FBC\u307F\u30B2\u30FC\u30C8\u304C\u639B\u304B\u308A\u307E\u3059: ${FORBIDDEN_MOVE}\u3002
46
+
47
+ `+PROJECT_HELP,destructive:true,forbidden:FORBIDDEN_MOVE,flags:[ITEM_FLAG,PROJECT_FLAG],prepare:(input,ctx)=>prepareItem(input,ctx,"twp agent-loop move help"),plan:input=>({method:"PUT",path:`${basePath(input)}/reorder`,body:{item_ids:[requireResolved(input,"itemId")]}}),summarize:body=>movedItems(body).map(row=>pick(row,LIST_COLUMNS)),raw:movedItems,notes(body){return movedItems(body).filter(row=>isRecord(row)&&row["status"]!=="pending").map(row=>{const r=row;return`\u30A2\u30A4\u30C6\u30E0 ${String(
48
+ r["item_id"])} \u306F ${String(r["status"])} \u306E\u305F\u3081\u3001\u4E26\u3073\u306F\u5909\u308F\u3063\u3066\u3044\u307E\u305B\u3093\uFF08\u5148\u982D\u3078\u79FB\u305B\u308B\u306E\u306F pending \u3060\u3051\u3067\u3059\uFF09\u3002`})}};var deleteOperation={name:"delete",summary:"\u30A2\u30A4\u30C6\u30E0\u3092\u30AD\u30E5\u30FC\u304B\u3089\u524A\u9664\u3059\u308B\uFF08--yes \u304C\u8981\u308B\u30FB\u7BA1\u7406\u8005\u306E\u307F\uFF09",usage:"twp agent-loop delete <\u30A2\u30A4\u30C6\u30E0ID> --yes [--project <\u30B3\u30FC\
49
+ \u30C9|ID>]",description:`\u524A\u9664\u306F\u53D6\u308A\u6D88\u305B\u307E\u305B\u3093\u3002\u30A2\u30A4\u30C6\u30E0\u306F\u5B9F\u884C\u8A18\u9332\uFF08\u53F0\u5E33\uFF09\u3067\u3082\u3042\u308B\u306E\u3067\u3001\u7D42\u308F\u3063\u305F\u30A2\u30A4\u30C6\u30E0\u306F\u6D88\u3055\u305A\u306B\u6B8B\u3059\u306E\u304C\u65E2\u5B9A\u3067\u3059\u3002
50
+ \u5B9A\u671F\u67A0\u306B\u7D10\u3065\u304F\u30A2\u30A4\u30C6\u30E0\u3092\u6D88\u3059\u3068\u3001\u30B5\u30FC\u30D0\u304C\u305D\u306E\u67A0\u3092\u89E3\u653E\u3057\u307E\u3059\uFF08\u5FDC\u7B54\u306E schedule_window_released\uFF09\u3002
51
+
52
+ \u524A\u9664\u306B\u306F\u66F8\u304D\u8FBC\u307F\u30B2\u30FC\u30C8\u304C\u639B\u304B\u308A\u307E\u3059: ${FORBIDDEN_DELETE}\u3002
53
+
54
+ `+PROJECT_HELP,destructive:true,forbidden:FORBIDDEN_DELETE,flags:[ITEM_FLAG,PROJECT_FLAG],prepare:(input,ctx)=>prepareItem(input,ctx,"twp agent-loop delete help"),plan:input=>({method:"DELETE",path:itemPath(input)}),summarize:body=>acknowledgement(body,"\u30A2\u30A4\u30C6\u30E0\u524A\u9664"),raw:body=>({...acknowledgement(body,"\u30A2\u30A4\u30C6\u30E0\u524A\u9664"),schedule_window_released:isRecord(body)?body["schedule_window_released"]??null:null})};function historyBound(raw){return/^\d{4}-\d{2}-\d{2}$/.
55
+ test(raw.trim())?`${raw.trim()}T00:00:00Z`:raw.trim()}var historyResource={name:"history",summary:"\u5B9F\u884C\u5C65\u6B74\uFF08\u671F\u9593\u6307\u5B9A\u30FB\u53F0\u5E33\u306E\u6B63\u672C\uFF09",operations:[{name:"list",summary:"\u671F\u9593\u3092\u6307\u5B9A\u3057\u3066\u5B9F\u884C\u5C65\u6B74\u3092\u4E00\u89A7\u3059\u308B",usage:"twp agent-loop history list --since <\u65E5\u4ED8|\u65E5\u6642> [--until <\u65E5\u4ED8|\u65E5\u6642>] [--status <\u72B6\u614B>] [--task-key <\u30AD\u30FC>] [--runner <ID>] [--skill <\u30B9\u30AD\u30EB>] [--full]",
56
+ description:`\u4F5C\u6210\u6642\u523B\uFF08sort_order\uFF09\u3067\u671F\u9593\u3092\u5207\u308A\u307E\u3059\u3002--since \u306F\u305D\u306E\u6642\u523B\u3092\u542B\u307F\u3001--until \u306F\u542B\u307F\u307E\u305B\u3093\uFF08\u7701\u7565\u6642\u306F\u73FE\u5728\uFF09\u3002
57
+ YYYY-MM-DD \u306F UTC \u306E 0 \u6642\u3068\u3057\u3066\u6271\u3044\u307E\u3059\u3002ISO8601\uFF082026-09-01T09:00:00+09:00\uFF09\u3082\u6E21\u305B\u307E\u3059\u3002
58
+ \u65E2\u5B9A\u3067\u306F result / prompt \u3092\u8FD4\u3057\u307E\u305B\u3093\uFF08--full \u3067\u8FD4\u3057\u307E\u3059\u3002\u5FDC\u7B54\u304C\u6570\u5341\u500D\u306B\u306A\u308A\u307E\u3059\uFF09\u3002
59
+
60
+ ${PROJECT_HELP}
61
+
62
+ `+LIST_PAGING_HELP,flags:[...LIST_FLAGS,{name:"--since",summary:"\u671F\u9593\u306E\u958B\u59CB\uFF08\u3053\u306E\u6642\u523B\u3092\u542B\u3080\u30FB\u5FC5\u9808\uFF09",takesValue:true,placeholder:"<\u65E5\u4ED8|\u65E5\u6642>"},{name:"--until",summary:"\u671F\u9593\u306E\u7D42\u4E86\uFF08\u3053\u306E\u6642\u523B\u3092\u542B\u307E\u306A\u3044\u30FB\u7701\u7565\u6642\u306F\u73FE\u5728\uFF09",takesValue:true,placeholder:"<\u65E5\u4ED8|\u65E5\u6642>"},{name:"--status",summary:`\u72B6\u614B\u3067\u7D5E\u308A\u8FBC\u3080\uFF08${STATUSES.
63
+ join(" / ")}\uFF09`,takesValue:true,placeholder:"<\u72B6\u614B>"},{name:"--task-key",summary:"\u30BF\u30B9\u30AF\u30AD\u30FC\u3067\u7D5E\u308A\u8FBC\u3080\uFF08\u5B8C\u5168\u4E00\u81F4\uFF09",takesValue:true,placeholder:"<\u30AD\u30FC>"},{name:"--runner",summary:"\u5B9F\u884C\u6A5F\uFF08runner_id\uFF09\u3067\u7D5E\u308A\u8FBC\u3080",takesValue:true,placeholder:"<runner_id>"},{name:"--skill",summary:"\u30B9\u30AD\u30EB\uFF08twp- \u7121\u3057\uFF09\u3067\u7D5E\u308A\u8FBC\u3080",takesValue:true,placeholder:"\
64
+ <\u30B9\u30AD\u30EB>"},{name:"--ai-type",summary:"AI \u3067\u7D5E\u308A\u8FBC\u3080",takesValue:true,placeholder:"<AI>"},{name:"--full",summary:"result / prompt \u3082\u8FD4\u3059",takesValue:false},PROJECT_FLAG],paging:historyPaging,async prepare(input,ctx){rejectArgs(input,"history list");if(nonEmpty(input.flags,"--since")===void 0){throw new UsageError("--since \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044","twp agent-loop history list --since 2026-09-01")}oneOf(input.flags,"--status",
65
+ STATUSES);return prepareProject(input,ctx)},plan(input){const until=nonEmpty(input.flags,"--until");return{method:"GET",path:`${basePath(input)}/history`,query:{from:historyBound(nonEmpty(input.flags,"--since")),to:until===void 0?void 0:historyBound(until),fields:input.flags.has("--full")?"full":void 0,status:oneOf(input.flags,"--status",STATUSES),task_key:nonEmpty(input.flags,"--task-key"),runner_id:nonEmpty(input.flags,"--runner"),skill:nonEmpty(input.flags,"--skill"),ai_type:nonEmpty(input.flags,
66
+ "--ai-type"),limit:positiveInteger(input.flags,"--limit"),cursor:nonEmpty(input.flags,"--cursor")}}},summarize:body=>historyPaging.items(body).map(row=>pick(row,HISTORY_COLUMNS)),raw:body=>historyPaging.items(body)}]};var agentLoopDomain={name:"agent-loop",summary:"\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30EB\u30FC\u30D7\u306E\u30AD\u30E5\u30FC\uFF08\u30A2\u30A4\u30C6\u30E0\u306E\u4E00\u89A7\u30FB\u6295\u5165\u30FB\u66F4\u65B0\u30FB\u4E26\u3073\u66FF\u3048\u30FB\u524A\u9664\u30FB\u5B9F\u884C\u5C65\u6B74\uFF09",
67
+ operations:[{name:"list",summary:"\u30AD\u30E5\u30FC\u306E\u30A2\u30A4\u30C6\u30E0\u3092\u4E00\u89A7\u3059\u308B\uFF08\u65B0\u3057\u3044\u9806\uFF09",usage:"twp agent-loop list [--status <\u72B6\u614B>] [--limit <\u4EF6\u6570>] [--all] [--project <\u30B3\u30FC\u30C9|ID>]",description:`--status \u306F ${STATUSES.join(" / ")} \u306E\u3044\u305A\u308C\u304B\u3002\u7701\u7565\u3059\u308B\u3068\u5168\u72B6\u614B\u3092\u65B0\u3057\u3044\u9806\u306B\u8FD4\u3057\u307E\u3059\u3002
68
+ \u671F\u9593\u3067\u5207\u3063\u305F\u5B9F\u884C\u5C65\u6B74\u306F twp agent-loop history list \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\uFF08\u3053\u3061\u3089\u306F\u5B8C\u4E86\u6E08\u307F\u3092\u5927\u91CF\u306B\u6301\u3064\u3068\u9045\u304F\u306A\u308A\u307E\u3059\uFF09\u3002
69
+
70
+ ${PROJECT_HELP}
71
+
72
+ `+LIST_PAGING_HELP,flags:[...LIST_FLAGS,{name:"--status",summary:`\u72B6\u614B\u3067\u7D5E\u308A\u8FBC\u3080\uFF08${STATUSES.join(" / ")}\uFF09`,takesValue:true,placeholder:"<\u72B6\u614B>"},PROJECT_FLAG],paging:listPaging,async prepare(input,ctx){rejectArgs(input,"list");oneOf(input.flags,"--status",STATUSES);return prepareProject(input,ctx)},plan(input){const status=oneOf(input.flags,"--status",STATUSES);return{method:"GET",path:basePath(input),query:{status,paginated:status===void 0?"1":void 0,
73
+ limit:positiveInteger(input.flags,"--limit"),cursor:nonEmpty(input.flags,"--cursor")}}},summarize:body=>listPaging.items(body).map(row=>pick(row,LIST_COLUMNS)),raw:body=>listPaging.items(body)},{name:"get",summary:"\u30A2\u30A4\u30C6\u30E01\u4EF6\u306E\u8A73\u7D30\u3092\u8868\u793A\u3059\u308B",usage:"twp agent-loop get <\u30A2\u30A4\u30C6\u30E0ID> [--project <\u30B3\u30FC\u30C9|ID>]",description:`\u30B9\u30C6\u30C3\u30D7\u30ED\u30B0\u5168\u6587\uFF08result\uFF09\u306F --output json \u304B --query result \u3067\u8AAD\u3081\u307E\u3059\u3002
74
+
75
+ ${PROJECT_HELP}`,flags:[ITEM_FLAG,PROJECT_FLAG],prepare:(input,ctx)=>prepareItem(input,ctx,"twp agent-loop get help"),plan:input=>({method:"GET",path:itemPath(input)}),summarize:body=>pick(itemObject(body),GET_COLUMNS),raw:itemObject},createOperation,updateOperation,moveOperation,deleteOperation],subresources:[historyResource]};export{agentLoopDomain,createBody,historyResource,parseSkillPrompt,updateBody};
@@ -1,8 +1,8 @@
1
1
  import { createRequire as __twpCreateRequire } from 'node:module';
2
2
  const require = __twpCreateRequire(import.meta.url);
3
- import{CommandModelMissingError,MAX_REPORTED_VIOLATIONS,loadCommandModelDomain,loadCommandModelRoutes,validateBody,validateQuery}from"./chunk-NZ7WI4RZ.js";import{readBody}from"./chunk-QVXZEUKN.js";import{NO_REDACT_FLAG,NO_REDACT_NOTICE,exitCodeFor,fetchAllPages,reportError}from"./chunk-7LTTKKQA.js";import{renderOutput}from"./chunk-APYYF7H6.js";import{redactSecretValues,withDebug}from"./chunk-EQWW2F5V.js";import{parseOperationArgs,repeatedValues}from"./chunk-O52CUEDO.js";
4
- import"./chunk-JB27KNCX.js";import{ApiError,TwpApiClient,appendQuery}from"./chunk-JKSXUBND.js";import"./chunk-II5RVJQN.js";import{DEFAULT_MAX_ITEMS,DEFAULT_MAX_PAGES,envelopePaging,positiveInteger,readEnvelopeCursor,shellQuote}from"./chunk-2VISRLWS.js";import"./chunk-X4RS5VBH.js";import{GLOBAL_OPTIONS_HELP}from"./chunk-TAN5I2DP.js";import{HELP_TOKEN}from"./chunk-PEGUHUTD.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-E4H22AO5.js";import{EXIT_OK,NetworkError,UsageError}from"./chunk-M3GWY6NT.js";
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-X45SJNT2.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{DEFAULT_MAX_ITEMS,DEFAULT_MAX_PAGES,envelopePaging,positiveInteger,readEnvelopeCursor,shellQuote}from"./chunk-G4OO4M44.js";import"./chunk-NIAOX77K.js";import"./chunk-GMBJTG6A.js";import{ApiError,TwpApiClient,appendQuery}from"./chunk-FTYJZFEK.js";import"./chunk-II5RVJQN.js";import{GLOBAL_OPTIONS_HELP}from"./chunk-TAN5I2DP.js";import{HELP_TOKEN}from"./chunk-SP27PYHC.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
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=>/^\{[^/{}]+\}$/.
7
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.
8
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;