task-recorder-cui 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. task_recorder_cui-1.0.0/LICENSE +21 -0
  2. task_recorder_cui-1.0.0/PKG-INFO +207 -0
  3. task_recorder_cui-1.0.0/README.md +175 -0
  4. task_recorder_cui-1.0.0/pyproject.toml +100 -0
  5. task_recorder_cui-1.0.0/setup.cfg +4 -0
  6. task_recorder_cui-1.0.0/src/task_recorder_cui/__init__.py +3 -0
  7. task_recorder_cui-1.0.0/src/task_recorder_cui/__main__.py +5 -0
  8. task_recorder_cui-1.0.0/src/task_recorder_cui/cli.py +162 -0
  9. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/__init__.py +0 -0
  10. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/_summary.py +246 -0
  11. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/add.py +63 -0
  12. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/all.py +37 -0
  13. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/cat.py +172 -0
  14. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/month.py +56 -0
  15. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/now.py +31 -0
  16. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/range.py +53 -0
  17. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/start.py +69 -0
  18. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/stop.py +38 -0
  19. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/today.py +71 -0
  20. task_recorder_cui-1.0.0/src/task_recorder_cui/commands/week.py +57 -0
  21. task_recorder_cui-1.0.0/src/task_recorder_cui/db.py +118 -0
  22. task_recorder_cui-1.0.0/src/task_recorder_cui/io.py +33 -0
  23. task_recorder_cui-1.0.0/src/task_recorder_cui/main.py +9 -0
  24. task_recorder_cui-1.0.0/src/task_recorder_cui/menu.py +344 -0
  25. task_recorder_cui-1.0.0/src/task_recorder_cui/models.py +51 -0
  26. task_recorder_cui-1.0.0/src/task_recorder_cui/repo.py +252 -0
  27. task_recorder_cui-1.0.0/src/task_recorder_cui/utils/__init__.py +0 -0
  28. task_recorder_cui-1.0.0/src/task_recorder_cui/utils/time.py +122 -0
  29. task_recorder_cui-1.0.0/src/task_recorder_cui/utils/validate.py +23 -0
  30. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/PKG-INFO +207 -0
  31. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/SOURCES.txt +52 -0
  32. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/dependency_links.txt +1 -0
  33. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/entry_points.txt +2 -0
  34. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/requires.txt +9 -0
  35. task_recorder_cui-1.0.0/src/task_recorder_cui.egg-info/top_level.txt +1 -0
  36. task_recorder_cui-1.0.0/tests/test_add.py +47 -0
  37. task_recorder_cui-1.0.0/tests/test_all.py +29 -0
  38. task_recorder_cui-1.0.0/tests/test_cat.py +148 -0
  39. task_recorder_cui-1.0.0/tests/test_cli.py +64 -0
  40. task_recorder_cui-1.0.0/tests/test_db.py +41 -0
  41. task_recorder_cui-1.0.0/tests/test_io.py +26 -0
  42. task_recorder_cui-1.0.0/tests/test_menu_pure.py +95 -0
  43. task_recorder_cui-1.0.0/tests/test_menu_smoke.py +32 -0
  44. task_recorder_cui-1.0.0/tests/test_month.py +40 -0
  45. task_recorder_cui-1.0.0/tests/test_now.py +29 -0
  46. task_recorder_cui-1.0.0/tests/test_range.py +54 -0
  47. task_recorder_cui-1.0.0/tests/test_repo_recent.py +70 -0
  48. task_recorder_cui-1.0.0/tests/test_start.py +69 -0
  49. task_recorder_cui-1.0.0/tests/test_stop.py +37 -0
  50. task_recorder_cui-1.0.0/tests/test_summary.py +70 -0
  51. task_recorder_cui-1.0.0/tests/test_time.py +103 -0
  52. task_recorder_cui-1.0.0/tests/test_today.py +68 -0
  53. task_recorder_cui-1.0.0/tests/test_validate.py +28 -0
  54. task_recorder_cui-1.0.0/tests/test_week.py +41 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yumeno Yuuka
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: task-recorder-cui
3
+ Version: 1.0.0
4
+ Summary: Minimal, no-friction CUI time tracker with weekly and monthly summaries
5
+ Author: Yumeno Yuuka
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/yuuka-dev/task-recorder-cui
8
+ Project-URL: Repository, https://github.com/yuuka-dev/task-recorder-cui
9
+ Project-URL: Issues, https://github.com/yuuka-dev/task-recorder-cui/issues
10
+ Keywords: time-tracking,cli,productivity,sqlite
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Office/Business :: Scheduling
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: rich
24
+ Requires-Dist: questionary
25
+ Provides-Extra: dev
26
+ Requires-Dist: ruff; extra == "dev"
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: jupyterlab; extra == "dev"
30
+ Requires-Dist: pandas; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # task-recorder-cui
34
+
35
+ [![CI](https://github.com/yuuka-dev/task-recorder-cui/actions/workflows/ci.yml/badge.svg)](https://github.com/yuuka-dev/task-recorder-cui/actions/workflows/ci.yml)
36
+ [![codecov](https://codecov.io/gh/yuuka-dev/task-recorder-cui/branch/main/graph/badge.svg)](https://codecov.io/gh/yuuka-dev/task-recorder-cui)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
38
+ [![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://www.python.org/)
39
+
40
+ > **一言で説明**: 日々の時間の使い方を記録し、週平均・月平均で可視化するCUIツール。タスク管理ではなく「時間記録」に特化しています。
41
+
42
+ ## 概要
43
+
44
+ ### なぜ作ったのか
45
+
46
+ Toggl などのタイムトラッキングツールは多機能ですが、項目が多すぎて続かないことがあります。本ツールは「何を・何時間・いつやったか」を **極限まで削ぎ落としたコマンド** で記録し、週平均・月平均を数字だけで見ることに特化しています。
47
+
48
+ 毎日使うのが苦にならない軽さを最優先に設計しました。
49
+
50
+ ## 主な機能
51
+
52
+ - `tsk start` / `tsk stop` で時間を記録(ストップウォッチ形式)
53
+ - `tsk add` で事後に手動追加
54
+ - `tsk today` / `tsk week` / `tsk month` で集計を表示
55
+ - カテゴリは自由に追加・アーカイブ可能(初期は `game` / `study` / `dev` の3つ)
56
+ - サブコマンドなしで起動すると階層型インタラクティブメニュー
57
+
58
+ ## 技術スタック
59
+
60
+ | カテゴリ | 技術 |
61
+ |---|---|
62
+ | 言語 | Python 3.11+ |
63
+ | データストア | SQLite(標準ライブラリ `sqlite3`) |
64
+ | CLI | `argparse` |
65
+ | 出力整形 | `rich` |
66
+ | インタラクティブ選択 | `questionary` |
67
+ | パッケージ管理 | `pyproject.toml` + `pip install -e .` |
68
+
69
+ ## はじめ方
70
+
71
+ ### 前提条件
72
+
73
+ - Python 3.11 以上
74
+ - 動作確認環境: WSL2 Ubuntu(他のLinux/macOSでも動作するはず)
75
+
76
+ ### セットアップ
77
+
78
+ ```bash
79
+ git clone https://github.com/yuuka-dev/task-recorder-cui.git
80
+ cd task-recorder-cui
81
+ pip install -e ".[dev]"
82
+ ```
83
+
84
+ インストール後、`tsk` コマンドが使えるようになります。データは `~/.local/share/tsk/records.db` に保存されます。
85
+
86
+ ### テスト / カバレッジ
87
+
88
+ ```bash
89
+ pytest # 全テスト実行
90
+ pytest --cov=task_recorder_cui --cov-report=term # カバレッジ付きで実行
91
+ ```
92
+
93
+ dev 依存関係を更新した場合は `pip install -e ".[dev]"` を再実行してください。
94
+
95
+ ## 基本的な使い方
96
+
97
+ ### 記録を開始する
98
+
99
+ ```bash
100
+ tsk start dev "ObatLog Firestore 実装"
101
+ ```
102
+
103
+ ### 記録を停止する
104
+
105
+ ```bash
106
+ tsk stop
107
+ ```
108
+
109
+ ### 今日の記録を確認する
110
+
111
+ ```bash
112
+ tsk today
113
+ ```
114
+
115
+ 出力例:
116
+
117
+ ```
118
+ 2026-04-14 (Tue)
119
+ 14:00-15:30 [ゲーム] HOI4 日本プレイ 1h30m
120
+ 15:45-17:00 [開発] task-recorder-cui実装 1h15m
121
+ 17:30-18:15 [学習] ABC B問題 45m
122
+ 19:00- [開発] ObatLog Firestore (記録中 32m)
123
+ 合計: 4h02m (記録中含む)
124
+ ゲーム: 1h30m (37%)
125
+ 開発: 1h47m (44%)
126
+ 学習: 45m (19%)
127
+ ```
128
+
129
+ ### 事後に手動で追加する
130
+
131
+ ```bash
132
+ tsk add study 45 "ABC B問題"
133
+ ```
134
+
135
+ ### 週次・月次サマリを見る
136
+
137
+ ```bash
138
+ tsk week # 直近7日
139
+ tsk month # 直近30日
140
+ ```
141
+
142
+ ### インタラクティブメニュー
143
+
144
+ サブコマンドなしで起動すると、階層メニューから操作できます。
145
+
146
+ ```bash
147
+ tsk
148
+ ```
149
+
150
+ ```
151
+ ┌─────────────────────────────────────┐
152
+ │ tsk - task recorder │
153
+ ├─────────────────────────────────────┤
154
+ │ 現在: [開発] ObatLog実装 (32m経過) │
155
+ ├─────────────────────────────────────┤
156
+ │ ? 操作を選んでください │
157
+ │ 開始 │
158
+ │ 停止 │
159
+ │ 今日の一覧 │
160
+ │ 週集計 │
161
+ │ 月集計 │
162
+ │ カテゴリ管理 │
163
+ │ ヘルプ (CLI コマンド一覧) │
164
+ │ 終了 │
165
+ └─────────────────────────────────────┘
166
+ ```
167
+
168
+ 矢印キー + Enter で選択します。Ctrl+C / ESC でいつでも安全に中断できます (記録中のセッションは保持されます)。
169
+
170
+ ## CLIサブコマンド一覧
171
+
172
+ ### 記録系
173
+
174
+ | コマンド | 説明 |
175
+ |---|---|
176
+ | `tsk start <category_key> ["<description>"]` | 新しいセッションを開始 |
177
+ | `tsk stop` | 記録中のセッションを終了 |
178
+ | `tsk add <category_key> <minutes> ["<description>"]` | 事後に手動で追加 |
179
+ | `tsk now` | 現在記録中のセッションと経過時間を表示 |
180
+
181
+ ### 参照系
182
+
183
+ | コマンド | 説明 |
184
+ |---|---|
185
+ | `tsk today` | 今日の記録一覧+カテゴリ別合計 |
186
+ | `tsk week` | 直近7日の日別内訳+週合計+平均 |
187
+ | `tsk month` | 直近30日の同様の集計 |
188
+
189
+ ### カテゴリ管理
190
+
191
+ | コマンド | 説明 |
192
+ |---|---|
193
+ | `tsk cat list` | カテゴリ一覧 |
194
+ | `tsk cat add <key> "<display_name>"` | カテゴリを追加 |
195
+ | `tsk cat remove <key>` | カテゴリをアーカイブ(物理削除はしない) |
196
+ | `tsk cat restore <key>` | アーカイブから復帰 |
197
+ | `tsk cat rename <key> "<new_display_name>"` | 表示名を変更 |
198
+
199
+ > `key` は ASCII 英小文字・数字・アンダースコアのみ。過去レコードの履歴を壊さないため、削除ではなく **アーカイブ** で運用します。
200
+
201
+ ## スコープ外(やらないこと)
202
+
203
+ タスク管理、クラウド同期、通知、グラフ描画、ポモドーロ、タグ、優先度機能は意図的に実装しません。時間を記録することだけに集中します。
204
+
205
+ ## ライセンス
206
+
207
+ [MIT License](./LICENSE)
@@ -0,0 +1,175 @@
1
+ # task-recorder-cui
2
+
3
+ [![CI](https://github.com/yuuka-dev/task-recorder-cui/actions/workflows/ci.yml/badge.svg)](https://github.com/yuuka-dev/task-recorder-cui/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/yuuka-dev/task-recorder-cui/branch/main/graph/badge.svg)](https://codecov.io/gh/yuuka-dev/task-recorder-cui)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://www.python.org/)
7
+
8
+ > **一言で説明**: 日々の時間の使い方を記録し、週平均・月平均で可視化するCUIツール。タスク管理ではなく「時間記録」に特化しています。
9
+
10
+ ## 概要
11
+
12
+ ### なぜ作ったのか
13
+
14
+ Toggl などのタイムトラッキングツールは多機能ですが、項目が多すぎて続かないことがあります。本ツールは「何を・何時間・いつやったか」を **極限まで削ぎ落としたコマンド** で記録し、週平均・月平均を数字だけで見ることに特化しています。
15
+
16
+ 毎日使うのが苦にならない軽さを最優先に設計しました。
17
+
18
+ ## 主な機能
19
+
20
+ - `tsk start` / `tsk stop` で時間を記録(ストップウォッチ形式)
21
+ - `tsk add` で事後に手動追加
22
+ - `tsk today` / `tsk week` / `tsk month` で集計を表示
23
+ - カテゴリは自由に追加・アーカイブ可能(初期は `game` / `study` / `dev` の3つ)
24
+ - サブコマンドなしで起動すると階層型インタラクティブメニュー
25
+
26
+ ## 技術スタック
27
+
28
+ | カテゴリ | 技術 |
29
+ |---|---|
30
+ | 言語 | Python 3.11+ |
31
+ | データストア | SQLite(標準ライブラリ `sqlite3`) |
32
+ | CLI | `argparse` |
33
+ | 出力整形 | `rich` |
34
+ | インタラクティブ選択 | `questionary` |
35
+ | パッケージ管理 | `pyproject.toml` + `pip install -e .` |
36
+
37
+ ## はじめ方
38
+
39
+ ### 前提条件
40
+
41
+ - Python 3.11 以上
42
+ - 動作確認環境: WSL2 Ubuntu(他のLinux/macOSでも動作するはず)
43
+
44
+ ### セットアップ
45
+
46
+ ```bash
47
+ git clone https://github.com/yuuka-dev/task-recorder-cui.git
48
+ cd task-recorder-cui
49
+ pip install -e ".[dev]"
50
+ ```
51
+
52
+ インストール後、`tsk` コマンドが使えるようになります。データは `~/.local/share/tsk/records.db` に保存されます。
53
+
54
+ ### テスト / カバレッジ
55
+
56
+ ```bash
57
+ pytest # 全テスト実行
58
+ pytest --cov=task_recorder_cui --cov-report=term # カバレッジ付きで実行
59
+ ```
60
+
61
+ dev 依存関係を更新した場合は `pip install -e ".[dev]"` を再実行してください。
62
+
63
+ ## 基本的な使い方
64
+
65
+ ### 記録を開始する
66
+
67
+ ```bash
68
+ tsk start dev "ObatLog Firestore 実装"
69
+ ```
70
+
71
+ ### 記録を停止する
72
+
73
+ ```bash
74
+ tsk stop
75
+ ```
76
+
77
+ ### 今日の記録を確認する
78
+
79
+ ```bash
80
+ tsk today
81
+ ```
82
+
83
+ 出力例:
84
+
85
+ ```
86
+ 2026-04-14 (Tue)
87
+ 14:00-15:30 [ゲーム] HOI4 日本プレイ 1h30m
88
+ 15:45-17:00 [開発] task-recorder-cui実装 1h15m
89
+ 17:30-18:15 [学習] ABC B問題 45m
90
+ 19:00- [開発] ObatLog Firestore (記録中 32m)
91
+ 合計: 4h02m (記録中含む)
92
+ ゲーム: 1h30m (37%)
93
+ 開発: 1h47m (44%)
94
+ 学習: 45m (19%)
95
+ ```
96
+
97
+ ### 事後に手動で追加する
98
+
99
+ ```bash
100
+ tsk add study 45 "ABC B問題"
101
+ ```
102
+
103
+ ### 週次・月次サマリを見る
104
+
105
+ ```bash
106
+ tsk week # 直近7日
107
+ tsk month # 直近30日
108
+ ```
109
+
110
+ ### インタラクティブメニュー
111
+
112
+ サブコマンドなしで起動すると、階層メニューから操作できます。
113
+
114
+ ```bash
115
+ tsk
116
+ ```
117
+
118
+ ```
119
+ ┌─────────────────────────────────────┐
120
+ │ tsk - task recorder │
121
+ ├─────────────────────────────────────┤
122
+ │ 現在: [開発] ObatLog実装 (32m経過) │
123
+ ├─────────────────────────────────────┤
124
+ │ ? 操作を選んでください │
125
+ │ 開始 │
126
+ │ 停止 │
127
+ │ 今日の一覧 │
128
+ │ 週集計 │
129
+ │ 月集計 │
130
+ │ カテゴリ管理 │
131
+ │ ヘルプ (CLI コマンド一覧) │
132
+ │ 終了 │
133
+ └─────────────────────────────────────┘
134
+ ```
135
+
136
+ 矢印キー + Enter で選択します。Ctrl+C / ESC でいつでも安全に中断できます (記録中のセッションは保持されます)。
137
+
138
+ ## CLIサブコマンド一覧
139
+
140
+ ### 記録系
141
+
142
+ | コマンド | 説明 |
143
+ |---|---|
144
+ | `tsk start <category_key> ["<description>"]` | 新しいセッションを開始 |
145
+ | `tsk stop` | 記録中のセッションを終了 |
146
+ | `tsk add <category_key> <minutes> ["<description>"]` | 事後に手動で追加 |
147
+ | `tsk now` | 現在記録中のセッションと経過時間を表示 |
148
+
149
+ ### 参照系
150
+
151
+ | コマンド | 説明 |
152
+ |---|---|
153
+ | `tsk today` | 今日の記録一覧+カテゴリ別合計 |
154
+ | `tsk week` | 直近7日の日別内訳+週合計+平均 |
155
+ | `tsk month` | 直近30日の同様の集計 |
156
+
157
+ ### カテゴリ管理
158
+
159
+ | コマンド | 説明 |
160
+ |---|---|
161
+ | `tsk cat list` | カテゴリ一覧 |
162
+ | `tsk cat add <key> "<display_name>"` | カテゴリを追加 |
163
+ | `tsk cat remove <key>` | カテゴリをアーカイブ(物理削除はしない) |
164
+ | `tsk cat restore <key>` | アーカイブから復帰 |
165
+ | `tsk cat rename <key> "<new_display_name>"` | 表示名を変更 |
166
+
167
+ > `key` は ASCII 英小文字・数字・アンダースコアのみ。過去レコードの履歴を壊さないため、削除ではなく **アーカイブ** で運用します。
168
+
169
+ ## スコープ外(やらないこと)
170
+
171
+ タスク管理、クラウド同期、通知、グラフ描画、ポモドーロ、タグ、優先度機能は意図的に実装しません。時間を記録することだけに集中します。
172
+
173
+ ## ライセンス
174
+
175
+ [MIT License](./LICENSE)
@@ -0,0 +1,100 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "task-recorder-cui"
7
+ version = "1.0.0"
8
+ description = "Minimal, no-friction CUI time tracker with weekly and monthly summaries"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Yumeno Yuuka" },
14
+ ]
15
+ keywords = ["time-tracking", "cli", "productivity", "sqlite"]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Environment :: Console",
19
+ "Intended Audience :: End Users/Desktop",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Office/Business :: Scheduling",
25
+ "Topic :: Utilities",
26
+ ]
27
+ dependencies = [
28
+ "rich",
29
+ "questionary",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "ruff",
35
+ "pytest",
36
+ "pytest-cov",
37
+ "jupyterlab",
38
+ "pandas",
39
+ ]
40
+
41
+ [project.urls]
42
+ Homepage = "https://github.com/yuuka-dev/task-recorder-cui"
43
+ Repository = "https://github.com/yuuka-dev/task-recorder-cui"
44
+ Issues = "https://github.com/yuuka-dev/task-recorder-cui/issues"
45
+
46
+ [project.scripts]
47
+ tsk = "task_recorder_cui.cli:main"
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+
52
+ [tool.ruff]
53
+ line-length = 100
54
+ target-version = "py311"
55
+ indent-width = 4
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "W", "I", "N", "UP", "B", "C4", "SIM", "D"]
59
+ ignore = [
60
+ "D100", # Missing docstring in public module
61
+ "D101", # Missing docstring in public class
62
+ "D203", # 1 blank line required before class docstring (D211と競合)
63
+ "D213", # Multi-line docstring summary should start at the second line (D212と競合)
64
+ # 日本語docstring方針との相性が悪いルール群
65
+ "D400", # First line should end with a period (日本語の "。" は対象外)
66
+ "D401", # First line should be in imperative mood (英語前提)
67
+ "D403", # First word of first line should be properly capitalized (英語前提)
68
+ "D415", # First line should end with ., ?, ! (日本語の "。" は対象外)
69
+ ]
70
+ fixable = ["ALL"]
71
+
72
+ [tool.ruff.lint.per-file-ignores]
73
+ # テスト関数名は日本語を許容し、名前自体が自己説明的なのでdocstring強制しない
74
+ "tests/**.py" = ["N802", "D102", "D103"]
75
+ # 空の __init__.py は単なるパッケージマーカー
76
+ "**/__init__.py" = ["D104"]
77
+
78
+ [tool.ruff.lint.isort]
79
+ section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
80
+ known-first-party = ["task_recorder_cui"]
81
+
82
+ [tool.ruff.format]
83
+ quote-style = "double"
84
+ indent-style = "space"
85
+ skip-magic-trailing-comma = false
86
+
87
+ [tool.pytest.ini_options]
88
+ testpaths = ["tests"]
89
+ addopts = "-ra -q"
90
+
91
+ [tool.coverage.run]
92
+ source = ["task_recorder_cui"]
93
+ branch = true
94
+
95
+ [tool.coverage.report]
96
+ exclude_lines = [
97
+ "pragma: no cover",
98
+ "if __name__ == .__main__.:",
99
+ "raise NotImplementedError",
100
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """task-recorder-cui: 時間記録のためのCUIツール。"""
2
+
3
+ __version__ = "1.0.0"
@@ -0,0 +1,5 @@
1
+ """`python -m task_recorder_cui` 用エントリ。"""
2
+
3
+ from task_recorder_cui.cli import main
4
+
5
+ raise SystemExit(main())
@@ -0,0 +1,162 @@
1
+ """argparse ベースの CLI エントリポイント。
2
+
3
+ 本モジュールはサブコマンドの受け口 (parser) と main ディスパッチャを持つ。
4
+ 記録系 (start/stop/now/add)、参照系 (today/week/month/range/all)、カテゴリ管理
5
+ (cat ...) は commands/ 配下の実装に dispatch する。インタラクティブメニューは
6
+ `menu.run()` に dispatch する。
7
+ """
8
+
9
+ import argparse
10
+
11
+ from task_recorder_cui import __version__
12
+ from task_recorder_cui.commands import add as add_cmd
13
+ from task_recorder_cui.commands import all as all_cmd
14
+ from task_recorder_cui.commands import cat as cat_cmd
15
+ from task_recorder_cui.commands import month as month_cmd
16
+ from task_recorder_cui.commands import now as now_cmd
17
+ from task_recorder_cui.commands import range as range_cmd
18
+ from task_recorder_cui.commands import start as start_cmd
19
+ from task_recorder_cui.commands import stop as stop_cmd
20
+ from task_recorder_cui.commands import today as today_cmd
21
+ from task_recorder_cui.commands import week as week_cmd
22
+
23
+
24
+ def build_parser() -> argparse.ArgumentParser:
25
+ """tsk の引数パーサを構築する。
26
+
27
+ Returns:
28
+ サブコマンドを含む設定済み ArgumentParser。
29
+
30
+ """
31
+ parser = argparse.ArgumentParser(
32
+ prog="tsk",
33
+ description="日々の時間の使い方を記録して、週平均・月平均で可視化するCUIツール",
34
+ )
35
+ parser.add_argument(
36
+ "--version",
37
+ action="version",
38
+ version=f"tsk {__version__}",
39
+ )
40
+
41
+ sub = parser.add_subparsers(dest="command", metavar="<command>")
42
+
43
+ # --- 記録系 ---
44
+ p_start = sub.add_parser("start", help="新しいセッションを開始")
45
+ p_start.add_argument("category_key", help="カテゴリキー (例: game, study, dev)")
46
+ p_start.add_argument("description", nargs="?", default=None, help="活動内容 (任意)")
47
+
48
+ sub.add_parser("stop", help="記録中のセッションを終了")
49
+
50
+ p_add = sub.add_parser("add", help="事後に手動で追加")
51
+ p_add.add_argument("category_key", help="カテゴリキー")
52
+ p_add.add_argument("minutes", type=int, help="記録する分数")
53
+ p_add.add_argument("description", nargs="?", default=None, help="活動内容 (任意)")
54
+
55
+ sub.add_parser("now", help="記録中のセッションを表示")
56
+
57
+ # --- 参照系 ---
58
+ sub.add_parser("today", help="今日の記録一覧")
59
+ p_week = sub.add_parser("week", help="直近7日 (default) または今週 (--calendar)")
60
+ p_week.add_argument(
61
+ "--calendar",
62
+ action="store_true",
63
+ help="月曜〜今日の今週集計にする",
64
+ )
65
+ p_month = sub.add_parser("month", help="直近30日 (default) または今月 (--calendar)")
66
+ p_month.add_argument(
67
+ "--calendar",
68
+ action="store_true",
69
+ help="今月1日〜今日の集計にする",
70
+ )
71
+ p_range = sub.add_parser("range", help="任意期間の集計")
72
+ p_range.add_argument("--from", dest="from_date", required=True, help="開始日 YYYY-MM-DD")
73
+ p_range.add_argument(
74
+ "--to", dest="to_date", required=True, help="終了日 YYYY-MM-DD (inclusive)"
75
+ )
76
+ sub.add_parser("all", help="全累計")
77
+
78
+ # --- カテゴリ管理 ---
79
+ p_cat = sub.add_parser("cat", help="カテゴリ管理")
80
+ cat_sub = p_cat.add_subparsers(dest="cat_action", metavar="<action>", required=True)
81
+
82
+ p_cat_list = cat_sub.add_parser("list", help="カテゴリ一覧")
83
+ list_filter = p_cat_list.add_mutually_exclusive_group()
84
+ list_filter.add_argument(
85
+ "--active", action="store_true", help="archived でないカテゴリだけ表示"
86
+ )
87
+ list_filter.add_argument("--archived", action="store_true", help="archived のカテゴリだけ表示")
88
+
89
+ p_cat_add = cat_sub.add_parser(
90
+ "add", help="カテゴリを追加 (archived同名があれば復帰+表示名上書き)"
91
+ )
92
+ p_cat_add.add_argument("key", help="新しいカテゴリキー")
93
+ p_cat_add.add_argument("display_name", help="表示名")
94
+ p_cat_remove = cat_sub.add_parser("remove", help="カテゴリをアーカイブ")
95
+ p_cat_remove.add_argument("key", help="アーカイブするカテゴリキー")
96
+ p_cat_restore = cat_sub.add_parser("restore", help="アーカイブから復帰")
97
+ p_cat_restore.add_argument("key", help="復帰させるカテゴリキー")
98
+ p_cat_rename = cat_sub.add_parser("rename", help="表示名を変更")
99
+ p_cat_rename.add_argument("key", help="変更するカテゴリキー")
100
+ p_cat_rename.add_argument("new_display_name", help="新しい表示名")
101
+
102
+ return parser
103
+
104
+
105
+ def main(argv: list[str] | None = None) -> int:
106
+ """CLI エントリポイント。
107
+
108
+ Args:
109
+ argv: 引数リスト。Noneの場合は sys.argv[1:] が使われる。
110
+
111
+ Returns:
112
+ 終了コード (0: 成功)。
113
+
114
+ Raises:
115
+ SystemExit: --help / --version 表示時、または usage error 時に
116
+ argparse が送出する。正常終了は code=0、usage error は code=2。
117
+
118
+ """
119
+ parser = build_parser()
120
+ args = parser.parse_args(argv)
121
+
122
+ if args.command is None:
123
+ from task_recorder_cui.menu import run as menu_run
124
+
125
+ return menu_run()
126
+
127
+ # --- 記録系 (Phase 3) ---
128
+ if args.command == "start":
129
+ return start_cmd.run(args.category_key, args.description)
130
+ if args.command == "stop":
131
+ return stop_cmd.run()
132
+ if args.command == "now":
133
+ return now_cmd.run()
134
+ if args.command == "add":
135
+ return add_cmd.run(args.category_key, args.minutes, args.description)
136
+
137
+ # --- 参照系 (Phase 4) ---
138
+ if args.command == "today":
139
+ return today_cmd.run()
140
+ if args.command == "week":
141
+ return week_cmd.run(calendar=args.calendar)
142
+ if args.command == "month":
143
+ return month_cmd.run(calendar=args.calendar)
144
+ if args.command == "range":
145
+ return range_cmd.run(args.from_date, args.to_date)
146
+ if args.command == "all":
147
+ return all_cmd.run()
148
+
149
+ # --- カテゴリ管理 (Phase 5) ---
150
+ if args.command == "cat":
151
+ if args.cat_action == "list":
152
+ return cat_cmd.list_categories(active_only=args.active, archived_only=args.archived)
153
+ if args.cat_action == "add":
154
+ return cat_cmd.add_category(args.key, args.display_name)
155
+ if args.cat_action == "remove":
156
+ return cat_cmd.remove_category(args.key)
157
+ if args.cat_action == "restore":
158
+ return cat_cmd.restore_category(args.key)
159
+ if args.cat_action == "rename":
160
+ return cat_cmd.rename_category(args.key, args.new_display_name)
161
+
162
+ return 0