@tocca-systems/twp-cli 0.44.0 → 0.46.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 +16 -0
- package/README.md +60 -5
- package/dist/{agent-loop-MMWJHN3D.js → agent-loop-RMJXHBNG.js} +1 -1
- package/dist/{ai-dispatch-FEDOAV2E.js → ai-dispatch-L6XZCCU4.js} +2 -2
- package/dist/{api-command-OIXWF72C.js → api-command-67456PBS.js} +8 -7
- package/dist/{app-6VL7WWT3.js → app-7227DY7N.js} +5 -5
- package/dist/{backlog-R3M54DPM.js → backlog-XZB35X7I.js} +1 -1
- package/dist/budget-FOFE3YUJ.js +97 -0
- package/dist/chunk-3AD2T6L2.js +64 -0
- package/dist/{chunk-4MTEXWYQ.js → chunk-3WHD2YVF.js} +16 -13
- package/dist/{chunk-AJIHNSXI.js → chunk-4OSCQLZT.js} +1 -1
- package/dist/{chunk-R4MOGEGN.js → chunk-AKPVALTZ.js} +1 -1
- package/dist/{chunk-O5AUX7AQ.js → chunk-AUAZP2G7.js} +5 -4
- package/dist/chunk-B4APKONL.js +9 -0
- package/dist/{chunk-FCISZHMZ.js → chunk-EZMXGIGX.js} +1 -1
- package/dist/{chunk-OKIENL5P.js → chunk-HS7EKE7M.js} +1 -1
- package/dist/{chunk-FUH3J5VB.js → chunk-JYNZEZYL.js} +1 -1
- package/dist/{chunk-EZ3RJBN6.js → chunk-L7IGGC7H.js} +1 -1
- package/dist/{chunk-UTIZTCAP.js → chunk-LKS7GANP.js} +1 -1
- package/dist/{chunk-OUP3JLVH.js → chunk-MXKAEPXA.js} +1 -1
- package/dist/{chunk-ERQT4AMC.js → chunk-OLBRIPOS.js} +1 -1
- package/dist/{chunk-2ZTJP74M.js → chunk-OVBKORPC.js} +1 -1
- package/dist/chunk-Q3B65OFC.js +3 -0
- package/dist/{chunk-3UW33UZI.js → chunk-QVZGNHRE.js} +1 -1
- package/dist/{chunk-SSYA2LNP.js → chunk-RMAW7KOR.js} +19 -17
- package/dist/{chunk-JC5HZGPD.js → chunk-SBWCQAHT.js} +1 -1
- package/dist/{chunk-R5KWKK5Z.js → chunk-V24LKF3V.js} +1 -1
- package/dist/{chunk-G2TBGGER.js → chunk-VMULCEHY.js} +1 -1
- package/dist/chunk-Y5EN7RYN.js +4 -0
- package/dist/{chunk-NIZXUROF.js → chunk-ZE75ZDLD.js} +1 -1
- package/dist/{chunk-QEWI75KI.js → chunk-ZM3MTWNT.js} +1 -1
- package/dist/cli.js +48 -9
- package/dist/{commands-DUFVGY5V.js → commands-5GP3REIU.js} +12 -12
- package/dist/{commands-255HOMWQ.js → commands-SWR442MR.js} +1 -1
- package/dist/{company-46SIKR43.js → company-FEXAHUPT.js} +3 -3
- package/dist/{completion-4EIFB6JN.js → completion-YSP6UE25.js} +1 -1
- package/dist/{contract-NDED7WTP.js → contract-4RALZBO5.js} +2 -2
- package/dist/{department-GLIMOUQM.js → department-VEXXWBZ4.js} +1 -1
- package/dist/{deposit-U6O52S6F.js → deposit-2AAST2DE.js} +2 -2
- package/dist/{estimate-DALQK4M5.js → estimate-JQURFOCH.js} +4 -4
- package/dist/{inquiry-QFW33SDT.js → inquiry-YTYZYUTY.js} +1 -1
- package/dist/{invoice-OO6EPZAZ.js → invoice-PHYBVU6Q.js} +3 -3
- package/dist/{job-title-WA6FRUL6.js → job-title-ORNY7A7L.js} +1 -1
- package/dist/{knowledge-3IT2MBRG.js → knowledge-FQ32UNDW.js} +2 -2
- package/dist/{leave-YYKSAXHD.js → leave-5V6EPGA3.js} +2 -2
- package/dist/{media-JMVFUWIM.js → media-BU23L547.js} +1 -1
- package/dist/{notification-5KPTSLO6.js → notification-XARS6JH2.js} +1 -1
- package/dist/onedrive-N4T6D2OW.js +47 -0
- package/dist/{oneshot-GXXMSQ4Y.js → oneshot-7BFL2VON.js} +1 -1
- package/dist/outlook-LY6WBXIJ.js +94 -0
- package/dist/{position-PCVPUJZQ.js → position-NNJZAT3A.js} +1 -1
- package/dist/{project-3WW2PW3O.js → project-FDY6LETQ.js} +2 -2
- package/dist/{prospect-6RF45LPK.js → prospect-CUWP3E5S.js} +3 -3
- package/dist/{purchase-TTKRSNCF.js → purchase-2CZTB5H7.js} +3 -3
- package/dist/{receivable-H6GMZ6JQ.js → receivable-KV5PPNLA.js} +2 -2
- package/dist/{registry-7OIXAAIO.js → registry-NZ2HNT52.js} +1 -1
- package/dist/{render-ASQBZ75M.js → render-R5QZ46GF.js} +1 -1
- package/dist/{report-OEETO2S5.js → report-PCQPTRUV.js} +1 -1
- package/dist/run-7BS34D2P.js +4 -0
- package/dist/{sales-ai-review-MXMECYDW.js → sales-ai-review-SVZHVH5P.js} +2 -2
- package/dist/{sales-master-PFGXXJFP.js → sales-master-VD6JE2P3.js} +3 -3
- package/dist/sales-numbering-P7W6N3OM.js +4 -0
- package/dist/{server-settings-326MD7T4.js → server-settings-3E7G56G7.js} +1 -1
- package/dist/{supplier-payment-FRHPIV4D.js → supplier-payment-2KPCVEPH.js} +3 -3
- package/dist/{task-XTTCYGDC.js → task-MFWWP5Q7.js} +3 -3
- package/dist/teams-DRHXPLWN.js +93 -0
- package/dist/{user-3J4CZ4LO.js → user-QG3KMK3T.js} +3 -3
- package/dist/{workflow-3M2KCVYI.js → workflow-CSYU4J4U.js} +1 -1
- package/package.json +2 -2
- package/dist/chunk-34X4JXND.js +0 -4
- package/dist/chunk-YPNMQCVG.js +0 -9
- package/dist/onedrive-XAFONTRT.js +0 -16
- package/dist/outlook-KVMKMFUE.js +0 -37
- package/dist/run-KVDDYJ6W.js +0 -4
- package/dist/sales-numbering-KR2L3FQA.js +0 -4
- package/dist/teams-RDBKQJMM.js +0 -50
package/CHANGELOG.public.md
CHANGED
|
@@ -11,6 +11,22 @@
|
|
|
11
11
|
`CHANGELOG.md` に残してあります。顧客向けの履歴は public 公開以降を対象とします。
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
|
+
## 0.46.0
|
|
15
|
+
|
|
16
|
+
Teams のチャットへのメッセージ送信・チャネルへの投稿・スレッドへの返信を `twp teams message send` / `twp teams reply send` で行えるようになりました。投稿はメンバーへ通知が届くため `--yes` の指定が必要で、`--dry-run` で送信先と本文を事前に確認できます。`--mention` でメンションも付けられます。
|
|
17
|
+
|
|
18
|
+
Outlook の予定を `twp outlook event create` / `update` / `delete` で作成・更新・削除できるようになりました。出席者がいる予定では通知が相手に届くため `--yes` の指定が必要で、`--dry-run` で内容と通知が届く相手を事前に確認できます。また、`twp onedrive item upload` で OneDrive へファイルをアップロードし(250MB まで・同名は上書きしません)、`twp onedrive link create` で組織内または匿名の共有リンクを作れるようになりました。
|
|
19
|
+
|
|
20
|
+
## 0.45.0
|
|
21
|
+
|
|
22
|
+
予実管理を `twp budget` で扱えるようになりました。年度の予実ダッシュボード・サマリー・部署ごとの内訳・CSV 出力に加え、目標の一覧・まとめての登録・前年度からのコピー・CSV での取り込み(雛形の書き出しを含む)と、プロジェクトの部署按分の参照と設定ができます。既存の目標や按分を上書きする操作は、実行前に今の値を表示し、`--yes` の指定が必要です。
|
|
23
|
+
|
|
24
|
+
Outlook のメールを `twp outlook mail send` / `reply` / `reply-all` / `forward` で送信・返信・全員返信・転送できるようになりました。送ったメールは取り消せないため `--yes` の指定が必要で、`--dry-run` で宛先・件名・本文・添付を事前に確認できます。返信・全員返信では、届く相手の目安を送る前に表示します。
|
|
25
|
+
|
|
26
|
+
`twp api --wait` で状態の取り直し中にサーバの応答が想定外の形になった場合も、最後に取れた応答を出力して終了するようになりました。エラー表示に認証情報が含まれないよう伏字化も行います。
|
|
27
|
+
|
|
28
|
+
npm のパッケージページ・README・起動時の画面の「ドキュメント」から、TWP CLI の使い方をまとめた公開ドキュメント(https://docs.tocca.systems/cli)へ直接移動できるようになりました。
|
|
29
|
+
|
|
14
30
|
## 0.44.0
|
|
15
31
|
|
|
16
32
|
プロジェクトメンバーの追加・役割と稼働期間の変更・削除を `twp project member` で行えるようになりました。自分(`twp project mine`)や指定したユーザー(`twp user projects`)が参画しているプロジェクトも一覧できます。
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ TWP(Tocca Working Platform)を、ターミナルから使うための CLI
|
|
|
8
8
|
- **Shift+Tab でモードを切り替え**、開発作業と業務作業を1つの端末で行き来できます
|
|
9
9
|
- Windows / macOS / Linux / WSL で動作します
|
|
10
10
|
|
|
11
|
-
ドキュメント: <https://docs.tocca.systems
|
|
11
|
+
ドキュメント: <https://docs.tocca.systems/cli>
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -29,16 +29,17 @@ TWP(Tocca Working Platform)を、ターミナルから使うための CLI
|
|
|
29
29
|
| **できる** | `twp attendance` による自分の勤怠の参照(いまの打刻状態・打刻の履歴・月の勤怠表)と打刻、管理者向けの残業サマリ(36協定を含む)・締め状況の参照 |
|
|
30
30
|
| **できる** | `twp leave` による有給の残日数・取得履歴・付与履歴の参照と有給の申請(`twp leave request`)、`twp workchange list` / `twp shift list` による月の勤務変更・シフトの参照(`--me` で自分の分・無ければ全員分=勤怠の管理者) |
|
|
31
31
|
| **できる** | `twp analysis` による分析の読み取り(稼働分析・プロジェクトアサイン・人材別アサインを月ごとの列で、今週のキャパシティと過負荷アラート・再分配候補・標準勤務時間の設定、負荷のリスク判定、プロジェクト健全性スコアの一覧・推移と AI の所見)、`twp project manhours` / `twp task manhours` による工数の集計、`twp project workload` によるメンバーごとのタスク件数。分析の権限と、ページごとの閲覧対象への登録が要ります |
|
|
32
|
+
| **できる** | `twp budget` による予実管理(年度の予実ダッシュボード・サマリー・部署行の内訳と未割当・CSV 出力、目標の一覧・JSON でのまとめ登録・前年度からのコピー・CSV の取り込みと雛形、プロジェクトの部署按分の参照と全件置換)。分析の権限と予実管理ページの閲覧対象への登録が要り、目標の書き込みは全体管理者か分析の権限が「管理者」の人です |
|
|
32
33
|
| **できる** | `twp workflow` による、自分が申請できる申請書・申請書の定義(管理者)・自分の申請・承認履歴・自分の承認待ちの参照(申請書は名前でも指定できます)と、申請の起票・提出・更新・削除、承認・却下・差し戻し・取下げ |
|
|
33
34
|
| **できる** | `twp report` による自分のレポート(日報)の一覧(フォーマット・状態・語で絞り込み)・詳細と、下書きの作成(フォーマットの入力項目から雛形を出せます)・更新・提出、使えるレポートフォーマットの一覧 |
|
|
34
35
|
| **できる** | `twp wiki` / `twp note` / `twp meeting` による、wiki ページ(親ページ直下の子の一覧を含む)・ノート・議事録(開催日の期間で絞り込み)の一覧と、本文を `--output text` で文書として読むこと |
|
|
35
|
-
| **できる** | `twp outlook` / `twp teams` / `twp onedrive` による Microsoft 365 の読み取り(メール・添付・予定、Teams のチーム・チャネル・チャット・メッセージ・スレッド返信・自分宛てメンション、OneDrive のファイルの一覧・情報・ダウンロード)。TWP に Microsoft
|
|
36
|
+
| **できる** | `twp outlook` / `twp teams` / `twp onedrive` による Microsoft 365 の読み取り(メール・添付・予定、Teams のチーム・チャネル・チャット・メッセージ・スレッド返信・自分宛てメンション、OneDrive のファイルの一覧・情報・ダウンロード)。TWP に Microsoft アカウントでログインしたことがあるユーザーが対象です。書き込みはメールの送信・返信・全員返信・転送(`twp outlook mail send` / `reply` / `reply-all` / `forward`)、Teams のチャット送信・チャネル投稿・スレッド返信(`twp teams message send` / `reply send`)、予定の作成・更新・削除(`twp outlook event create` / `update` / `delete`)、共有リンクの作成(`twp onedrive link create`)ができ(いずれも `--yes` が必要)、OneDrive へのアップロード(`twp onedrive item upload`)もできます |
|
|
36
37
|
| **できる** | `twp task-loop` による、TWP のタスクキューを手元の AI CLI に実行させる常駐ループ |
|
|
37
38
|
| **できる** | `twp agent-loop` による、エージェントループのキューの一覧・投入・更新・先頭への移動・削除と、期間を指定した実行履歴の参照。更新・移動・削除はテナントの管理者の権限が要ります |
|
|
38
39
|
| **できる** | `twp completion bash` / `zsh` / `fish` / `powershell` によるシェル補完(コマンド名・操作名・フラグ名。プロジェクトやステータスの値は補完しません)と、`twp configure` による既定のプロジェクト・出力形式・既定プロファイルの対話設定 |
|
|
39
40
|
| **できる** | スラッシュコマンド: `/help` `/mode` `/model` `/clear` `/context` `/doctor` `/exit` `/demo`(動作デモ) `/tasks` `/task` `/projects`。`/tasks` などの TWP 系は `twp task list` と同じ結果を画面に出すだけで、AI は動かしません(クレジットも消費しません)。スラッシュコマンドは TUI の中だけで使えます(`twp -p` では解釈しません) |
|
|
40
41
|
| **できる** | 自分用のスラッシュコマンドを markdown で追加すること(`.twp/commands/*.md` / `~/.twp/commands/*.md`・[下記](#スラッシュコマンドを自分で足す))。入力中の `@パス` でファイルを、`#ABC-123` でタスクの内容を AI へ添付できます |
|
|
41
|
-
|
|
|
42
|
+
| **できる** | 会話中の AI が TWP のデータを調べて使うこと。AI は必要な操作を検索し、内容を確かめてから実行します(TWP のデータを読む・書く操作は実行前に確認が表示され、削除は毎回確認します)。特定のタスクを確実に読ませたいときは `#ABC-123` と書いて添付できます |
|
|
42
43
|
| **まだできない** | タスクの起票・コメント・通知などを行うスラッシュコマンド(`/task-new` `/comment` `/inbox` など)。同じ操作は `twp task create` / `twp task comment create` で行えます |
|
|
43
44
|
|
|
44
45
|
登録されていないコマンドは補完にも `/help` にも出しません。**「あるのに動かない」ものは置かない**方針です。
|
|
@@ -790,6 +791,32 @@ twp project workload [<コード>]
|
|
|
790
791
|
- `project manhours`(プロジェクト管理者)と `task manhours` は、期間を省くと今月です(テナントの業務日の区切りでサーバが決めます)。応答にユーザー名は無いので、`user_id` は `twp project members` と突き合わせてください
|
|
791
792
|
- 標準勤務時間の変更・負荷判定の再実行・ページの閲覧対象の設定は CLI では行えません(画面か `twp api` を使ってください)
|
|
792
793
|
|
|
794
|
+
### 予実を見る・目標を入れる
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
twp budget dashboard [--year <YYYY>] [--start-month <月>] [--reliability <確度>]...
|
|
798
|
+
twp budget summary [--year <YYYY>] [--start-month <月>] [--department <部署>]
|
|
799
|
+
twp budget breakdown [--department <部署>] [--axis project|estimate_user|reliability|estimate] [--year <YYYY>] [--start-month <月>] [--reliability <確度>]...
|
|
800
|
+
twp budget unassigned [--year <YYYY>] [--start-month <月>] [--reliability <確度>]...
|
|
801
|
+
twp budget export --out <パス.csv> [--force] [--year <YYYY>] [--start-month <月>]
|
|
802
|
+
twp budget target list [--year <YYYY>] [--department <部署>]
|
|
803
|
+
twp budget target set --year <YYYY> --file <JSON> --yes
|
|
804
|
+
twp budget target copy-previous-year --year <YYYY> [--department <部署>] --yes
|
|
805
|
+
twp budget target import-template --out <パス.csv> [--force] [--year <YYYY>] [--start-month <月>]
|
|
806
|
+
twp budget target import --year <YYYY> --file <CSV> --yes
|
|
807
|
+
twp budget allocation list [--project <コード>]
|
|
808
|
+
twp budget allocation set [--project <コード>] (--split <部署>=<比率>% | --split <部署>=<金額>)... --yes
|
|
809
|
+
twp budget allocation set [--project <コード>] --clear --yes
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
- 値は画面と同じくサーバの集計のままです(全社合計・部署の巻き上げを CLI で計算し直しません)。月ごとの値は `--output json` で読めます
|
|
813
|
+
- `--year` を省くと**サーバの今年(暦年)**の年度です。4月始まりのテナントで1〜3月に省くと翌年度になるので、省いたときは stderr でそう言います
|
|
814
|
+
- 目標の書き込み(`target set` / `copy-previous-year` / `import`)は同じ部署・月の既存の目標を上書きし、元に戻せません(目標を消す操作はありません)。送る前に今の値を読み、`set` と `copy-previous-year` は上書きされる件数と前後の値を、`import` はその年度の既存の目標の件数を出します(`--dry-run` でも出ます)
|
|
815
|
+
- `--reliability` は見積の確度コード(`60` など)です。サーバが知らない確度は使われず、そのときは stderr でそう言います
|
|
816
|
+
- `target set --file` の JSON は `[{"department": "開発部", "month": 4, "sales_target": 1000000, "profit_target": 200000}]` の形です。誤りは全部挙げて1件も送りません
|
|
817
|
+
- `target import` は雛形(`import-template`)の形の CSV を取り込みます。1行でも誤りがあればサーバが1件も書かず、行ごとの理由をすべて出して終了コード 3 です
|
|
818
|
+
- `allocation set` は按分を**全件置き換え**ます(指定しなかった部署の按分は消えます)。`--clear` で按分をすべて消します。送る前に置換前と置換後の按分を出します。比率の合計(100%)はサーバも CLI も検査しないので、自分で確かめてください
|
|
819
|
+
|
|
793
820
|
### ワークフロー(申請)を見る・出す・承認する
|
|
794
821
|
|
|
795
822
|
```bash
|
|
@@ -914,17 +941,27 @@ twp backlog issue update <課題キー> [--assignee <名前|ID>] [--status <
|
|
|
914
941
|
|
|
915
942
|
### Microsoft 365(Outlook・Teams・OneDrive)を読む
|
|
916
943
|
|
|
917
|
-
TWP に Microsoft アカウントでログインしたことがあるユーザーは、自分のメール・予定・Teams・OneDrive
|
|
944
|
+
TWP に Microsoft アカウントでログインしたことがあるユーザーは、自分のメール・予定・Teams・OneDrive を読めます。メールの送信・返信・転送、Teams のチャット送信・チャネル投稿・スレッド返信、予定の作成・更新・削除、OneDrive へのアップロードと共有リンクの作成もできます。
|
|
918
945
|
|
|
919
946
|
```
|
|
920
947
|
twp outlook mail list [--folder <名前|ID>] [--unread] [--search <語>] [--filter <OData>] [--orderby <OData>]
|
|
921
948
|
[--select <項目>] [--limit <件数>] [--all]
|
|
922
949
|
twp outlook mail get <メールID>
|
|
950
|
+
twp outlook mail send --to <アドレス> [--to …] [--cc <アドレス> …] --subject <件名> (--body-file <パス> | --body <文字列>)
|
|
951
|
+
[--html] [--attach <パス> …] --yes
|
|
952
|
+
twp outlook mail reply <メールID> (--body-file <パス> | --body <文字列>) [--html] --yes # 差出人へ
|
|
953
|
+
twp outlook mail reply-all <メールID> (--body-file <パス> | --body <文字列>) [--html] --yes # 差出人と To・Cc の全員へ
|
|
954
|
+
twp outlook mail forward <メールID> --to <アドレス> [--to …] [--body-file <パス> | --body <文字列>] [--html] --yes
|
|
923
955
|
twp outlook attachment list <メールID> # id / name / size
|
|
924
956
|
twp outlook attachment download <メールID> <添付ID> --out <パス>
|
|
925
957
|
twp outlook event list [--from <yyyy-MM-dd>] [--to <yyyy-MM-dd>] [--filter <OData>] [--orderby <OData>]
|
|
926
958
|
[--select <項目>] [--limit <件数>] [--all]
|
|
927
959
|
twp outlook event get <予定ID>
|
|
960
|
+
twp outlook event create --subject <件名> --start <yyyy-MM-ddTHH:mm> --end <yyyy-MM-ddTHH:mm> [--time-zone <IANA名>]
|
|
961
|
+
[--all-day] [--body-file <パス> | --body <文字列>] [--html] [--location <場所>]
|
|
962
|
+
[--attendee <アドレス> …] [--optional-attendee <アドレス> …] [--online-meeting] --yes
|
|
963
|
+
twp outlook event update <予定ID> [上と同じ項目のうち変えるもの] [--clear-attendees] --yes
|
|
964
|
+
twp outlook event delete <予定ID> --yes
|
|
928
965
|
|
|
929
966
|
twp teams team list # --team に渡す id / 名前
|
|
930
967
|
twp teams member list --team <名前|ID>
|
|
@@ -932,13 +969,19 @@ twp teams channel list --team <名前|ID> # --channel に渡す id
|
|
|
932
969
|
twp teams channel folder --team <名前|ID> --channel <名前|ID> # チャネルのファイルの driveId
|
|
933
970
|
twp teams chat list [--limit <件数>] [--all] # --chat に渡す id
|
|
934
971
|
twp teams message list (--chat <ID> | --team <名前|ID> --channel <名前|ID>) [--limit <件数>] [--all]
|
|
972
|
+
twp teams message send (--chat <ID> | --team <名前|ID> --channel <名前|ID>) (--body-file <パス> | --body <文字列>)
|
|
973
|
+
[--html] [--mention <ユーザーID>=<表示名> …] --yes
|
|
935
974
|
twp teams reply list <投稿ID> --team <名前|ID> --channel <名前|ID>
|
|
975
|
+
twp teams reply send <投稿ID> --team <名前|ID> --channel <名前|ID> (--body-file <パス> | --body <文字列>)
|
|
976
|
+
[--html] [--mention <ユーザーID>=<表示名> …] --yes
|
|
936
977
|
twp teams mention list [--since <日時>] [--until <日時>] [--unread] [--scope chats|channels|all] [--limit <件数>]
|
|
937
978
|
[--type user,tag,conversation]
|
|
938
979
|
|
|
939
980
|
twp onedrive item list [<フォルダID>] [--drive <ID>] [--limit <件数>] [--all]
|
|
940
981
|
twp onedrive item get <項目ID> [--drive <ID>]
|
|
941
982
|
twp onedrive item download <項目ID> --out <パス> [--drive <ID>]
|
|
983
|
+
twp onedrive item upload <ローカルのパス> [--folder <フォルダID>] [--name <名前>] [--drive <ID>]
|
|
984
|
+
twp onedrive link create <項目ID> --scope organization|anonymous [--type view|edit] [--drive <ID>] --yes
|
|
942
985
|
```
|
|
943
986
|
|
|
944
987
|
- **Microsoft 365 と連携していないと、連携の手順を表示して終了コード 3 で止まります。** TWP の画面で「Microsoftアカウントでログイン」から一度ログインすると連携されます(`twp login` のやり直しは要りません)
|
|
@@ -948,6 +991,18 @@ twp onedrive item download <項目ID> --out <パス> [--drive <ID>]
|
|
|
948
991
|
- `twp outlook mail list` の `--search` は `--filter` / `--unread` / `--orderby` と併用できません(Microsoft 365 が受け付けないため、送る前に止めます)。検索語に `"` は使えません
|
|
949
992
|
- `twp outlook attachment list` の `type` が `fileAttachment` の添付だけ実体をダウンロードできます(添付されたメール・予定やリンクの添付は 0 バイトになり、そのことを表示します)
|
|
950
993
|
- `twp outlook event list` の `--from` / `--to` は日本時間の日付です。⚠ **繰り返しの予定は系列の1件として返り、各回には展開されません**(系列の開始日時で絞るため、`--from` より前に始まった繰り返し予定は出ません)
|
|
994
|
+
- ⚠ **メールの送信・返信・全員返信・転送は、実行した瞬間に相手へ届き取り消せません。** `--yes` が無ければ実行しません。`--dry-run` で宛先・件名・本文・添付の名前と大きさを確かめてから `--yes` を付けてください。返信・全員返信は、届く相手の目安を元のメールから読んで送る前に表示します
|
|
995
|
+
- 宛先は `--to` / `--cc` にメールアドレスで指定します(名前からは探しません。複数ならフラグを繰り返します)。**Bcc は指定できません**。返信・転送では Cc・添付を足せません(Microsoft 365 の中継が受け付けないため)
|
|
996
|
+
- 本文は既定でテキストとして送ります。返信・転送の本文は Microsoft 365 が HTML として読むので、改行と記号が見たとおりに届くよう HTML に直して送ります。`--html` を付けると HTML のまま送ります
|
|
997
|
+
- 添付(`--attach`)は合計 3MB までです(Microsoft 365 がメールに直接載せられる上限)
|
|
998
|
+
- 送信に失敗して終了コード 4 になっても、送信済みのことがあります。打ち直す前に `twp outlook mail list --folder sentitems` で確かめてください
|
|
999
|
+
- ⚠ **Teams のチャット送信・チャネル投稿・スレッド返信は、実行した瞬間にメンバーへ通知が届きます。** `--yes` が無ければ実行しません。`--dry-run` で送信先(チーム・チャネルの表示名と ID、チャットの ID)と本文を確かめてから `--yes` を付けてください。チーム・チャネルは ID で指定しても参加中の一覧で引き直し、一意に決まらなければ送りません
|
|
1000
|
+
- Teams の本文は既定でテキストとして扱い、改行と記号が見たとおりに表示されるよう HTML に直して送ります(`--html` で HTML のまま)。メンションは `--mention <ユーザーID>=<表示名>` で、本文中の最初の `@<表示名>` がメンションになります(無ければ送りません。ユーザーID は `twp teams member list` の `userId`)
|
|
1001
|
+
- 投稿に失敗して終了コード 4 になっても、投稿済みのことがあります。打ち直す前に `twp teams message list` / `reply list` で確かめてください
|
|
1002
|
+
- ⚠ **予定の作成・更新・削除は、出席者がいれば招待・更新・キャンセルの通知が相手へ届き取り消せません。** 3つとも `--yes` が無ければ実行しません。更新・削除は送る前に予定を読み、通知が届く相手(いまの出席者)を表示します。`--attendee` を付けない予定は自分の予定表だけに入ります
|
|
1003
|
+
- 予定の日時は `--start` / `--end` に `yyyy-MM-ddTHH:mm` で、タイムゾーンを付けずに指定します(タイムゾーンは `--time-zone`・既定 Asia/Tokyo)。`--all-day` の終日予定は日付で指定し、`--end` は Microsoft 365 と同じく**最終日の翌日**です(10/5〜10/6 の2日間なら `--start 2026-10-05 --end 2026-10-07`。作成で省くと1日の予定)。作成・更新で終了コード 4 になっても反映済みのことがあるので、打ち直す前に `twp outlook event list` で確かめてください。更新の `--attendee` は出席者を**置き換えます**(足すのではありません)
|
|
1004
|
+
- `twp onedrive item upload` は 250MB までのファイルを 10MB ずつに分けて送ります。**同じ名前のファイルがあっても上書きせず**、Microsoft 365 が名前を変えて保存します(付いた名前は結果の `name` に出ます)。ファイルは CLI が直接読み、シェルを通しません
|
|
1005
|
+
- `twp onedrive link create` は `--scope`(`organization`=組織内/`anonymous`=リンクを知る誰でも)を必ず指定し、`--yes` が必要です。**作ったリンクはこの CLI からは消せません**(OneDrive の「アクセス許可の管理」から外します)。OneDrive のファイルの削除もこの CLI からはできません
|
|
951
1006
|
- `twp teams message list` のチャネルで返るのはスレッドの最初の投稿だけです。返信は `twp teams reply list <投稿ID>` で読みます
|
|
952
1007
|
- `twp onedrive` の `--drive` を省くと自分の OneDrive が対象です(そのことを表示します)。Teams のチャネルのファイルは `twp teams channel folder` の `driveId` を `--drive` に渡します
|
|
953
1008
|
- ダウンロードは **`--out` のパスへ実体をそのまま書き出し**、既存ファイルは `--force` を付けたときだけ上書きします。添付・ファイルの名前から書き出し先を組み立てることはしません
|
|
@@ -1341,6 +1396,6 @@ twp task-loop skill pull --project <キー|UUID> --all # サーバの全件
|
|
|
1341
1396
|
|
|
1342
1397
|
本ソフトウェアは TWP の利用契約を結んでいるテナントの利用者に対してのみ利用を許諾しています。詳細はパッケージに同梱の `LICENSE` をご確認ください。
|
|
1343
1398
|
|
|
1344
|
-
- ドキュメント: <https://docs.tocca.systems
|
|
1399
|
+
- ドキュメント: <https://docs.tocca.systems/cli>
|
|
1345
1400
|
- お問い合わせ・不具合のご報告: TWP の[サポート](https://app.tocca.systems/v1/support)からご連絡ください(ログインが必要です)
|
|
1346
1401
|
- 変更履歴: パッケージに同梱の `CHANGELOG.public.md`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{stepToItem}from"./chunk-L25UV7DE.js";import
|
|
3
|
+
import{stepToItem}from"./chunk-L25UV7DE.js";import{loadLocalConfig}from"./chunk-QVPU4HHG.js";import"./chunk-N2UVRM3Z.js";import{loadAiConfig}from"./chunk-AEJHDFXB.js";import"./chunk-G2THOTBW.js";import"./chunk-GY7KI5E5.js";import"./chunk-II5RVJQN.js";import{LIST_FLAGS,LIST_PAGING_HELP,envelopePaging,nonEmpty,positiveInteger}from"./chunk-IOGMOXYF.js";import{requireResolved,singleRef,withResolved}from"./chunk-LXIAOCUW.js";import{acknowledgement,
|
|
4
4
|
isRecord,pick}from"./chunk-VTQAI52S.js";import{ApiResponseError,UsageError}from"./chunk-UFND7FBC.js";import"./chunk-PMOUHEJQ.js";import"./chunk-J7QYPKVK.js";import"./chunk-5WGOHFAS.js";import"./chunk-RZVI6PMW.js";import"./chunk-NHYMHCAT.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
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
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";
|
|
@@ -1,7 +1,7 @@
|
|
|
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{
|
|
4
|
-
|
|
3
|
+
import{failureHint,isAuthError,isCliFatalText,isRateLimited,isServerAiType,isUntrusted,maxTurnsReached,rateLimitWaitSeconds,tailForScan}from"./chunk-ZOOEH7ZE.js";import{detectAiClis}from"./chunk-T4QZO6RQ.js";import{expandServerSkills,prepareSkillOverlay}from"./chunk-AITUMFCH.js";import"./chunk-H3WYVFTS.js";import"./chunk-AJO4O5ZF.js";import"./chunk-VRBI2NPI.js";import{isForceOnly,killProcessTree,system32}from"./chunk-N2UVRM3Z.js";import{DEFAULT_CLAUDE_LAUNCHER,
|
|
4
|
+
activeSlotPath,detectClaudeAutoSwitch,isClaudeAi,isUsableModelId,modelFitsRoute,resolveSpawnTarget,usesBedrock,wrapWithAutoSwitch}from"./chunk-AEJHDFXB.js";import"./chunk-G2THOTBW.js";import"./chunk-GY7KI5E5.js";import"./chunk-UFND7FBC.js";import{findExecutable,isWindowsDriveAbsolute}from"./chunk-PMOUHEJQ.js";import"./chunk-J7QYPKVK.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\
|
|
7
7
|
\u884C\u306F\u7D99\u7D9A\u3057\u307E\u3059`)]}if(resets!==null)this.result.resetsAt=resets;this.result.rateLimited=true;return[this.line(`\u26A0\uFE0F \u30EC\u30FC\u30C8\u30EA\u30DF\u30C3\u30C8\u901A\u77E5: status=${status}${at}`)]}onAssistant(event){const out=[];for(const block of contentBlocks(event)){if(block.type==="tool_use"){const name=typeof block.name==="string"?block.name:"tool";if(typeof block.id==="string")this.toolNames.set(block.id,name);this.toolCount+=1;out.push(this.line(`>> ${name}${toolDetail(
|
|
@@ -1,9 +1,9 @@
|
|
|
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{NO_REDACT_FLAG,NO_REDACT_NOTICE,exitCodeFor,fetchAllPages,reportError}from"./chunk-
|
|
4
|
-
|
|
5
|
-
import{HELP_TOKEN}from"./chunk-
|
|
6
|
-
EXIT_WAIT_TIMEOUT,NetworkError,UsageError}from"./chunk-UFND7FBC.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import"./chunk-RZVI6PMW.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";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=>/^\{[^/{}]+\}$/.
|
|
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-RMAW7KOR.js";import"./chunk-B4APKONL.js";import{evaluateQuery}from"./chunk-ATYA6DG5.js";import{renderOutput}from"./chunk-MXKAEPXA.js";import{redactSecretValues,redactSecrets,withDebug}from"./chunk-AUAZP2G7.js";import"./chunk-Q3B65OFC.js";
|
|
4
|
+
import{readBody}from"./chunk-ORUDW52G.js";import"./chunk-3WHD2YVF.js";import"./chunk-GMBJTG6A.js";import"./chunk-3HH5IYNO.js";import{parseOperationArgs,repeatedValues}from"./chunk-F7K37QG6.js";import{ApiError,TwpApiClient,appendQuery}from"./chunk-IF2K4PM5.js";import{GLOBAL_OPTIONS_HELP}from"./chunk-YLM54X35.js";import{AuthSession,NotLoggedInError,SessionExpiredError,loadCredentials}from"./chunk-XNLIEUAW.js";import{effectiveApiUrl,resolveConfiguredOutput,
|
|
5
|
+
resolveProfile}from"./chunk-4VZKNEVN.js";import{HELP_TOKEN}from"./chunk-Y5EN7RYN.js";import"./chunk-QQRJLH6B.js";import{OUTPUT_FORMATS,resolveOutputFormat}from"./chunk-K2ONOH3L.js";import"./chunk-WVS4W5FY.js";import"./chunk-II5RVJQN.js";import{DEFAULT_MAX_ITEMS,DEFAULT_MAX_PAGES,envelopePaging,isPageNumberEnvelope,pageRangeNotes,positiveInteger,readEnvelopeCursor,readPageNumberCursor,shellQuote}from"./chunk-IOGMOXYF.js";import"./chunk-VTQAI52S.js";
|
|
6
|
+
import{ApiRejectedError,ApiResponseError,EXIT_OK,EXIT_WAIT_TIMEOUT,NetworkError,UsageError}from"./chunk-UFND7FBC.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import"./chunk-RZVI6PMW.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";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;
|
|
9
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.
|
|
@@ -93,8 +93,9 @@ intervalSeconds}}function seconds(flag,raw,fallback,min,max){if(raw===void 0)ret
|
|
|
93
93
|
meout"?`\u4E0A\u9650 ${MAX_WAIT_TIMEOUT_SECONDS} \u79D2\u306F AI CLI \u306E Bash \u30C4\u30FC\u30EB\u306E\u4E0A\u9650\uFF08600\u79D2\uFF09\u306B\u53CE\u3081\u308B\u305F\u3081\u3067\u3059\u3002\u9577\u3044\u51E6\u7406\u306F\u9593\u3092\u7F6E\u3044\u3066\u6253\u3061\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002`:void 0)}return value}function readWaitStatus(body){const status=pickStatus(body);if(status===void 0){throw new UsageError("--wait \u306F status \u3092\u8FD4\u3059\u5FDC\u7B54\u306B\u3057\u304B\u4F7F\u3048\u307E\u305B\u3093\uFF08\u5FDC\u7B54\u306B data.status / status \u304C\u3042\u308A\u307E\u305B\u3093\uFF09",
|
|
94
94
|
"\u975E\u540C\u671F\u51E6\u7406\u306E\u72B6\u614B\u306E\u30D1\u30B9\uFF08\u4F8B: /v2/media/files/generate/video/<task_id>\uFF09\u306B\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u3002")}if(status===TERMINAL_OK)return{kind:"completed",status};if(TERMINAL_FAILED.includes(status))return{kind:"failed",status};if(PENDING_STATUSES.includes(status))return{kind:"pending",status};throw new ApiResponseError(`--wait \u304C\u77E5\u3089\u306A\u3044 status \u3067\u3059: ${status}\uFF08\u5F85\u3064\u306E\u306F ${PENDING_STATUSES.
|
|
95
95
|
join(" / ")}\u3001\u7D42\u308F\u308A\u306F ${[TERMINAL_OK,...TERMINAL_FAILED].join(" / ")}\uFF09`)}function pickStatus(body){if(!isRecord(body))return void 0;const data=body["data"];if(isRecord(data)&&typeof data["status"]==="string")return data["status"];if(typeof body["status"]==="string")return body["status"];return void 0}function isRecord(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}async function waitUntilTerminal(firstBody,options,deps){const startedAt=deps.startedAt??
|
|
96
|
-
deps.now();const deadline=startedAt+options.timeoutSeconds*1e3;let body=firstBody;let state=readWaitStatus(body);let polls=1;while(state.kind==="pending"){if(deps.now()+options.intervalSeconds*1e3>deadline){return{body,state,polls,elapsedSeconds:elapsed(deps.now(),startedAt),timedOut:true}}await deps.sleep(options.intervalSeconds*1e3);let next;try{next=await deps.fetchAgain()}catch(pollError){return{body,state,polls,elapsedSeconds:elapsed(deps.now(),startedAt),timedOut:false,pollError}}
|
|
97
|
-
|
|
96
|
+
deps.now();const deadline=startedAt+options.timeoutSeconds*1e3;let body=firstBody;let state=readWaitStatus(body);let polls=1;while(state.kind==="pending"){if(deps.now()+options.intervalSeconds*1e3>deadline){return{body,state,polls,elapsedSeconds:elapsed(deps.now(),startedAt),timedOut:true}}await deps.sleep(options.intervalSeconds*1e3);let next;try{next=await deps.fetchAgain()}catch(pollError){return{body,state,polls,elapsedSeconds:elapsed(deps.now(),startedAt),timedOut:false,pollError}}let nextState;
|
|
97
|
+
try{nextState=readWaitStatus(next)}catch(statusError){const pollError=statusError instanceof UsageError?new ApiResponseError("\u53D6\u308A\u76F4\u3057\u305F\u5FDC\u7B54\u306B status \u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u6700\u521D\u306E\u5FDC\u7B54\u306B\u306F\u3042\u308A\u307E\u3057\u305F\uFF09"):statusError;return{body,state,polls,elapsedSeconds:elapsed(deps.now(),startedAt),timedOut:false,pollError}}body=next;state=nextState;polls+=1}return{body,state,polls,elapsedSeconds:elapsed(deps.now(),
|
|
98
|
+
startedAt),timedOut:false}}function elapsed(now,startedAt){return Math.round((now-startedAt)/1e3)}function describeWaitResult(result){const head=`\u5F85\u6A5F: ${result.polls} \u56DE\u53D6\u5F97\u30FB${result.elapsedSeconds} \u79D2`;if(result.pollError!==void 0){const reason=result.pollError instanceof Error?result.pollError.message:String(result.pollError);return{note:`${head}\u3002\u53D6\u308A\u76F4\u3057\u306B\u5931\u6557\u3057\u305F\u305F\u3081\u6253\u3061\u5207\u308A\u307E\u3057\u305F\uFF08${reason}\
|
|
98
99
|
\uFF09\u3002\u6700\u5F8C\u306B\u53D6\u308C\u305F\u5FDC\u7B54\uFF08status=${result.state.status}\u30FB**\u672A\u5B8C\u4E86**\uFF09\u3092 stdout \u306B\u51FA\u3057\u3066\u3044\u307E\u3059\u3002\u51E6\u7406\u306F\u30B5\u30FC\u30D0\u3067\u7D9A\u3044\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308B\u306E\u3067\u3001\u958B\u59CB\u304B\u3089\u6253\u3061\u76F4\u3055\u305A\u540C\u3058\u30B3\u30DE\u30F3\u30C9\u3092\u6253\u3061\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,error:result.pollError instanceof
|
|
99
100
|
Error?result.pollError:new Error(reason)}}if(result.timedOut){return{note:`${head}\u3002\u6B21\u306E\u53D6\u5F97\u304C\u4E0A\u9650\u3092\u8D8A\u3048\u308B\u305F\u3081\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002status=${result.state.status} \u306E\u307E\u307E**\u672A\u5B8C\u4E86**\u3067\u3059\uFF08\u7D42\u4E86\u30B3\u30FC\u30C9 6\uFF09\u3002\u540C\u3058\u30B3\u30DE\u30F3\u30C9\u3092\u6253\u3061\u76F4\u3059\u3068\u7D9A\u304D\u3092\u5F85\u3066\u307E\u3059\u3002`,error:null}}if(result.state.kind===
|
|
100
101
|
"failed"){return{note:`${head}\u3002status=${result.state.status} \u3067\u7D42\u308F\u308A\u307E\u3057\u305F\u3002`,error:new ApiRejectedError(`\u975E\u540C\u671F\u51E6\u7406\u304C ${result.state.status} \u3067\u7D42\u308F\u308A\u307E\u3057\u305F\uFF08\u5FDC\u7B54\u306F stdout \u306B\u51FA\u3057\u3066\u3044\u307E\u3059\uFF09`)}}return{note:`${head}\u3002status=${result.state.status} \u3067\u7D42\u308F\u308A\u307E\u3057\u305F\u3002`,error:null}}var writeOut=text=>void process.stdout.write(text);var writeErr=text=>void process.stderr.write(text);function line(text){return text===""?"":text.endsWith("\n")?text:`${text}
|
|
@@ -128,7 +129,7 @@ const plan={method,path,query,...body!==void 0?{body}:{}};const stored=loadCrede
|
|
|
128
129
|
`);if(noValidate)writeErr("\u6CE8\u8A18: --no-validate \u306E\u305F\u3081\u9001\u4FE1\u524D\u306E\u30B9\u30AD\u30FC\u30DE\u691C\u8A3C\u3092\u884C\u3044\u307E\u305B\u3093\u3002\n");if(noRedact){writeErr(`${NO_REDACT_NOTICE}
|
|
129
130
|
`)}if(globals.dryRun){writeOut(line(renderOutput(dryRunValue(apiUrl,plan),format,noRedact)));return EXIT_OK}const transport=options.fetchImpl??httpFetch;const fetchImpl=globals.debug?withDebug(transport):transport;const session=new AuthSession(profile.name,apiUrl,process.env,fetchImpl);const client=new TwpApiClient(apiUrl,session,fetchImpl,options.version);const send=async()=>{try{return await client.request(plan.method,appendQuery(plan.path,plan.query),plan.body)}catch(err){if(err instanceof ApiError||
|
|
130
131
|
err instanceof NotLoggedInError||err instanceof SessionExpiredError)throw err;throw new NetworkError(`${apiUrl} \u3078\u306E\u901A\u4FE1\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${err.message}`,{cause:err})}};const waitStartedAt=(options.nowImpl??Date.now)();let responseBody=await send();if(wait!==null){const result=await waitUntilTerminal(responseBody,wait,{fetchAgain:send,sleep:options.sleepImpl??(ms=>new Promise(resolve=>setTimeout(resolve,ms))),now:options.nowImpl??Date.now,startedAt:waitStartedAt});
|
|
131
|
-
const source2=noRedact?result.body:redactSecretValues(result.body);const unfinished=result.timedOut||result.pollError!==void 0;const value2=globals.query===void 0||unfinished?source2:await evaluateQuery(globals.query,source2);writeOut(line(renderOutput(value2,format,noRedact)));const outcome=describeWaitResult(result);writeErr(`${stripTerminalControls(outcome.note)}
|
|
132
|
+
const source2=noRedact?result.body:redactSecretValues(result.body);const unfinished=result.timedOut||result.pollError!==void 0;const value2=globals.query===void 0||unfinished?source2:await evaluateQuery(globals.query,source2);writeOut(line(renderOutput(value2,format,noRedact)));const outcome=describeWaitResult(result);writeErr(`${redactSecrets(stripTerminalControls(outcome.note))}
|
|
132
133
|
`);if(unfinished&&globals.query!==void 0)writeErr("\u6CE8\u8A18: \u672A\u5B8C\u4E86\u306E\u305F\u3081 --query \u3092\u5F53\u3066\u305A\u3001\u5FDC\u7B54\u5168\u4F53\u3092\u51FA\u3057\u3066\u3044\u307E\u3059\u3002\n");if(outcome.error!==null)throw outcome.error;return result.timedOut?EXIT_WAIT_TIMEOUT:EXIT_OK}const pageNumbered=method==="GET"&&isPageNumberList(responseBody,paging.resultPath);const sentPage=pageNumberOf(paging.startingToken??plan.query[PAGE_NUMBER_PARAM]);const firstState=pageNumbered?
|
|
133
134
|
readPageNumberState(responseBody,sentPage):null;if(paging.startingToken!==void 0&&firstState?.kind==="ignored"){throw new UsageError(`\u3053\u306E\u4E00\u89A7\u306F\u30DA\u30FC\u30B8\u756A\u53F7\u65B9\u5F0F\u306E\u305F\u3081 --starting-token \u306F\u52B9\u304D\u307E\u305B\u3093\uFF08cursor=${stripTerminalControls(paging.startingToken)} \u3092\u9001\u308A\u3001\u30DA\u30FC\u30B8 ${firstState.returned} \u304C\u8FD4\u308A\u307E\u3057\u305F\uFF09`,`\u30DA\u30FC\u30B8\u306F --query-param ${PAGE_NUMBER_PARAM}\
|
|
134
135
|
=<\u30DA\u30FC\u30B8\u756A\u53F7> \u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}let paged;let pageNoIgnored;const mode=paging.resultPath===null?null:pagingMode(responseBody,{...paging,resultPath:paging.resultPath},firstState);if(mode!==null){const label=`${method} ${model.template??path}`;try{paged=await fetchAllPages({client,apiUrl,plan,paging:mode.kind==="page"?pageNumberApiPaging(label,mode.itemsKey,sentPage):envelopePaging({label,itemsKey:mode.itemsKey,cursorParam:CURSOR_PARAM}),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{RESIDENT_TOKEN_CAP,activateModeFiles,activatePermissionSettings,buildResidentSet,buildSystemPrompt,createAuditLogger,createTwpToolkit,currentBranch,describeAuditLog,describeToolCatalog,displayCwd,executeTool,findProjectTwpSubdir,localTools,lstatOrNull,parseFrontMatter,parseRule,persistProjectAllow,projectPermissionsPath,projectRootFor,readFileTool,residentInputs,resolveGitExecutable,runTurn,secretReason}from"./chunk-
|
|
4
|
-
diffStat}from"./chunk-VRBI2NPI.js";import"./chunk-
|
|
5
|
-
minSupportedBlockMessage}from"./chunk-DXXFUNYN.js";import"./chunk-4VZKNEVN.js";import{parseArgv}from"./chunk-
|
|
3
|
+
import{RESIDENT_TOKEN_CAP,activateModeFiles,activatePermissionSettings,buildResidentSet,buildSystemPrompt,createAuditLogger,createTwpToolkit,currentBranch,describeAuditLog,describeToolCatalog,displayCwd,executeTool,findProjectTwpSubdir,localTools,lstatOrNull,parseFrontMatter,parseRule,persistProjectAllow,projectPermissionsPath,projectRootFor,readFileTool,residentInputs,resolveGitExecutable,runTurn,secretReason}from"./chunk-LKS7GANP.js";import"./chunk-NZ7WI4RZ.js";import{buildDiffLines,
|
|
4
|
+
diffStat}from"./chunk-VRBI2NPI.js";import"./chunk-AUAZP2G7.js";import{require_fuzzysort}from"./chunk-DIMZRTLE.js";import"./chunk-3WHD2YVF.js";import"./chunk-GMBJTG6A.js";import"./chunk-3HH5IYNO.js";import"./chunk-IF2K4PM5.js";import{RelayError,builtinCatalog,createRuntime,loadCachedCatalog,modelLabel,pickModel,toModelInfos}from"./chunk-6QOT7CHX.js";import"./chunk-D233KKXW.js";import"./chunk-XNLIEUAW.js";import{checkMinSupportedVersion,isBelowMinSupported,
|
|
5
|
+
minSupportedBlockMessage}from"./chunk-DXXFUNYN.js";import"./chunk-4VZKNEVN.js";import{parseArgv}from"./chunk-4OSCQLZT.js";import{applyPermissionMode,checkPermission,describePermissionMode,getMode,isModeId,modeSource,nextMode}from"./chunk-NAUH75MM.js";import"./chunk-Y5EN7RYN.js";import"./chunk-QQRJLH6B.js";import{isFullWidth,isWide,stringWidth,stripAnsi}from"./chunk-WVS4W5FY.js";import"./chunk-N2UVRM3Z.js";import"./chunk-II5RVJQN.js";import"./chunk-UFND7FBC.js";
|
|
6
6
|
import"./chunk-PMOUHEJQ.js";import{proxyDiagnostics}from"./chunk-J7QYPKVK.js";import{configReadDirs,twpHomeDir}from"./chunk-RZVI6PMW.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.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.
|
|
7
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]||
|
|
8
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=
|
|
@@ -1212,7 +1212,7 @@ cwd()){const listed=await gitListFiles(cwd2);const raw=listed??await walkFiles(c
|
|
|
1212
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}
|
|
1213
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
|
|
1214
1214
|
`}}if(parsed.unknown.length>0){return{code:2,out:"",err:`\u4E0D\u660E\u306A\u5F15\u6570: ${parsed.unknown.join(" ")}
|
|
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-
|
|
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-7BS34D2P.js");try{const code=await runDomain({domain:route.domain,...parsed.operation!==void 0?{operation:parsed.operation}:
|
|
1216
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}
|
|
1217
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",
|
|
1218
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",
|
|
@@ -1246,7 +1246,7 @@ spec);const choose=index=>{const item=items[index];if(item===void 0)return{state
|
|
|
1246
1246
|
state:{...state,selected:Math.min(items.length-1,state.selected+1)}};if(ev.name==="enter")return choose(state.selected);if(ev.name==="escape"){return state.stage==="scope"?{state:{...state,stage:"choose",selected:indexOf(topItems(spec),"always")}}:{answer:"no"}}if(ev.name==="char"&&ev.value&&/^[1-9]$/.test(ev.value)){const index=Number(ev.value)-1;return index<items.length?choose(index):{state}}return{state}}function indexOf(items,key){return Math.max(0,items.findIndex(i=>i.key===key))}import{readFileSync as readFileSync2}from"fs";import{homedir,userInfo}from"os";import{join}from"path";function displayName(){const fromEnv=process.env["GIT_AUTHOR_NAME"]??process.env["GIT_COMMITTER_NAME"];if(fromEnv)return fromEnv;const fromGitConfig=readGitUserName(join(homedir(),".gitconfig"));if(fromGitConfig)return fromGitConfig;try{return userInfo().username}catch{return"there"}}function readGitUserName(path3){let text;try{text=readFileSync2(path3,"utf8")}catch{return null}let inUser=false;
|
|
1247
1247
|
for(const raw of text.split("\n")){const line=raw.trim();if(line.startsWith("[")){inUser=line.startsWith("[user");continue}if(!inUser)continue;const m=/^name\s*=\s*(.+)$/.exec(line);if(m?.[1])return m[1].trim()}return null}var LOGO=["\u2580\u2588\u2580 \u2584 \u2584 \u2588\u2580\u2580\u2584"," \u2588 \u2588\u2584\u2588\u2584\u2588 \u2588\u2580\u2580\u2598"," \u2588 \u2580 \u2580 \u2588 "];function buildBanner(opts){const cwd2=displayCwd();return{title:`twp-cli v${opts.version}`,welcome:`Welcome back ${displayName()}!`,logo:LOGO,meta:[`${modelLabel(opts.model)} \xB7 Tocca Systems`,opts.branch?`${cwd2} \u2387 ${opts.branch}`:cwd2],sections:[{heading:"\u306F\u3058\u3081\u304B\u305F",lines:["/help \u3067\u30B3\u30DE\u30F3\u30C9\u4E00\u89A7\u3001/de\
|
|
1248
1248
|
mo \u3067\u4E00\u9023\u306E\u6D41\u308C\u3092\u518D\u751F","Shift+Tab\uFF08\u52B9\u304B\u306A\u3044\u7AEF\u672B\u306F Alt+M\uFF09\u3067\u30E2\u30FC\u30C9\u3092\u5DE1\u56DE","/model \u3067\u30E2\u30C7\u30EB\u5207\u66FF\uFF08\u30E2\u30FC\u30C9\u3068\u306F\u72EC\u7ACB\uFF09","/doctor \u3067\u7AEF\u672B\u306E\u30AD\u30FC\u5165\u529B\u3092\u5B9F\u6E2C"]},{heading:"\u3053\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u306B\u3064\u3044\u3066",lines:["\u4F1A\u8A71\u3068\u30ED\u30FC\u30AB\u30EB\u30C4\u30FC\u30EB\u306F\u5B9F\u7269\u3067\u3059\uFF08\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u3067\u8AB2\u91D1\u3055\u308C\u307E\u3059\uFF09",
|
|
1249
|
-
`\u30B9\u30E9\u30C3\u30B7\u30E5\u30B3\u30DE\u30F3\u30C9${COMMANDS.length}\u672C / \u4F1A\u8A71\u4E2D\u306E AI \
|
|
1249
|
+
`\u30B9\u30E9\u30C3\u30B7\u30E5\u30B3\u30DE\u30F3\u30C9${COMMANDS.length}\u672C / \u4F1A\u8A71\u4E2D\u306E AI \u3082 TWP \u3092\u8ABF\u3079\u3066\u4F7F\u3048\u307E\u3059`,"\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8: https://docs.tocca.systems/cli"]}],width:opts.width}}var import_react35=__toESM(require_react(),1);var FLUSH_INTERVAL_MS=33;var TOKEN_INTERVAL_MS=9;function tokenize2(text){return text.match(/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]{1,3}|[A-Za-z0-9_./-]+|\s|./gu)??[]}function useTokenStream(){const[text,setText]=(0,import_react35.useState)("");const[streaming,setStreaming]=(0,import_react35.useState)(false);const bufferRef=(0,import_react35.useRef)("");const timersRef=(0,import_react35.useRef)([]);const cancelRef=(0,import_react35.useRef)(
|
|
1250
1250
|
null);const clearTimers=(0,import_react35.useCallback)(()=>{for(const t of timersRef.current)clearInterval(t);timersRef.current=[]},[]);const cancel=(0,import_react35.useCallback)(()=>{clearTimers();cancelRef.current?.();cancelRef.current=null;setStreaming(false)},[clearTimers]);const begin=(0,import_react35.useCallback)(()=>{clearTimers();bufferRef.current="";setText("");setStreaming(true);const flusher=setInterval(()=>setText(bufferRef.current),FLUSH_INTERVAL_MS);timersRef.current=[flusher]},[
|
|
1251
1251
|
clearTimers]);const push2=(0,import_react35.useCallback)(chunk=>{bufferRef.current+=chunk},[]);const end=(0,import_react35.useCallback)(()=>{clearTimers();const full=bufferRef.current;setText(full);setStreaming(false);cancelRef.current=null;return full},[clearTimers]);const start=(0,import_react35.useCallback)(target=>new Promise(resolve=>{clearTimers();bufferRef.current="";setText("");setStreaming(true);const tokens=tokenize2(target);let i=0;let finished=false;const producer=setInterval(()=>{if(i>=
|
|
1252
1252
|
tokens.length){finished=true;return}bufferRef.current+=tokens[i]??"";i+=1},TOKEN_INTERVAL_MS);const flusher=setInterval(()=>{setText(bufferRef.current);if(finished){clearTimers();setStreaming(false);cancelRef.current=null;resolve()}},FLUSH_INTERVAL_MS);timersRef.current=[producer,flusher];cancelRef.current=()=>resolve()}),[clearTimers]);const clear=(0,import_react35.useCallback)(()=>{clearTimers();bufferRef.current="";setText("");setStreaming(false)},[clearTimers]);(0,import_react35.useEffect)(()=>clearTimers,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{readBody}from"./chunk-ORUDW52G.js";import{BACKLOG_BASE_PATH,BACKLOG_PROJECT_SCOPE_LABEL,BACKLOG_SCOPE_LABEL,backlogSpacePath,isExactNumericId,resolveNamed}from"./chunk-
|
|
3
|
+
import{readBody}from"./chunk-ORUDW52G.js";import{BACKLOG_BASE_PATH,BACKLOG_PROJECT_SCOPE_LABEL,BACKLOG_SCOPE_LABEL,backlogSpacePath,isExactNumericId,resolveNamed}from"./chunk-3WHD2YVF.js";import"./chunk-GMBJTG6A.js";import"./chunk-3HH5IYNO.js";import"./chunk-IF2K4PM5.js";import"./chunk-4VZKNEVN.js";import"./chunk-II5RVJQN.js";import{requireResolved,singleRef,withResolved}from"./chunk-LXIAOCUW.js";import{isRecord,pick}from"./chunk-VTQAI52S.js";
|
|
4
4
|
import{ApiResponseError,UsageError}from"./chunk-UFND7FBC.js";import"./chunk-J7QYPKVK.js";import"./chunk-RZVI6PMW.js";import"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";var DEFAULT_COUNT=20;var MAX_COUNT=100;var NUMERIC=/^[0-9]+$/;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","summary","description","descriptionTruncated","status","issueType","priority","assignee","cr\
|
|
5
5
|
eatedUser","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)}var ATTACHMENT_COLUMNS=["id","name","size","contentType","createdUserId","create\
|
|
6
6
|
dUser","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;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\
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
|
+
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
+
import{analysisForbidden}from"./chunk-E7MUDY4P.js";import"./chunk-YLXW7TIU.js";import"./chunk-4B3T4UE7.js";import{repeatedValues}from"./chunk-F7K37QG6.js";import{ApiError,MultipartBody}from"./chunk-IF2K4PM5.js";import"./chunk-QQRJLH6B.js";import{nonEmpty}from"./chunk-IOGMOXYF.js";import{requireResolved,withResolved}from"./chunk-LXIAOCUW.js";import{isRecord,pick}from"./chunk-VTQAI52S.js";import{ApiRejectedError,ApiResponseError,UsageError}from"./chunk-UFND7FBC.js";
|
|
4
|
+
import"./chunk-J7QYPKVK.js";import"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import fs from"fs";import path from"path";var PATH="/api/v2/budget";var ANALYSIS_FORBIDDEN=analysisForbidden("");function budgetForbidden(body){if(body?.error==="forbidden")return"\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u95B2\u89A7\u3067\u304D\u307E\u305B\u3093\uFF08\u30E1\u30F3\u30D0\u30FC\u3067\u306A\u3044\u304B\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u6A29\u9650\u304C\u8DB3\u308A\u307E\u305B\u3093\uFF09\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u7BA1\u7406\u8005\u306B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002";
|
|
5
|
+
return ANALYSIS_FORBIDDEN(body)}var FORBIDDEN=budgetForbidden;var EDIT_HINT="\u76EE\u6A19\u306E\u8A2D\u5B9A\u30FB\u30B3\u30D4\u30FC\u30FB\u53D6\u308A\u8FBC\u307F\u306F\u3001\u5168\u4F53\u7BA1\u7406\u8005\u304B\u5206\u6790\u306E\u6A29\u9650\u304C\u300C\u7BA1\u7406\u8005\u300D\u306E\u4EBA\u3060\u3051\u304C\u3067\u304D\u307E\u3059\u3002\u6309\u5206\u306F\u305D\u308C\u306B\u52A0\u3048\u3066\u3001\u305D\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u7BA1\u7406\u8005\u3082\u3067\u304D\u307E\u3059\n\uFF08\u3069\u3061\u3089\u3082\u5206\u6790\u306E\u6A29\u9650\u304C\u300C\u306A\u3057\u300D\u3067\u306F\u4F7F\u3048\u307E\u305B\u3093\uFF09\u3002";
|
|
6
|
+
var YEAR_MIN=2e3;var YEAR_MAX=2100;var IMPORT_MAX_BYTES=2048*1024;var SET_FILE_MAX_BYTES=4*1024*1024;var AMOUNT_MAX=999999999999;var SHOWN_OVERWRITES=24;var BOM=new RegExp(`^${String.fromCharCode(65279)}`);function usageOf(op){return`twp budget ${op} help`}function text(value){return typeof value==="string"||typeof value==="number"?String(value):""}function yen(value){return typeof value==="number"?`${value.toLocaleString("ja-JP")} \u5186`:"\uFF08\u306A\u3057\uFF09"}function noArgs(input,op){if(input.
|
|
7
|
+
args.length>0)throw new UsageError(`${op} \u306F\u4F4D\u7F6E\u5F15\u6570\u3092\u53D6\u308A\u307E\u305B\u3093: ${input.args.join(" ")}`,usageOf(op))}function envelope(body,what){if(!isRecord(body)||body["result"]!==true)throw new ApiResponseError(`${what}\u306E\u5FDC\u7B54\u306E\u5F62\u304C\u60F3\u5B9A\u3068\u9055\u3044\u307E\u3059\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);return body}function dataRecord(body,what){const data=envelope(body,what)["data"];
|
|
8
|
+
if(!isRecord(data))throw new ApiResponseError(`${what}\u306E\u5FDC\u7B54\u306B data \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);return data}function dataRows(body,what){const data=envelope(body,what)["data"];if(!Array.isArray(data)||!data.every(isRecord))throw new ApiResponseError(`${what}\u306E\u5FDC\u7B54\u306B data \u914D\u5217\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);
|
|
9
|
+
return data}var YEAR_FLAG={name:"--year",summary:`\u5E74\u5EA6\uFF08YYYY\u30FB${YEAR_MIN}\u301C${YEAR_MAX}\u3002\u7701\u304F\u3068\u30B5\u30FC\u30D0\u306E\u4ECA\u5E74\uFF1D\u66A6\u5E74\uFF09`,takesValue:true,placeholder:"<YYYY>"};var TEMPLATE_YEAR_FLAG={name:"--year",summary:`\u305D\u306E\u5E74\u5EA6\u306B\u5728\u7C4D\u3057\u3066\u3044\u305F\u90E8\u7F72\u3092\u4E26\u3079\u308B\uFF08YYYY\u3002\u7701\u304F\u3068\u4ECA\u65E5\u6642\u70B9\u3067\u6709\u52B9\u306A\u90E8\u7F72\uFF09`,takesValue:true,placeholder:"\
|
|
10
|
+
<YYYY>"};var REQUIRED_YEAR_FLAG={name:"--year",summary:`\u5E74\u5EA6\uFF08YYYY\u30FB${YEAR_MIN}\u301C${YEAR_MAX}\u30FB\u5FC5\u9808\uFF09`,takesValue:true,placeholder:"<YYYY>"};var START_MONTH_FLAG={name:"--start-month",summary:"\u671F\u9996\u6708\uFF081\u301C12\u3002\u7701\u304F\u3068\u30C6\u30CA\u30F3\u30C8\u306E\u671F\u9996\u6708\uFF09",takesValue:true,placeholder:"<\u6708>"};var RELIABILITY_FLAG={name:"--reliability",summary:"\u58F2\u4E0A\u898B\u8FBC\u306B\u542B\u3081\u308B\u898B\u7A4D\u306E\u78BA\u5EA6\u30B3\u30FC\u30C9\uFF08\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u3002\u7701\u304F\u3068\u30B5\u30FC\u30D0\u306E\u65E2\u5B9A\u3002\u9069\u7528\u3055\u308C\u305F\u78BA\u5EA6\u306F stderr \u306B\u51FA\u308B\uFF09",
|
|
11
|
+
takesValue:true,placeholder:"<\u78BA\u5EA6>",repeatable:true};var DEPARTMENT_FLAG={name:"--department",summary:"\u90E8\u7F72\uFF08\u540D\u524D\u30FB\u30B3\u30FC\u30C9\u30FBID\uFF09",takesValue:true,placeholder:"<\u90E8\u7F72>"};function fiscalYear(input,required){const raw=nonEmpty(input.flags,"--year");if(raw===void 0){if(required)throw new UsageError("--year <YYYY> \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5BFE\u8C61\u306E\u5E74\u5EA6\uFF09");return void 0}const value=raw.trim();
|
|
12
|
+
const year=Number(value);if(!/^\d{4}$/.test(value)||year<YEAR_MIN||year>YEAR_MAX)throw new UsageError(`--year \u306F ${YEAR_MIN}\u301C${YEAR_MAX} \u306E\u897F\u66A64\u6841\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044: ${raw}`);return year}function startMonth(input){const raw=nonEmpty(input.flags,"--start-month");if(raw===void 0)return void 0;const value=raw.trim();const month=Number(value);if(!/^\d{1,2}$/.test(value)||month<1||month>12)throw new UsageError(`--start-month \u306F 1\u301C12 \u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\
|
|
13
|
+
\u3044: ${raw}`);return month}function reliabilities(input){const values=repeatedValues(input,RELIABILITY_FLAG.name).map(v=>v.trim());if(values.some(v=>v===""||v.includes(",")))throw new UsageError("--reliability \u306F\u78BA\u5EA6\u30921\u3064\u305A\u3064\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\u306B\u3057\u306A\u3044\uFF09");return values.length===0?void 0:values.join(",")}function periodQuery(input,withReliability){return{fiscal_year:fiscalYear(
|
|
14
|
+
input,false),start_month:startMonth(input),...withReliability?{estimate_reliabilities:reliabilities(input)}:{}}}function periodNotes(input){const lines=[];if(!input.flags.has("--year"))lines.push("--year \u3092\u7701\u3044\u305F\u306E\u3067\u3001\u30B5\u30FC\u30D0\u306E\u4ECA\u5E74\uFF08\u66A6\u5E74\uFF09\u306E\u5E74\u5EA6\u306B\u306A\u308A\u307E\u3059\uFF08\u671F\u9996\u6708\u304C4\u6708\u306A\u3089\u30011\u301C3\u6708\u306B\u7701\u304F\u3068\u7FCC\u5E74\u5EA6\u3067\u3059\u3002\u9069\u7528\u3055\u308C\u305F\u5E74\u5EA6\u306F\u5FDC\u7B54\u306E\u5F8C\u306B\u51FA\u307E\u3059\uFF09\u3002");
|
|
15
|
+
return lines}function reliabilityNotes(applied,input){if(!Array.isArray(applied))return[];const used=new Set(applied.map(String));const appliedText=applied.map(String).join(", ");const requested=[...new Set(repeatedValues(input,RELIABILITY_FLAG.name).map(v=>v.trim()).map(v=>/^\d$/.test(v)?`0${v}`:v))];const dropped=requested.filter(v=>!used.has(v));if(dropped.length===0)return[`\u58F2\u4E0A\u898B\u8FBC\u306B\u542B\u3081\u305F\u78BA\u5EA6: ${appliedText}`];const allDropped=dropped.length===requested.
|
|
16
|
+
length;return[`\u26A0 \u6307\u5B9A\u3057\u305F\u78BA\u5EA6\u306E\u3046\u3061 ${dropped.join(", ")} \u306F\u4F7F\u308F\u308C\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u30B5\u30FC\u30D0\u304C\u77E5\u3089\u306A\u3044\u78BA\u5EA6\u3067\u3059\uFF09\u3002${allDropped?"\u6307\u5B9A\u304C\u3059\u3079\u3066\u4F7F\u3048\u306A\u304B\u3063\u305F\u306E\u3067\u3001\u30B5\u30FC\u30D0\u306E\u65E2\u5B9A":"\u58F2\u4E0A\u898B\u8FBC\u306B\u542B\u3081\u305F\u78BA\u5EA6"}: ${appliedText}`]}function basisNotes(data){const basis=isRecord(
|
|
17
|
+
data["basis"])?data["basis"]:{};const legacy=Array.isArray(basis["labor_legacy_share_year_months"])?basis["labor_legacy_share_year_months"].map(String):[];return legacy.length===0?[]:[`\u4EBA\u4EF6\u8CBB\u5B9F\u7E3E\u306E\u90E8\u7F72\u5225\u5185\u8A33\u304C\u65E7\u65B9\u5F0F\uFF08\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u5358\u4F4D\u306E\u6309\u5206\uFF09\u306E\u6708\u304C\u3042\u308A\u307E\u3059: ${legacy.join(", ")}\uFF08\u53CE\u652F\u5206\u6790\u306E\u6570\u5B57\u3068\u98DF\u3044\u9055\u3046\u3053\u3068\u304C\u3042\u308A\u307E\u3059\uFF09`]}
|
|
18
|
+
function monthRange(data){const months=Array.isArray(data["months"])?data["months"].filter(isRecord):[];if(months.length===0)return"";return`${text(months[0]?.["year_month"])} \u301C ${text(months[months.length-1]?.["year_month"])}`}var ANNUAL_COLUMNS=["sales_target","sales_forecast","sales_actual","sales_variance","sales_achievement_rate","labor_cost_actual","profit_target","profit_actual","profit_variance","profit_rate"];function dashboardRows(body){const data=dataRecord(body,"\u4E88\u5B9F\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9");
|
|
19
|
+
const departments=data["departments"];const company=data["company_totals"];if(!Array.isArray(departments)||!isRecord(company))throw new ApiResponseError("\u4E88\u5B9F\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u5FDC\u7B54\u306B departments / company_totals \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");const row=(id,name,level,entry)=>({department_id:id??null,department_name:name??null,level:level??null,...pick(entry["\
|
|
20
|
+
annual"],ANNUAL_COLUMNS)});return[row(null,"\u5168\u793E",null,company),...departments.filter(isRecord).map(dept=>row(dept["department_id"],dept["department_name"],dept["level"],dept))]}var dashboardOperation={name:"dashboard",summary:"\u5E74\u5EA6\u306E\u4E88\u5B9F\uFF08\u5168\u793E\u3068\u90E8\u7F72\u3054\u3068\u306E\u76EE\u6A19\u30FB\u898B\u8FBC\u30FB\u5B9F\u7E3E\u30FB\u5DEE\u7570\uFF09\u3092\u8868\u793A\u3059\u308B",usage:"twp budget dashboard [--year <YYYY>] [--start-month <\u6708>] [--reliabili\
|
|
21
|
+
ty <\u78BA\u5EA6>]...",description:"GET /api/v2/budget/dashboard\u3002\u753B\u9762\u306E\u4E88\u5B9F\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u3068\u540C\u3058\u5024\u3067\u3059\uFF08\u5168\u793E\u5408\u8A08\u30FB\u90E8\u7F72\u306E\u5DFB\u304D\u4E0A\u3052\u306F\u30B5\u30FC\u30D0\u306E\u8A08\u7B97\u3092\u305D\u306E\u307E\u307E\u51FA\u3057\u307E\u3059\uFF09\u3002\n--output table / text / tsv \u306F\u5168\u793E\u3068\u90E8\u7F72\u3054\u3068\u306E\u5E74\u9593\u306E\u5024\u3067\u3059\u3002\u6708\u3054\u3068\u306E\u5024\uFF08monthly\uFF09\u30FB\u6708\u306E\u4E26\u3073\uFF08months\uFF09\u30FB\u6A29\u9650\uFF08permissions\uFF09\u306F --output json \u3067\u8AAD\u3081\u307E\u3059\u3002",
|
|
22
|
+
flags:[YEAR_FLAG,START_MONTH_FLAG,RELIABILITY_FLAG],forbidden:FORBIDDEN,plan:input=>{noArgs(input,"dashboard");return{method:"GET",path:`${PATH}/dashboard`,query:periodQuery(input,true)}},plannedNotes:periodNotes,summarize:dashboardRows,raw:body=>{dashboardRows(body);return dataRecord(body,"\u4E88\u5B9F\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9")},notes:(body,input)=>{const data=dataRecord(body,"\u4E88\u5B9F\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9");return[`${text(data["fiscal_year"])} \u5E74\u5EA6\uFF08${monthRange(
|
|
23
|
+
data)}\uFF09`,...reliabilityNotes(data["estimate_reliabilities"],input),...basisNotes(data)]}};function summaryOf(body){const data=dataRecord(body,"\u4E88\u5B9F\u30B5\u30DE\u30EA\u30FC");if(!isRecord(data["sales"])||!isRecord(data["profit"]))throw new ApiResponseError("\u4E88\u5B9F\u30B5\u30DE\u30EA\u30FC\u306E\u5FDC\u7B54\u306B sales / profit \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");return data}var summaryOperation={
|
|
24
|
+
name:"summary",summary:"\u5E74\u5EA6\u306E\u58F2\u4E0A\u30FB\u5229\u76CA\u306E\u76EE\u6A19\u3068\u5B9F\u7E3E\u306E\u5408\u8A08\uFF08\u30B5\u30DE\u30EA\u30FC\u30AB\u30FC\u30C9\uFF09\u3092\u8868\u793A\u3059\u308B",usage:"twp budget summary [--year <YYYY>] [--start-month <\u6708>] [--department <\u90E8\u7F72>]",description:"GET /api/v2/budget/summary\u3002\u753B\u9762\u306E\u30B5\u30DE\u30EA\u30FC\u30AB\u30FC\u30C9\u3068\u540C\u3058\u5024\u3067\u3059\u3002--department \u3092\u4ED8\u3051\u308B\u3068\u3001\u305D\u306E\u90E8\u7F72\u3068\u914D\u4E0B\uFF08\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u90E8\u7F72\u884C\u3068\u540C\u3058\u898F\u5247\uFF09\u306E\u5408\u8A08\u3001\n\u7701\u304F\u3068\u5168\u793E\u306E\u5408\u8A08\u3067\u3059\u3002",
|
|
25
|
+
flags:[YEAR_FLAG,START_MONTH_FLAG,DEPARTMENT_FLAG],forbidden:FORBIDDEN,async prepare(input,ctx){noArgs(input,"summary");fiscalYear(input,false);startMonth(input);const department=nonEmpty(input.flags,DEPARTMENT_FLAG.name);return department===void 0?input:withResolved(input,{departmentId:(await ctx.resolver.department(department)).id})},plan:input=>({method:"GET",path:`${PATH}/summary`,query:{...periodQuery(input,false),department_id:input.resolved?.["departmentId"]}}),plannedNotes:periodNotes,summarize:body=>{
|
|
26
|
+
const data=summaryOf(body);const line=(kind,entry)=>({item:kind,...pick(entry,["target","actual","variance","achievement_rate"])});return[line("\u58F2\u4E0A",data["sales"]),line("\u5229\u76CA",data["profit"])]},raw:summaryOf,notes:body=>{const data=summaryOf(body);return[`${text(data["fiscal_year"])} \u5E74\u5EA6${data["department_id"]?`\u30FB\u90E8\u7F72 ${text(data["department_id"])}`:"\u30FB\u5168\u793E"}\u3002\u5229\u76CA\u7387 ${data["profit_rate"]===null||data["profit_rate"]===void 0?"\uFF08\u58F2\u4E0A\u5B9F\
|
|
27
|
+
\u7E3E\u306A\u3057\uFF09":`${text(data["profit_rate"])}%`}`,...basisNotes(data)]}};var BREAKDOWN_PROJECT_COLUMNS=["project_code","project_name","sales_forecast","sales_actual","labor_cost_actual","procurement_cost","profit_actual"];function breakdownRows(body){const data=dataRecord(body,"\u4E88\u5B9F\u306E\u5185\u8A33");if(Array.isArray(data["projects"])){return data["projects"].filter(isRecord).map(row=>({project_id:row["project_id"]??null,...pick(row,BREAKDOWN_PROJECT_COLUMNS.slice(0,2)),...pick(
|
|
28
|
+
row["annual"],BREAKDOWN_PROJECT_COLUMNS.slice(2))}))}if(Array.isArray(data["groups"])){return data["groups"].filter(isRecord).map(row=>({key:row["key"]??null,label:row["label"]??null,...pick(row["annual"],["sales_forecast","estimate_count"]),...pick(row,["estimate_no","billing_date","invoice_date"])}))}throw new ApiResponseError("\u4E88\u5B9F\u306E\u5185\u8A33\u306E\u5FDC\u7B54\u306B projects / groups \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002")}
|
|
29
|
+
function breakdownRaw(body){breakdownRows(body);return dataRecord(body,"\u4E88\u5B9F\u306E\u5185\u8A33")}function breakdownNotes(body,input){const data=dataRecord(body,"\u4E88\u5B9F\u306E\u5185\u8A33");const lines=[`${text(data["fiscal_year"])} \u5E74\u5EA6\uFF08${monthRange(data)}\uFF09\u30FB${data["department_id"]?`\u90E8\u7F72 ${text(data["department_id"])}\uFF08\u914D\u4E0B\u3092\u542B\u3080\uFF09`:"\u672A\u5272\u5F53\uFF08\u90E8\u7F72\u304C\u672A\u8A2D\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09"}`];
|
|
30
|
+
if(breakdownRows(body).length===0)lines.push("\u5185\u8A33\u306E\u884C\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u5B9F\u7E3E\u306F\u5F53\u6708\u307E\u3067\u3001\u58F2\u4E0A\u898B\u8FBC\u306F\u5BFE\u8C61\u306E\u78BA\u5EA6\u306E\u898B\u7A4D\u3060\u3051\u304C\u96C6\u8A08\u3055\u308C\u307E\u3059\uFF09");const unlinked=isRecord(data["unlinked_forecast"])?data["unlinked_forecast"]:void 0;if(unlinked!==void 0&&Number(unlinked["estimate_count"])>0){lines.push(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u7D10\u3065\u304B\u306A\u3044\u898B\u7A4D\u306E\u58F2\u4E0A\u898B\u8FBC: ${yen(
|
|
31
|
+
isRecord(unlinked["annual"])?unlinked["annual"]["sales_forecast"]:void 0)}\uFF08${text(unlinked["estimate_count"])} \u4EF6\u30FB\u884C\u306B\u306F\u51FA\u307E\u305B\u3093\uFF09`)}const basis=isRecord(data["basis"])?data["basis"]:{};return[...lines,...reliabilityNotes(basis["estimate_reliabilities"],input),...basisNotes(data)]}var breakdownOperation={name:"breakdown",summary:"\u90E8\u7F72\u884C\u306E\u91D1\u984D\u306E\u5185\u8A33\u3092\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF08\u307E\u305F\u306F\u62C5\u5F53\u8005\u30FB\u78BA\u5EA6\u30FB\u6848\u4EF6\uFF09\u3054\u3068\u306B\u8868\u793A\u3059\u308B",
|
|
32
|
+
usage:"twp budget breakdown [--department <\u90E8\u7F72>] [--axis project|estimate_user|reliability|estimate] [--year <YYYY>] [--start-month <\u6708>] [--reliability <\u78BA\u5EA6>]...",description:"GET /api/v2/budget/project-breakdown\u3002\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u90E8\u7F72\u884C\u306E\u30BB\u30EB\u3092\u62BC\u3057\u305F\u3068\u304D\u306E\u5185\u8A33\u3068\u540C\u3058\u5024\u3067\u3059\uFF08\u914D\u4E0B\u306E\u90E8\u7F72\u3092\u542B\u307F\u307E\u3059\uFF09\u3002\n--department \u3092\u7701\u304F\u3068\u300C\u672A\u5272\u5F53\u300D\uFF08\u90E8\u7F72\u304C\u672A\u8A2D\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09\u306E\u5185\u8A33\u3067\u3059\uFF08twp budget unassigned \u3068\u540C\u3058\uFF09\u3002\n--axis \u306F\u5185\u8A33\u306E\u8EF8\u3067\u3059\u3002project\uFF08\u65E2\u5B9A\uFF09\u306F\u58F2\u4E0A\u898B\u8FBC\u30FB\u58F2\u4E0A\u5B9F\u7E3E\u30FB\u4EBA\u4EF6\u8CBB\u30FB\u4ED5\u5165\u30FB\u5229\u76CA\u3092\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3054\u3068\u306B\u3001\nestimate_user\uFF08\u6848\u4EF6\u62C5\u5F53\u8005\uFF09\u30FBreliability\uFF08\u78BA\u5EA6\uFF09\u30FBestimate\uFF08\u6848\u4EF6\u3054\u3068\uFF09\u306F\u58F2\u4E0A\u898B\u8FBC\u3060\u3051\u3092\u8FD4\u3057\u307E\u3059\u3002\u8EF8\u306E\u5224\u5B9A\u306F\u30B5\u30FC\u30D0\u304C\u884C\u3044\u307E\u3059\u3002",
|
|
33
|
+
flags:[DEPARTMENT_FLAG,{name:"--axis",summary:"\u5185\u8A33\u306E\u8EF8\uFF08project\u30FBestimate_user\u30FBreliability\u30FBestimate\uFF09",takesValue:true,placeholder:"<\u8EF8>"},YEAR_FLAG,START_MONTH_FLAG,RELIABILITY_FLAG],forbidden:FORBIDDEN,async prepare(input,ctx){noArgs(input,"breakdown");fiscalYear(input,false);startMonth(input);reliabilities(input);const department=nonEmpty(input.flags,DEPARTMENT_FLAG.name);return department===void 0?input:withResolved(input,{departmentId:(await ctx.resolver.
|
|
34
|
+
department(department)).id})},plan:input=>({method:"GET",path:`${PATH}/project-breakdown`,query:{...periodQuery(input,true),department_id:input.resolved?.["departmentId"],axis:nonEmpty(input.flags,"--axis")}}),plannedNotes:input=>[...periodNotes(input),...input.flags.has(DEPARTMENT_FLAG.name)?[]:["--department \u3092\u7701\u3044\u305F\u306E\u3067\u300C\u672A\u5272\u5F53\u300D\uFF08\u90E8\u7F72\u304C\u672A\u8A2D\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09\u306E\u5185\u8A33\u3067\u3059\u3002"]],
|
|
35
|
+
summarize:breakdownRows,raw:breakdownRaw,notes:breakdownNotes};var unassignedOperation={name:"unassigned",summary:"\u300C\u672A\u5272\u5F53\u300D\uFF08\u90E8\u7F72\u304C\u672A\u8A2D\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09\u306E\u5185\u8A33\u3092\u8868\u793A\u3059\u308B",usage:"twp budget unassigned [--year <YYYY>] [--start-month <\u6708>] [--reliability <\u78BA\u5EA6>]...",description:"GET /api/v2/budget/unassigned-projects\u3002\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u300C\u672A\u5272\u5F53\u300D\u884C\u306E\u5185\u8A33\u3067\u3059\uFF08twp budget breakdown \u3092 --department \u7121\u3057\
|
|
36
|
+
\u3067\u6253\u3064\u306E\u3068\u540C\u3058\u5024\uFF09\u3002",flags:[YEAR_FLAG,START_MONTH_FLAG,RELIABILITY_FLAG],forbidden:FORBIDDEN,plan:input=>{noArgs(input,"unassigned");return{method:"GET",path:`${PATH}/unassigned-projects`,query:periodQuery(input,true)}},plannedNotes:periodNotes,summarize:breakdownRows,raw:breakdownRaw,notes:breakdownNotes};var OUT_FLAG={name:"--out",summary:"\u66F8\u304D\u51FA\u3057\u5148\u306E\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9\uFF08\u5FC5\u9808\uFF09",takesValue:true,placeholder:"\
|
|
37
|
+
<\u30D1\u30B9>"};var FORCE_FLAG={name:"--force",summary:"\u65E2\u5B58\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u4E0A\u66F8\u304D\u3059\u308B",takesValue:false};var exportOperation={name:"export",summary:"\u5E74\u5EA6\u306E\u4E88\u5B9F\u3092 CSV \u306B\u66F8\u304D\u51FA\u3059\uFF08--out\uFF09",usage:"twp budget export --out <\u30D1\u30B9.csv> [--force] [--year <YYYY>] [--start-month <\u6708>]",description:"GET /api/v2/budget/export\u3002\u753B\u9762\u306E CSV \u51FA\u529B\u3068\u540C\u3058\u5185\u5BB9\uFF08UTF-8\u30FBBOM \u4ED8\u304D\uFF09\u3067\u3059\u3002\u5168\u793E\u3068\u90E8\u7F72\u3054\u3068\u306B\u3001\u58F2\u4E0A\u76EE\u6A19\u30FB\u5B9F\u7E3E\u30FB\u5DEE\u7570\u30FB\u4EBA\u4EF6\u8CBB\u30FB\u5229\u76CA\u306E\u884C\u304C\u6708\u3054\u3068\u306B\u4E26\u3073\u307E\u3059\u3002\
|
|
38
|
+
\n\u53D6\u308A\u8FBC\u307F\uFF08twp budget target import\uFF09\u306E\u5F62\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u53D6\u308A\u8FBC\u307F\u306E\u96DB\u5F62\u306F twp budget target import-template\uFF09\u3002\n\u65E2\u5B58\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u4E0A\u66F8\u304D\u3057\u307E\u305B\u3093\uFF08\u4E0A\u66F8\u304D\u3059\u308B\u306A\u3089 --force\uFF09\u3002",flags:[OUT_FLAG,FORCE_FLAG,YEAR_FLAG,START_MONTH_FLAG],download:{outFlag:OUT_FLAG.name,forceFlag:FORCE_FLAG.name},forbidden:FORBIDDEN,
|
|
39
|
+
plan:input=>{noArgs(input,"export");return{method:"GET",path:`${PATH}/export`,query:periodQuery(input,false)}},plannedNotes:periodNotes,summarize:body=>body,raw:body=>body};var TARGET_COLUMNS=["fiscal_year","month","department_id","department_name","sales_target","profit_target","updated_at"];var TARGET_WRITE_COLUMNS=TARGET_COLUMNS.filter(column=>column!=="department_name");function withDepartmentNames(rows,input){const names=new Map(Object.entries(JSON.parse(input.resolved?.["departments"]??"{}")));
|
|
40
|
+
return rows.map(row=>({...row,department_name:names.get(String(row["department_id"]))??null}))}async function departmentNames(ctx){try{return JSON.stringify(Object.fromEntries((await ctx.resolver.departments()).map(d=>[d.id,d.name])))}catch{return"{}"}}function targetKey(departmentId,month){return`${String(departmentId)}#${String(month)}`}async function currentTargets(ctx,year,departmentId){const query=`fiscal_year=${year}${departmentId===void 0?"":`&department_id=${encodeURIComponent(departmentId)}`}`;
|
|
41
|
+
return dataRows(await ctx.resolver.salesJson(`${PATH}/targets?${query}`,"\u4E88\u7B97\u76EE\u6A19"),"\u4E88\u7B97\u76EE\u6A19")}var targetListOperation={name:"list",summary:"\u5E74\u5EA6\u306E\u76EE\u6A19\uFF08\u90E8\u7F72\u30FB\u6708\u3054\u3068\u306E\u58F2\u4E0A\u76EE\u6A19\u3068\u5229\u76CA\u76EE\u6A19\uFF09\u3092\u4E00\u89A7\u3059\u308B",usage:"twp budget target list [--year <YYYY>] [--department <\u90E8\u7F72>]",description:`GET /api/v2/budget/targets\u3002\u76EE\u6A19\u304C\u767B\u9332\u3055\u308C\u3066\u3044\u308B\uFF08\u90E8\u7F72\u30FB\u6708\uFF09\u3060\u3051\u304C\u8FD4\u308A\u307E\u3059\uFF08\u767B\u9332\u306E\u7121\u3044\u6708\u306F\u884C\u306B\u306A\u308A\u307E\u305B\u3093\uFF09\
|
|
42
|
+
\u3002
|
|
43
|
+
\u3053\u306E API \u306F\u30DA\u30FC\u30B8\u30F3\u30B0\u3092\u6301\u3061\u307E\u305B\u3093\u3002
|
|
44
|
+
--output table / text / tsv \u306F\u8981\u7D04\u5217\uFF08${TARGET_COLUMNS.join(" / ")}\uFF09\u3067\u3059\u3002department_name \u306F\u90E8\u7F72\u30DE\u30B9\u30BF\u304B\u3089 CLI \u304C\u8DB3\u3057\u305F\u540D\u524D\u3067\u3059\u3002`,flags:[YEAR_FLAG,DEPARTMENT_FLAG],forbidden:FORBIDDEN,async prepare(input,ctx){noArgs(input,"target list");fiscalYear(input,false);const department=nonEmpty(input.flags,DEPARTMENT_FLAG.name);const resolved={departments:await departmentNames(ctx)};if(department!==void 0)
|
|
45
|
+
resolved["departmentId"]=(await ctx.resolver.department(department)).id;return withResolved(input,resolved)},plan:input=>({method:"GET",path:`${PATH}/targets`,query:{fiscal_year:fiscalYear(input,false),department_id:input.resolved?.["departmentId"]}}),plannedNotes:periodNotes,narrow:(body,input)=>({result:true,data:withDepartmentNames(dataRows(body,"\u4E88\u7B97\u76EE\u6A19"),input)}),summarize:body=>dataRows(body,"\u4E88\u7B97\u76EE\u6A19").map(row=>pick(row,TARGET_COLUMNS)),raw:body=>dataRows(
|
|
46
|
+
body,"\u4E88\u7B97\u76EE\u6A19"),notes:body=>dataRows(body,"\u4E88\u7B97\u76EE\u6A19").length===0?["\u76EE\u6A19\u306F\u767B\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093"]:[]};var SET_ROW_KEYS=new Set(["department","department_id","month","sales_target","profit_target"]);function parseTargetRows(raw){const list=isRecord(raw)&&Array.isArray(raw["targets"])?raw["targets"]:raw;if(!Array.isArray(list))return{rows:[],errors:['JSON \u306F\u76EE\u6A19\u306E\u914D\u5217\uFF08\u307E\u305F\u306F {"targets": [...]}\uFF09\u306B\u3057\u3066\u304F\u3060\u3055\u3044']};
|
|
47
|
+
if(list.length===0)return{rows:[],errors:["\u76EE\u6A19\u304C1\u4EF6\u3082\u3042\u308A\u307E\u305B\u3093"]};const rows=[];const errors=[];list.forEach((item,index)=>{const at=`${index+1} \u4EF6\u76EE`;if(!isRecord(item)){errors.push(`${at}: \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093`);return}const unknown=Object.keys(item).filter(key=>!SET_ROW_KEYS.has(key));if(unknown.length>0)errors.push(`${at}: \u4F7F\u3048\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059: ${unknown.
|
|
48
|
+
join(", ")}\uFF08\u4F7F\u3048\u308B\u306E\u306F ${[...SET_ROW_KEYS].join(" / ")}\uFF09`);const hasName=item["department"]!==void 0;const hasId=item["department_id"]!==void 0;const ref=hasName?item["department"]:item["department_id"];if(hasName===hasId)errors.push(`${at}: department\uFF08\u540D\u524D\u30FB\u30B3\u30FC\u30C9\u30FBID\uFF09\u304B department_id \u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`);else if(typeof ref!=="string")errors.push(`${at}\
|
|
49
|
+
: \u90E8\u7F72\u306F\u6587\u5B57\u5217\uFF08\u540D\u524D\u30FB\u30B3\u30FC\u30C9\u30FBID\uFF09\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`);else if(ref.trim()==="")errors.push(`${at}: \u90E8\u7F72\u304C\u7A7A\u3067\u3059`);const month=item["month"];if(!Number.isInteger(month)||month<1||month>12)errors.push(`${at}: month \u306F 1\u301C12 \u306E\u6574\u6570\u3067\u3059`);const amount=key=>{const value=item[key];if(typeof value!=="number"||!Number.isFinite(value)||value<0){errors.push(`${at}: ${key}\
|
|
50
|
+
\u306F 0 \u4EE5\u4E0A\u306E\u6570\u5024\u3067\u3059\uFF08\u7701\u7565\u3067\u304D\u307E\u305B\u3093\uFF09`);return 0}return value};const sales=amount("sales_target");const profit=amount("profit_target");if(typeof ref==="string"&&Number.isInteger(month))rows.push({ref:ref.trim(),month,sales_target:sales,profit_target:profit})});return{rows,errors}}function readSetFile(file,usage){try{const stat=fs.statSync(file);if(!stat.isFile())throw new UsageError(`--file \u306B\u901A\u5E38\u306E\u30D5\u30A1\u30A4\u30EB\u4EE5\u5916\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093: ${file}`,
|
|
51
|
+
usage);if(stat.size>SET_FILE_MAX_BYTES)throw new UsageError(`--file \u306E\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u307E\u3059\uFF08${stat.size} \u30D0\u30A4\u30C8\uFF09: ${file}`,usage);return JSON.parse(fs.readFileSync(file,"utf8").replace(BOM,""))}catch(err){if(err instanceof UsageError)throw err;if(err instanceof SyntaxError)throw new UsageError(`--file \u3092 JSON \u3068\u3057\u3066\u8AAD\u3081\u307E\u305B\u3093: ${file}`,usage);throw new UsageError(`--file \u306E\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u3081\u307E\u305B\u3093: ${file}\
|
|
52
|
+
\uFF08${err.code??err.message}\uFF09`,usage)}}function overwriteLines(existing,incoming,names,year,verb="\u9001\u308A\u307E\u3059"){const before=new Map(existing.map(row=>[targetKey(row["department_id"],row["month"]),row]));const overwritten=incoming.filter(row=>before.has(targetKey(row.department_id,row.month)));const lines=[`${year} \u5E74\u5EA6\u306E\u76EE\u6A19\u3092 ${incoming.length} \u4EF6${verb}\uFF08\u4E0A\u66F8\u304D ${overwritten.length} \u4EF6\u30FB\u65B0\u898F ${incoming.length-overwritten.
|
|
53
|
+
length} \u4EF6\uFF09\u3002`];for(const row of overwritten.slice(0,SHOWN_OVERWRITES)){const old=before.get(targetKey(row.department_id,row.month));lines.push(` \u4E0A\u66F8\u304D: ${names.get(row.department_id)??row.department_id} ${row.month}\u6708 \u58F2\u4E0A ${yen(old["sales_target"])} \u2192 ${yen(row.sales_target)}\u30FB\u5229\u76CA ${yen(old["profit_target"])} \u2192 ${yen(row.profit_target)}`)}if(overwritten.length>SHOWN_OVERWRITES)lines.push(` \u2026\u307B\u304B ${overwritten.length-SHOWN_OVERWRITES}\
|
|
54
|
+
\u4EF6\u3092\u4E0A\u66F8\u304D\u3057\u307E\u3059`);return lines}var targetSetOperation={name:"set",summary:"\u5E74\u5EA6\u306E\u76EE\u6A19\u3092 JSON \u3067\u307E\u3068\u3081\u3066\u767B\u9332\u30FB\u4E0A\u66F8\u304D\u3059\u308B\uFF08--file\u30FB--yes \u304C\u8981\u308B\uFF09",usage:"twp budget target set --year <YYYY> --file <JSON> --yes",description:'POST /api/v2/budget/targets\u3002\uFF08\u5E74\u5EA6\u30FB\u90E8\u7F72\u30FB\u6708\uFF09\u3054\u3068\u306B\u58F2\u4E0A\u76EE\u6A19\u3068\u5229\u76CA\u76EE\u6A19\u3092\u66F8\u304D\u307E\u3059\u3002\u540C\u3058\uFF08\u90E8\u7F72\u30FB\u6708\uFF09\u306E\u65E2\u5B58\u306E\u76EE\u6A19\u306F\u4E0A\u66F8\u304D\u3055\u308C\u3001\u5143\u306B\u623B\u305B\u307E\u305B\u3093\n\uFF08\u76EE\u6A19\u3092\u6D88\u3059 API \u306F\u3042\u308A\u307E\u305B\u3093\u30020 \u3092\u66F8\u3051\u3070 0 \u306B\u306A\u308A\u307E\u3059\uFF09\u3002\u30D5\u30A1\u30A4\u30EB\u306B\u66F8\u304B\u306A\u304B\u3063\u305F\u90E8\u7F72\u30FB\u6708\u306F\u5909\u308F\u308A\u307E\u305B\u3093\u3002\nJS\
|
|
55
|
+
ON \u306F\u76EE\u6A19\u306E\u914D\u5217\u3067\u3059\uFF08{"targets": [...]} \u3067\u3082\u53EF\uFF09\u30021\u4EF6\u306F\u6B21\u306E\u5F62\u3067\u3001\u90E8\u7F72\u306F\u540D\u524D\u30FB\u30B3\u30FC\u30C9\u30FBID \u306E\u3044\u305A\u308C\u304B\u3067\u66F8\u3051\u307E\u3059:\n [{"department": "\u958B\u767A\u90E8", "month": 4, "sales_target": 1000000, "profit_target": 200000}]\n\u8AA4\u308A\uFF08\u4F7F\u3048\u306A\u3044\u9805\u76EE\u30FB\u6708\u306E\u7BC4\u56F2\u5916\u30FB\u8CA0\u306E\u91D1\u984D\u30FB\u540C\u3058\u90E8\u7F72\u3068\u6708\u306E\u91CD\u8907\uFF09\u306F\u9001\u308B\u524D\u306B\u5168\u90E8\u6319\u3052\u3066\u30011\u4EF6\u3082\u9001\u3089\u305A\u306B\u6B62\u3081\u307E\u3059\u3002\n\u9001\u308B\u524D\u306B\u4ECA\u306E\u76EE\u6A19\u3092\u8AAD\u307F\u3001\u4E0A\u66F8\u304D\u3055\u308C\u308B\u4EF6\u6570\u3068\u4E0A\u66F8\u304D\u524D\u5F8C\u306E\u5024\u3092 stderr \u306B\u51FA\u3057\u307E\u3059\uFF08--dry-run \u3067\u3082\u51FA\u307E\u3059\uFF09\u3002\n'+
|
|
56
|
+
EDIT_HINT,destructive:true,confirmation:"\u65E2\u5B58\u306E\u76EE\u6A19\u3092\u4E0A\u66F8\u304D\u3059\u308B\u64CD\u4F5C",flags:[REQUIRED_YEAR_FLAG,{name:"--file",summary:"\u76EE\u6A19\u306E JSON\uFF08\u5FC5\u9808\uFF09",takesValue:true,placeholder:"<JSON>"}],forbidden:FORBIDDEN,async prepare(input,ctx){const usage=usageOf("target set");noArgs(input,"target set");const year=fiscalYear(input,true);const file=nonEmpty(input.flags,"--file");if(file===void 0)throw new UsageError("--file <JSON> \u3092\u6307\u5B9A\u3057\u3066\u304F\
|
|
57
|
+
\u3060\u3055\u3044",usage);const parsed=parseTargetRows(readSetFile(file,usage));const errors=[...parsed.errors];const rows=[];for(const row of parsed.rows){try{const department=await ctx.resolver.department(row.ref,"department");rows.push({department_id:department.id,month:row.month,sales_target:row.sales_target,profit_target:row.profit_target})}catch(err){if(!(err instanceof UsageError))throw err;errors.push(`\u90E8\u7F72\u300C${row.ref}\u300D: ${err.message}`)}}const names=new Map((await ctx.
|
|
58
|
+
resolver.departments()).map(d=>[d.id,d.name]));const seen=new Set;for(const row of rows){const key=targetKey(row.department_id,row.month);if(seen.has(key))errors.push(`\u540C\u3058\u90E8\u7F72\u3068\u6708\u304C2\u56DE\u3042\u308A\u307E\u3059: ${names.get(row.department_id)??row.department_id} ${row.month}\u6708\uFF08\u5F8C\u306E\u884C\u304C\u9ED9\u3063\u3066\u52DD\u3064\u306E\u3067\u9001\u308A\u307E\u305B\u3093\uFF09`);seen.add(key)}if(errors.length>0)throw new UsageError(`--file \u306B\u8AA4\u308A\u304C ${errors.
|
|
59
|
+
length} \u4EF6\u3042\u308A\u307E\u3059\uFF081\u4EF6\u3082\u9001\u3063\u3066\u3044\u307E\u305B\u3093\uFF09:
|
|
60
|
+
${errors.join("\n ")}`,usage);const notes=overwriteLines(await currentTargets(ctx,year),rows,names,year);return withResolved(input,{targets:JSON.stringify(rows.map(row=>({fiscal_year:year,...row}))),notes:JSON.stringify(notes)})},plan:input=>({method:"POST",path:`${PATH}/targets`,body:{targets:JSON.parse(requireResolved(input,"targets"))}}),plannedNotes:input=>JSON.parse(requireResolved(input,"notes")),summarize:body=>dataRows(body,"\u4E88\u7B97\u76EE\u6A19").map(row=>pick(row,TARGET_WRITE_COLUMNS)),
|
|
61
|
+
raw:body=>dataRows(body,"\u4E88\u7B97\u76EE\u6A19"),notes:body=>[`${dataRows(body,"\u4E88\u7B97\u76EE\u6A19").length} \u4EF6\u306E\u76EE\u6A19\u3092\u66F8\u304D\u307E\u3057\u305F`]};var copyOperation={name:"copy-previous-year",summary:"\u524D\u5E74\u5EA6\u306E\u76EE\u6A19\u3092\u3001\u6307\u5B9A\u3057\u305F\u5E74\u5EA6\u3078\u305D\u306E\u307E\u307E\u5199\u3059\uFF08--yes \u304C\u8981\u308B\uFF09",usage:"twp budget target copy-previous-year --year <YYYY> [--department <\u90E8\u7F72>] --yes",description:"\
|
|
62
|
+
POST /api/v2/budget/targets/copy-previous-year\u3002--year \u306E\u524D\u5E74\u5EA6\uFF08YYYY-1\uFF09\u306E\u76EE\u6A19\u3092\u3001\u540C\u3058\u90E8\u7F72\u30FB\u6708\u306E --year \u306E\u76EE\u6A19\u3068\u3057\u3066\u66F8\u304D\u307E\u3059\u3002\n--year \u5074\u306B\u65E2\u306B\u76EE\u6A19\u304C\u3042\u308B\uFF08\u90E8\u7F72\u30FB\u6708\uFF09\u306F\u524D\u5E74\u5EA6\u306E\u5024\u3067\u4E0A\u66F8\u304D\u3055\u308C\u3001\u5143\u306B\u623B\u305B\u307E\u305B\u3093\u3002\u524D\u5E74\u5EA6\u306B\u76EE\u6A19\u306E\u7121\u3044\u90E8\u7F72\u30FB\u6708\u306F\u5909\u308F\u308A\u307E\u305B\u3093\u3002\n--department \u3092\u4ED8\u3051\u308B\u3068\u3001\u305D\u306E\u90E8\u7F72\u306E\u76EE\u6A19\u3060\u3051\u3092\u5199\u3057\u307E\u3059\uFF08\u914D\u4E0B\u306E\u90E8\u7F72\u306F\u542B\u307F\u307E\u305B\u3093\uFF09\u3002\n\u9001\u308B\u524D\u306B\u3001\u5199\u3059\u4EF6\u6570\u3068\u4E0A\u66F8\u304D\u3055\u308C\u308B\u4EF6\u6570\u3092 stderr \u306B\u51FA\u3057\u307E\u3059\uFF08--dry-run \u3067\u3082\u51FA\u307E\u3059\uFF09\u3002\u524D\u5E74\u5EA6\u306B\u76EE\u6A19\u304C\u7121\u3051\u308C\u3070\u4F55\u3082\u5199\u308A\u307E\u305B\u3093\u3002\n"+
|
|
63
|
+
EDIT_HINT,destructive:true,confirmation:"\u65E2\u5B58\u306E\u76EE\u6A19\u3092\u4E0A\u66F8\u304D\u3059\u308B\u64CD\u4F5C",flags:[REQUIRED_YEAR_FLAG,DEPARTMENT_FLAG],forbidden:FORBIDDEN,async prepare(input,ctx){noArgs(input,"target copy-previous-year");const year=fiscalYear(input,true);const department=nonEmpty(input.flags,DEPARTMENT_FLAG.name);const departmentId=department===void 0?void 0:(await ctx.resolver.department(department)).id;const source=await currentTargets(ctx,year-1,departmentId);const existing=await currentTargets(
|
|
64
|
+
ctx,year,departmentId);const names=new Map((await ctx.resolver.departments()).map(d=>[d.id,d.name]));const incoming=source.map(row=>({department_id:String(row["department_id"]),month:Number(row["month"]),sales_target:Number(row["sales_target"]),profit_target:Number(row["profit_target"])}));const notes=incoming.length===0?[`\u524D\u5E74\u5EA6\uFF08${year-1}\uFF09\u306B\u76EE\u6A19\u304C\u7121\u3044\u305F\u3081\u3001\u4F55\u3082\u5199\u308A\u307E\u305B\u3093\u3002`]:[`\u524D\u5E74\u5EA6\uFF08${year-
|
|
65
|
+
1}\uFF09\u306E\u76EE\u6A19\u3092\u5199\u3057\u307E\u3059\uFF08\u5199\u3059\u306E\u306F\u30B5\u30FC\u30D0\u3067\u3059\uFF09\u3002`,...overwriteLines(existing,incoming,names,year,"\u66F8\u304D\u307E\u3059")];return withResolved(input,{...departmentId===void 0?{}:{departmentId},notes:JSON.stringify(notes)})},plan:input=>({method:"POST",path:`${PATH}/targets/copy-previous-year`,body:{fiscal_year:fiscalYear(input,true),...input.resolved?.["departmentId"]===void 0?{}:{department_id:input.resolved["dep\
|
|
66
|
+
artmentId"]}}}),plannedNotes:input=>JSON.parse(requireResolved(input,"notes")),summarize:body=>dataRows(body,"\u524D\u5E74\u5EA6\u306E\u76EE\u6A19\u306E\u30B3\u30D4\u30FC").map(row=>pick(row,TARGET_WRITE_COLUMNS)),raw:body=>({copied_count:envelope(body,"\u524D\u5E74\u5EA6\u306E\u76EE\u6A19\u306E\u30B3\u30D4\u30FC")["copied_count"]??null,data:dataRows(body,"\u524D\u5E74\u5EA6\u306E\u76EE\u6A19\u306E\u30B3\u30D4\u30FC")}),notes:body=>[`${text(envelope(body,"\u524D\u5E74\u5EA6\u306E\u76EE\u6A19\u306E\u30B3\u30D4\u30FC")["\
|
|
67
|
+
copied_count"])} \u4EF6\u306E\u76EE\u6A19\u3092\u5199\u3057\u307E\u3057\u305F`]};function isImportOutcome(body){return isRecord(body)&&body["budgetImport"]===true}var TARGET_IMPORT_OP=["target","import"].join(" ");async function prepareImport(input,ctx){const usage=usageOf(TARGET_IMPORT_OP);noArgs(input,TARGET_IMPORT_OP);const year=fiscalYear(input,true);const file=nonEmpty(input.flags,"--file");if(file===void 0)throw new UsageError("--file <CSV> \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
68
|
+
usage);let bytes;try{const stat=fs.statSync(file);if(!stat.isFile())throw new UsageError(`--file \u306B\u901A\u5E38\u306E\u30D5\u30A1\u30A4\u30EB\u4EE5\u5916\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093: ${file}`,usage);if(stat.size>IMPORT_MAX_BYTES)throw new UsageError(`--file \u306E\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u307E\u3059\uFF08${stat.size} \u30D0\u30A4\u30C8\u30FB\u30B5\u30FC\u30D0\u304C\u53D7\u3051\u308B\u306E\u306F ${IMPORT_MAX_BYTES} \u30D0\u30A4\u30C8\u307E\u3067\uFF09: ${file}`,
|
|
69
|
+
"\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u3051\u3066\u53D6\u308A\u8FBC\u3093\u3067\u304F\u3060\u3055\u3044\u3002");bytes=fs.readFileSync(file)}catch(err){if(err instanceof UsageError)throw err;throw new UsageError(`--file \u306E\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u3081\u307E\u305B\u3093: ${file}\uFF08${err.code??err.message}\uFF09`,usage)}const existing=await currentTargets(ctx,year);const departments=new Set(existing.map(row=>String(row["department_id"]))).size;const notes=[existing.length===0?`${year}\
|
|
70
|
+
\u5E74\u5EA6\u306B\u76EE\u6A19\u306F\u307E\u3060\u3042\u308A\u307E\u305B\u3093\u3002`:`${year} \u5E74\u5EA6\u306B\u306F\u65E2\u306B\u76EE\u6A19\u304C ${existing.length} \u4EF6\uFF08${departments} \u90E8\u7F72\uFF09\u3042\u308A\u307E\u3059\u3002CSV \u306B\u5024\u306E\u3042\u308B\u90E8\u7F72\u30FB\u6708\u306F\u4E0A\u66F8\u304D\u3055\u308C\u3001\u5143\u306B\u623B\u305B\u307E\u305B\u3093\uFF08CSV \u306B\u7121\u3044\u90E8\u7F72\u30FB\u6708\u306F\u5909\u308F\u308A\u307E\u305B\u3093\uFF09\u3002`,"\u30B5\u30FC\u30D0\u304C\
|
|
71
|
+
\u5168\u884C\u3092\u691C\u67FB\u3057\u3001\u691C\u67FB\u30671\u884C\u3067\u3082\u8AA4\u308A\u304C\u3042\u308C\u30701\u4EF6\u3082\u66F8\u304D\u307E\u305B\u3093\uFF08\u305D\u306E\u3068\u304D\u306F\u884C\u3054\u3068\u306E\u7406\u7531\u3092\u3059\u3079\u3066\u51FA\u3057\u307E\u3059\uFF09\u3002"];return withResolved(input,{fileName:path.basename(file),fileBase64:bytes.toString("base64"),notes:JSON.stringify(notes)})}function importPlan(input){const bytes=Buffer.from(requireResolved(input,"fileBase64"),
|
|
72
|
+
"base64");return{method:"POST",path:`${PATH}/targets/import`,body:new MultipartBody({fiscal_year:String(fiscalYear(input,true))},[{field:"file",filename:requireResolved(input,"fileName"),contentType:"text/csv",bytes:new Uint8Array(bytes)}])}}function importRejection(err){if(!(err instanceof ApiError)||err.status!==422||!isRecord(err.body))return void 0;const body=err.body;const errors=Array.isArray(body["errors"])?body["errors"].filter(e=>typeof e==="string"):[];if(errors.length===0)return void 0;
|
|
73
|
+
const head=text(body["message"])||"CSV \u3092\u53D6\u308A\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F\u3002";return new ApiRejectedError(`${head} \u8AA4\u308A\u304C ${errors.length} \u4EF6\u3042\u308A\u307E\u3059\uFF081\u4EF6\u3082\u66F8\u3044\u3066\u3044\u307E\u305B\u3093\uFF09:
|
|
74
|
+
${errors.join("\n ")}`)}async function runImport(input,ctx){let body;try{body=await ctx.send(importPlan(input))}catch(err){const rejected=importRejection(err);if(rejected!==void 0)throw rejected;if(!(err instanceof ApiError)||err.status>=500){ctx.warn("\u53D6\u308A\u8FBC\u307F\u306E\u9014\u4E2D\u3067\u5931\u6557\u3057\u305F\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u4E00\u90E8\u306E\u76EE\u6A19\u304C\u66F8\u304B\u308C\u3066\u3044\u308B\u3053\u3068\u304C\u3042\u308B\u306E\u3067\u3001twp budget target list --year \u3067\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002")}
|
|
75
|
+
throw err}const data=dataRecord(body,"\u76EE\u6A19\u306E\u53D6\u308A\u8FBC\u307F");return{budgetImport:true,imported_count:data["imported_count"]??null,message:data["message"]??null}}var targetImportOperation={name:"import",summary:"\u76EE\u6A19\u3092 CSV \u3067\u53D6\u308A\u8FBC\u3080\uFF08--year\u30FB--file\u30FB--yes \u304C\u8981\u308B\uFF09",usage:"twp budget target import --year <YYYY> --file <CSV> --yes",description:"POST /api/v2/budget/targets/import\u3002\u96DB\u5F62\uFF08twp budget target import-template\uFF09\u306E\
|
|
76
|
+
\u5F62\u306E CSV \u3092\u3001--year \u306E\u5E74\u5EA6\u306E\u76EE\u6A19\u3068\u3057\u3066\u53D6\u308A\u8FBC\u307F\u307E\u3059\u3002\n\u5217\u306F department_id\uFF08\u90E8\u7F72 ID \u304B\u90E8\u7F72\u540D\uFF09\u3068 sales_target_<\u6708> / profit_target_<\u6708>\uFF081\u301C12\u30FB\u300C<\u6708>\u6708_\u58F2\u4E0A\u76EE\u6A19\u300D\u3067\u3082\u53EF\uFF09\u3067\u3059\u3002\n\u5024\u306E\u3042\u308B\uFF08\u90E8\u7F72\u30FB\u6708\uFF09\u3060\u3051\u3092\u66F8\u304D\u3001\u65E2\u5B58\u306E\u76EE\u6A19\u306F\u4E0A\u66F8\u304D\u3055\u308C\u307E\u3059\uFF08\u5143\u306B\u623B\u305B\u307E\u305B\u3093\uFF09\u3002\u7A7A\u306E\u6708\u306F\u5909\u308F\u308A\u307E\u305B\u3093\u3002\n\u6587\u5B57\u30B3\u30FC\u30C9\u306F UTF-8\uFF08BOM \u4ED8\u304D\u3067\u3082\u53EF\uFF09\u304B Shift_JIS\uFF08Excel \u306E\u65E2\u5B9A\uFF09\u3067\u3059\u3002\u5224\u5B9A\u306F\u30B5\u30FC\u30D0\u304C\u884C\u3044\u307E\u3059\u3002\n\u30B5\u30FC\u30D0\u306F\u5168\u884C\u3092\u691C\u67FB\u3057\u30011\u884C\u3067\u3082\u8AA4\u308A\uFF08\u90E8\u7F72\u304C\u898B\u3064\u304B\u3089\u306A\u3044\u30FB\u6570\u5024\u3067\u306A\u3044\u30FB\u8CA0\u306E\u5024\u30FB\u5024\u304C1\u3064\u3082\u7121\u3044\u884C\uFF09\u304C\u3042\u308C\u30701\u4EF6\u3082\u66F8\u304B\u305A\u306B\n\u884C\u3054\u3068\u306E\u7406\u7531\u3092\u8FD4\u3057\u307E\u3059\u3002CLI \u306F\u305D\u308C\u3092\u3059\u3079\u3066\u51FA\u3057\u3066\u7D42\u4E86\u30B3\u30FC\u30C9 3 \u3067\u7D42\u308F\u308A\u307E\u3059\uFF08\u691C\u67FB\u3092\u901A\u3063\u305F\u5F8C\u306E\u66F8\u304D\u8FBC\u307F\u306E\u9014\u4E2D\u3067\u5931\u6557\u3057\u305F\u3068\u304D\u306F\u3001\n\u4E00\u90E8\u304C\u66F8\u304B\u308C\u3066\u3044\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u305D\u306E\u3068\u304D\u306F stderr \u3067\u305D\u3046\u8A00\u3044\u307E\u3059\uFF09\u3002\n\u9001\u308B\u524D\u306B\u3001\u305D\u306E\u5E74\u5EA6\u306E\u65E2\u5B58\u306E\u76EE\u6A19\u306E\u4EF6\u6570\u3092 stderr \u306B\u51FA\u3057\u307E\u3059\uFF08--dry-run \u3067\u3082\u51FA\u307E\u3059\u3002CSV \u306E\u4E2D\u8EAB\u306F\u51FA\u3057\u307E\u305B\u3093\uFF09\u3002\n"+
|
|
77
|
+
EDIT_HINT,destructive:true,confirmation:"\u65E2\u5B58\u306E\u76EE\u6A19\u3092\u4E0A\u66F8\u304D\u3059\u308B\u64CD\u4F5C",flags:[REQUIRED_YEAR_FLAG,{name:"--file",summary:"\u53D6\u308A\u8FBC\u3080 CSV\uFF08\u5FC5\u9808\u30FB1\u884C\u76EE\u304C\u898B\u51FA\u3057\uFF09",takesValue:true,placeholder:"<CSV>"}],forbidden:FORBIDDEN,prepare:prepareImport,plan:importPlan,plannedNotes:input=>JSON.parse(requireResolved(input,"notes")),execute:runImport,summarize:body=>isImportOutcome(body)?{imported_count:body.
|
|
78
|
+
imported_count}:body,raw:body=>isImportOutcome(body)?{imported_count:body.imported_count,message:body.message}:body,notes:body=>isImportOutcome(body)&&typeof body.message==="string"?[body.message]:[]};var templateOperation={name:"import-template",summary:"\u76EE\u6A19\u306E\u53D6\u308A\u8FBC\u307F\u7528 CSV \u306E\u96DB\u5F62\u3092\u66F8\u304D\u51FA\u3059\uFF08--out\uFF09",usage:"twp budget target import-template --out <\u30D1\u30B9.csv> [--force] [--year <YYYY>] [--start-month <\u6708>]",description:"\
|
|
79
|
+
GET /api/v2/budget/targets/import-template\u3002\u90E8\u7F72\u3054\u3068\u306B1\u884C\uFF08department_id\u30FB\u90E8\u7F72\u540D\u3068\u3001\u6708\u3054\u3068\u306E\u7A7A\u306E\u58F2\u4E0A\u76EE\u6A19\u30FB\u5229\u76CA\u76EE\u6A19\u306E\u5217\uFF09\u306E CSV\uFF08UTF-8\u30FBBOM \u4ED8\u304D\uFF09\u3067\u3059\u3002\n--year \u3092\u4ED8\u3051\u308B\u3068\u305D\u306E\u5E74\u5EA6\u306B\u5728\u7C4D\u3057\u3066\u3044\u305F\u90E8\u7F72\uFF08\u5E74\u5EA6\u9014\u4E2D\u3067\u7D42\u4E86\u3057\u305F\u90E8\u7F72\u3092\u542B\u3080\uFF09\u3001\u7701\u304F\u3068\u4ECA\u65E5\u6642\u70B9\u3067\u6709\u52B9\u306A\u90E8\u7F72\u304C\u4E26\u3073\u307E\u3059\u3002\n\u5024\u3092\u57CB\u3081\u3066 twp budget target import \u3067\u53D6\u308A\u8FBC\u307F\u307E\u3059\u3002\u65E2\u5B58\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u4E0A\u66F8\u304D\u3057\u307E\u305B\u3093\uFF08\u4E0A\u66F8\u304D\u3059\u308B\u306A\u3089 --force\uFF09\u3002",
|
|
80
|
+
flags:[OUT_FLAG,FORCE_FLAG,TEMPLATE_YEAR_FLAG,START_MONTH_FLAG],download:{outFlag:OUT_FLAG.name,forceFlag:FORCE_FLAG.name},forbidden:FORBIDDEN,plan:input=>{noArgs(input,"target import-template");return{method:"GET",path:`${PATH}/targets/import-template`,query:periodQuery(input,false)}},summarize:body=>body,raw:body=>body};var targetResource={name:"target",summary:"\u5E74\u5EA6\u306E\u76EE\u6A19\uFF08\u4E00\u89A7\u30FB\u307E\u3068\u3081\u3066\u767B\u9332\u30FB\u524D\u5E74\u5EA6\u304B\u3089\u306E\u30B3\u30D4\u30FC\u30FBCSV \u306E\u53D6\u308A\u8FBC\u307F\u3068\u96DB\u5F62\uFF09",
|
|
81
|
+
operations:[targetListOperation,targetSetOperation,copyOperation,targetImportOperation,templateOperation]};var ALLOCATION_COLUMNS=["department_id","department_name","allocation_type","percentage","amount","updated_at"];var PROJECT_FLAG={name:"--project",summary:"\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF08\u30B3\u30FC\u30C9\u30FBID\u3002\u7701\u304F\u3068\u65E2\u5B9A\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\uFF09",takesValue:true,placeholder:"<\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8>"};var SPLIT_FLAG={
|
|
82
|
+
name:"--split",summary:"<\u90E8\u7F72>=<\u6BD4\u7387>%\uFF08\u6BD4\u7387\uFF09\u304B <\u90E8\u7F72>=<\u91D1\u984D>\uFF08\u5186\uFF09\u3002\u8907\u6570\u56DE\u6307\u5B9A\u53EF",takesValue:true,placeholder:"<\u90E8\u7F72>=<\u5024>",repeatable:true};var CLEAR_FLAG={name:"--clear",summary:"\u6309\u5206\u3092\u3059\u3079\u3066\u6D88\u3059\uFF08--split \u3068\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u306A\u3044\uFF09",takesValue:false};function parseSplit(raw){const at=raw.lastIndexOf("=");const ref=at<
|
|
83
|
+
0?"":raw.slice(0,at).trim();const valueText=at<0?"":raw.slice(at+1).trim();const bad=new UsageError(`--split \u306F <\u90E8\u7F72>=<\u6BD4\u7387>%\uFF080\u301C100\uFF09\u304B <\u90E8\u7F72>=<\u91D1\u984D>\uFF080 \u4EE5\u4E0A\u306E\u6574\u6570\u30FB\u5186\uFF09\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044: ${raw}`,usageOf("allocation set"));if(ref==="")throw bad;if(valueText.endsWith("%")){const number=valueText.slice(0,-1).trim();const value2=Number(number);if(!/^\d+(\.\d+)?$/.test(number)||
|
|
84
|
+
value2>100)throw bad;return{ref,type:"percentage",value:value2}}const value=Number(valueText);if(!/^\d+$/.test(valueText)||value>AMOUNT_MAX)throw bad;return{ref,type:"amount",value}}function splitLabel(row){return row.allocation_type==="amount"?yen(row.amount):`${text(row.percentage)}%`}async function prepareAllocationSet(input,ctx){const usage=usageOf("allocation set");noArgs(input,"allocation set");const raws=repeatedValues(input,SPLIT_FLAG.name);const clear=input.flags.has(CLEAR_FLAG.name);if(clear&&
|
|
85
|
+
raws.length>0)throw new UsageError("--clear \u3068 --split \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093",usage);if(!clear&&raws.length===0)throw new UsageError("\u6309\u5206\u3092 --split <\u90E8\u7F72>=<\u5024> \u30671\u3064\u4EE5\u4E0A\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u6309\u5206\u3092\u3059\u3079\u3066\u6D88\u3059\u306A\u3089 --clear\uFF09",usage);const parsed=raws.map(parseSplit);const projectId=await ctx.projectId(nonEmpty(input.flags,PROJECT_FLAG.
|
|
86
|
+
name));const splits=[];for(const{ref,type,value}of parsed){const department=await ctx.resolver.department(ref,SPLIT_FLAG.name);if(splits.some(s=>s.department_id===department.id))throw new UsageError(`\u540C\u3058\u90E8\u7F72\u304C2\u56DE\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059: ${department.name}`,usage);splits.push(type==="amount"?{department_id:department.id,allocation_type:"amount",amount:value}:{department_id:department.id,allocation_type:"percentage",percentage:value})}let before;try{
|
|
87
|
+
before=dataRows(await ctx.resolver.salesJson(`${PATH}/allocations?project_id=${encodeURIComponent(projectId)}`,"\u90E8\u7F72\u6309\u5206"),"\u90E8\u7F72\u6309\u5206")}catch(err){if(!(err instanceof ApiError&&err.status===403))throw err}const names=new Map((await ctx.resolver.departments()).map(d=>[d.id,d.name]));const label=id=>names.get(String(id))??String(id);const notes=[clear?`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8 ${projectId} \u306E\u90E8\u7F72\u6309\u5206\u3092\u3059\u3079\u3066\u6D88\u3057\u307E\u3059:`:
|
|
88
|
+
`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8 ${projectId} \u306E\u90E8\u7F72\u6309\u5206\u3092\u5168\u4EF6\u7F6E\u304D\u63DB\u3048\u307E\u3059\uFF08\u6307\u5B9A\u3057\u306A\u304B\u3063\u305F\u90E8\u7F72\u306E\u6309\u5206\u306F\u6D88\u3048\u307E\u3059\uFF09:`,...before===void 0?[" \u7F6E\u63DB\u524D: \u8AAD\u3081\u307E\u305B\u3093\uFF08\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u95B2\u89A7\u3067\u304D\u306A\u3044\u305F\u3081\u3002\u65E2\u5B58\u306E\u6309\u5206\u306F\u5168\u90E8\u7F6E\u304D\u63DB\u308F\u308A\u307E\u3059\uFF09"]:
|
|
89
|
+
before.length===0?[" \u7F6E\u63DB\u524D: \u306A\u3057"]:before.map(row=>` \u7F6E\u63DB\u524D: ${label(row["department_id"])} ${splitLabel(row)}`),...clear?[" \u7F6E\u63DB\u5F8C: \u306A\u3057"]:splits.map(s=>` \u7F6E\u63DB\u5F8C: ${label(s.department_id)} ${splitLabel(s)}`)];return withResolved(input,{projectId,body:JSON.stringify({project_id:projectId,allocations:splits}),notes:JSON.stringify(notes)})}var allocationResource={name:"allocation",summary:"\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u90E8\u7F72\u6309\u5206\uFF08\u4E88\u5B9F\u306E\u90E8\u7F72\u5225\u306E\u58F2\u4E0A\u306E\u914D\u308A\u65B9\u30FB\u4E00\u89A7\u3068\u5168\u4EF6\u7F6E\u63DB\uFF09",
|
|
90
|
+
operations:[{name:"list",summary:"\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u90E8\u7F72\u6309\u5206\u3092\u8868\u793A\u3059\u308B",usage:"twp budget allocation list [--project <\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8>]",description:`GET /api/v2/budget/allocations\u3002\u6309\u5206\u304C\u7121\u3051\u308C\u3070\u7A7A\u306E\u4E00\u89A7\u3067\u3059\uFF08\u3053\u306E API \u306F\u30DA\u30FC\u30B8\u30F3\u30B0\u3092\u6301\u3061\u307E\u305B\u3093\uFF09\u3002
|
|
91
|
+
\u6309\u5206\u306F\u884C\u3054\u3068\u306B\u6BD4\u7387\uFF08percentage\u30FB%\uFF09\u304B\u91D1\u984D\uFF08amount\u30FB\u5186\uFF09\u306E\u3069\u3061\u3089\u304B\u3067\u3001\u4F7F\u308F\u306A\u3044\u5074\u306F 0 \u3067\u3059\u3002
|
|
92
|
+
--output table / text / tsv \u306F\u8981\u7D04\u5217\uFF08${ALLOCATION_COLUMNS.join(" / ")}\uFF09\u3067\u3059\u3002`,flags:[PROJECT_FLAG],forbidden:FORBIDDEN,async prepare(input,ctx){noArgs(input,"allocation list");return withResolved(input,{projectId:await ctx.projectId(nonEmpty(input.flags,PROJECT_FLAG.name))})},plan:input=>({method:"GET",path:`${PATH}/allocations`,query:{project_id:requireResolved(input,"projectId")}}),summarize:body=>dataRows(body,"\u90E8\u7F72\u6309\u5206").map(row=>pick(row,
|
|
93
|
+
ALLOCATION_COLUMNS)),raw:body=>dataRows(body,"\u90E8\u7F72\u6309\u5206"),notes:body=>dataRows(body,"\u90E8\u7F72\u6309\u5206").length===0?["\u90E8\u7F72\u6309\u5206\u306F\u3042\u308A\u307E\u305B\u3093"]:[]},{name:"set",summary:"\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u90E8\u7F72\u6309\u5206\u3092\u5168\u4EF6\u7F6E\u304D\u63DB\u3048\u308B\uFF08--clear \u3067\u5168\u90E8\u6D88\u3059\u30FB--yes \u304C\u8981\u308B\uFF09",usage:"twp budget allocation set [--project <\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8>] (--split <\u90E8\u7F72>=<\u5024>... |\
|
|
94
|
+
--clear) --yes",description:"POST /api/v2/budget/allocations \u3067\u6309\u5206\u3092**\u5168\u4EF6\u7F6E\u304D\u63DB\u3048\u307E\u3059**\uFF08\u6307\u5B9A\u3057\u306A\u304B\u3063\u305F\u90E8\u7F72\u306E\u6309\u5206\u306F\u6D88\u3048\u3001\u5143\u306B\u623B\u305B\u307E\u305B\u3093\uFF09\u3002\n--split <\u90E8\u7F72>=60% \u306F\u6BD4\u7387\u3001--split <\u90E8\u7F72>=500000 \u306F\u91D1\u984D\uFF08\u5186\uFF09\u3067\u3059\u3002\u884C\u3054\u3068\u306B\u6DF7\u305C\u3089\u308C\u307E\u3059\u3002--clear \u306F\u6309\u5206\u3092\u3059\u3079\u3066\u6D88\u3057\u307E\u3059\u3002\n**\u6BD4\u7387\u306E\u5408\u8A08\uFF08100%\uFF09\u306F\u30B5\u30FC\u30D0\u3082 CLI \u3082\u691C\u67FB\u3057\u307E\u305B\u3093**\uFF08\u884C\u3054\u3068\u306E\u7BC4\u56F2\u3060\u3051\u3092\u898B\u307E\u3059\uFF09\u3002\u5408\u8A08\u306F\u9001\u308B\u524D\u306B\u81EA\u5206\u3067\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\n\u9001\u308B\u524D\u306B\u7F6E\u63DB\u524D\u3068\u7F6E\u63DB\u5F8C\u306E\u6309\u5206\u3092 stderr \u306B\u51FA\u3057\u307E\u3059\uFF08--dry-run \u3067\u3082\u51FA\u307E\u3059\uFF09\u3002\n \u4F8B: twp budget allocation set --project SAMPLE --split \u958B\u767A\u90E8=60% --split \u55B6\u696D\u90E8=40% --yes\n"+
|
|
95
|
+
EDIT_HINT,destructive:true,confirmation:"\u90E8\u7F72\u6309\u5206\u3092\u5168\u4EF6\u7F6E\u304D\u63DB\u3048\u308B\u64CD\u4F5C",flags:[PROJECT_FLAG,SPLIT_FLAG,CLEAR_FLAG],forbidden:FORBIDDEN,prepare:prepareAllocationSet,plan:input=>({method:"POST",path:`${PATH}/allocations`,body:JSON.parse(requireResolved(input,"body"))}),plannedNotes:input=>JSON.parse(requireResolved(input,"notes")),summarize:body=>dataRows(body,"\u90E8\u7F72\u6309\u5206").map(row=>pick(row,ALLOCATION_COLUMNS.filter(column=>column!==
|
|
96
|
+
"department_name"))),raw:body=>dataRows(body,"\u90E8\u7F72\u6309\u5206"),notes:body=>[`\u90E8\u7F72\u6309\u5206\u3092 ${dataRows(body,"\u90E8\u7F72\u6309\u5206").length} \u4EF6\u306B\u3057\u307E\u3057\u305F`]}]};var budgetDomain={name:"budget",summary:"\u4E88\u5B9F\u7BA1\u7406\uFF08\u5E74\u5EA6\u306E\u76EE\u6A19\u30FB\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u30FB\u30B5\u30DE\u30EA\u30FC\u30FB\u5185\u8A33\u30FBCSV \u51FA\u529B\u3001\u76EE\u6A19\u306E\u767B\u9332\u3068\u53D6\u308A\u8FBC\u307F\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u90E8\u7F72\u6309\u5206\uFF09",
|
|
97
|
+
operations:[dashboardOperation,summaryOperation,breakdownOperation,unassignedOperation,exportOperation],subresources:[targetResource,allocationResource]};export{breakdownRows,budgetDomain,dashboardRows,fiscalYear,importRejection,overwriteLines,parseSplit,parseTargetRows};
|