student-task-manager-cli 0.1.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 (27) hide show
  1. student_task_manager_cli-0.1.0/PKG-INFO +134 -0
  2. student_task_manager_cli-0.1.0/README.md +127 -0
  3. student_task_manager_cli-0.1.0/pyproject.toml +20 -0
  4. student_task_manager_cli-0.1.0/setup.cfg +4 -0
  5. student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/PKG-INFO +134 -0
  6. student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/SOURCES.txt +25 -0
  7. student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/dependency_links.txt +1 -0
  8. student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/entry_points.txt +2 -0
  9. student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/top_level.txt +1 -0
  10. student_task_manager_cli-0.1.0/src/task_manager/__init__.py +1 -0
  11. student_task_manager_cli-0.1.0/src/task_manager/__main__.py +5 -0
  12. student_task_manager_cli-0.1.0/src/task_manager/arguments.py +52 -0
  13. student_task_manager_cli-0.1.0/src/task_manager/cli.py +22 -0
  14. student_task_manager_cli-0.1.0/src/task_manager/commands.py +75 -0
  15. student_task_manager_cli-0.1.0/src/task_manager/demo.py +69 -0
  16. student_task_manager_cli-0.1.0/src/task_manager/input.py +36 -0
  17. student_task_manager_cli-0.1.0/src/task_manager/interactive.py +97 -0
  18. student_task_manager_cli-0.1.0/src/task_manager/productivity.py +37 -0
  19. student_task_manager_cli-0.1.0/src/task_manager/storage.py +78 -0
  20. student_task_manager_cli-0.1.0/src/task_manager/ui/__init__.py +0 -0
  21. student_task_manager_cli-0.1.0/src/task_manager/ui/animation.py +26 -0
  22. student_task_manager_cli-0.1.0/src/task_manager/ui/theme.py +57 -0
  23. student_task_manager_cli-0.1.0/src/task_manager/ui/views.py +123 -0
  24. student_task_manager_cli-0.1.0/tests/test_demo.py +43 -0
  25. student_task_manager_cli-0.1.0/tests/test_interactive.py +84 -0
  26. student_task_manager_cli-0.1.0/tests/test_productivity.py +36 -0
  27. student_task_manager_cli-0.1.0/tests/test_tasks.py +130 -0
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: student-task-manager-cli
3
+ Version: 0.1.0
4
+ Summary: A simple command-line task manager
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+
8
+ ## Install
9
+
10
+ From the project directory, on macOS or Linux:
11
+
12
+ ```bash
13
+ python3 -m venv .venv
14
+ source .venv/bin/activate
15
+ python -m pip install -e .
16
+ ```
17
+
18
+ On Windows PowerShell:
19
+
20
+ ```powershell
21
+ py -m venv .venv
22
+ .venv\Scripts\Activate.ps1
23
+ python -m pip install -e .
24
+ ```
25
+
26
+ After activation, run `task` to open the interactive terminal view.
27
+ Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
28
+ `list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
29
+ Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
30
+ `clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
31
+
32
+ Tab completes commands and the arrow keys recall history on terminals with readline.
33
+ The welcome screen shows your next task and a small activity chart.
34
+
35
+ You can also run single commands directly, such as:
36
+ `task add "Write report"` or `task --help`.
37
+
38
+ To leave the environment, run `deactivate`.
39
+
40
+ ## Commands
41
+
42
+ | Command | Purpose |
43
+ | --- | --- |
44
+ | `task add "Write report"` | Add a task |
45
+ | `task list` or `task ls` | List To do tasks |
46
+ | `task list --done` | List completed tasks |
47
+ | `task list --undone` | List To do tasks |
48
+ | `task list --all` | List every task |
49
+ | `task done 1` | Complete task 1 |
50
+ | `task undone 1` | Make task 1 pending |
51
+ | `task delete 1` | Delete task 1 |
52
+ | `task update 1 "New title"` | Change task 1's title |
53
+ | `task show 1` | Show task 1's details |
54
+ | `task clear` | Delete completed tasks |
55
+ | `task stats` | Show progress and a 7-day completion chart |
56
+ | `task demo` | Try 26 sample tasks in a temporary workspace |
57
+ | `task help` | Show all commands |
58
+
59
+ Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
60
+
61
+ ## Try it with sample data
62
+
63
+ ```bash
64
+ task demo
65
+ ```
66
+
67
+ Or run `python test_task.py` from the project directory. Both open a separate
68
+ session with 8 pending and 18 completed tasks spread across the last week.
69
+ Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
70
+ Demo changes are discarded; your own tasks stay untouched.
71
+ `task demo --preview` prints the sample list and chart without opening a prompt.
72
+
73
+ ## Progress
74
+
75
+ `stats` shows task counts, completion percentage, and a daily chart:
76
+
77
+ ```text
78
+ Progress ━━━━━━━━━━━━━━────── 69%
79
+
80
+ This week · completed tasks
81
+
82
+ Tue 06 ━━━━ 1
83
+ Wed 07 ━━━━━━━━━━━━ 3
84
+ Thu 08 ━━━━━━━━ 2
85
+ Fri 09 ━━━━━━━━━━━━━━━━ 4
86
+ Sat 10 ━━━━ 1
87
+ Sun 11 ━━━━━━━━━━━━ 3
88
+ Mon 12 ━━━━━━━━━━━━━━━━ 4
89
+ ```
90
+
91
+ Dates follow your local timezone. `done` records the completion time; `undone`
92
+ removes it. The chart counts tasks still in the file, so deleting completed tasks
93
+ also removes them from the chart. Older tasks without a completion date still
94
+ count toward the total, but not the daily chart.
95
+
96
+ ## Project structure
97
+
98
+ ```text
99
+ src/task_manager/
100
+ cli.py Entry point: one command or interactive mode
101
+ arguments.py Command names, flags, and ls alias
102
+ commands.py Add, edit, complete, delete, list
103
+ storage.py JSON file, validation, task IDs
104
+ productivity.py Weekly counts and progress
105
+ input.py Parse commands typed at the prompt
106
+ interactive.py Input loop and command history
107
+ demo.py Sample tasks and temporary workspace
108
+ ui/
109
+ theme.py Colors and terminal sizing
110
+ animation.py Startup and result transitions
111
+ views.py Welcome screen, help, and task list
112
+ tests/ CLI, interactive, demo, and productivity tests
113
+ test_task.py Start the demo from the project directory
114
+ ```
115
+
116
+ A command goes through `cli → arguments → commands → storage`.
117
+ Interactive mode adds `input` and `ui`; both modes use the same commands.
118
+ No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
119
+ or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
120
+
121
+ ## Where tasks are stored
122
+
123
+ The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
124
+
125
+ ## Run tests
126
+
127
+ With the virtual environment active, install pytest separately for development:
128
+
129
+ ```bash
130
+ python -m pip install pytest
131
+ python -m pytest
132
+ ```
133
+
134
+ Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
@@ -0,0 +1,127 @@
1
+ ## Install
2
+
3
+ From the project directory, on macOS or Linux:
4
+
5
+ ```bash
6
+ python3 -m venv .venv
7
+ source .venv/bin/activate
8
+ python -m pip install -e .
9
+ ```
10
+
11
+ On Windows PowerShell:
12
+
13
+ ```powershell
14
+ py -m venv .venv
15
+ .venv\Scripts\Activate.ps1
16
+ python -m pip install -e .
17
+ ```
18
+
19
+ After activation, run `task` to open the interactive terminal view.
20
+ Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
21
+ `list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
22
+ Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
23
+ `clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
24
+
25
+ Tab completes commands and the arrow keys recall history on terminals with readline.
26
+ The welcome screen shows your next task and a small activity chart.
27
+
28
+ You can also run single commands directly, such as:
29
+ `task add "Write report"` or `task --help`.
30
+
31
+ To leave the environment, run `deactivate`.
32
+
33
+ ## Commands
34
+
35
+ | Command | Purpose |
36
+ | --- | --- |
37
+ | `task add "Write report"` | Add a task |
38
+ | `task list` or `task ls` | List To do tasks |
39
+ | `task list --done` | List completed tasks |
40
+ | `task list --undone` | List To do tasks |
41
+ | `task list --all` | List every task |
42
+ | `task done 1` | Complete task 1 |
43
+ | `task undone 1` | Make task 1 pending |
44
+ | `task delete 1` | Delete task 1 |
45
+ | `task update 1 "New title"` | Change task 1's title |
46
+ | `task show 1` | Show task 1's details |
47
+ | `task clear` | Delete completed tasks |
48
+ | `task stats` | Show progress and a 7-day completion chart |
49
+ | `task demo` | Try 26 sample tasks in a temporary workspace |
50
+ | `task help` | Show all commands |
51
+
52
+ Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
53
+
54
+ ## Try it with sample data
55
+
56
+ ```bash
57
+ task demo
58
+ ```
59
+
60
+ Or run `python test_task.py` from the project directory. Both open a separate
61
+ session with 8 pending and 18 completed tasks spread across the last week.
62
+ Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
63
+ Demo changes are discarded; your own tasks stay untouched.
64
+ `task demo --preview` prints the sample list and chart without opening a prompt.
65
+
66
+ ## Progress
67
+
68
+ `stats` shows task counts, completion percentage, and a daily chart:
69
+
70
+ ```text
71
+ Progress ━━━━━━━━━━━━━━────── 69%
72
+
73
+ This week · completed tasks
74
+
75
+ Tue 06 ━━━━ 1
76
+ Wed 07 ━━━━━━━━━━━━ 3
77
+ Thu 08 ━━━━━━━━ 2
78
+ Fri 09 ━━━━━━━━━━━━━━━━ 4
79
+ Sat 10 ━━━━ 1
80
+ Sun 11 ━━━━━━━━━━━━ 3
81
+ Mon 12 ━━━━━━━━━━━━━━━━ 4
82
+ ```
83
+
84
+ Dates follow your local timezone. `done` records the completion time; `undone`
85
+ removes it. The chart counts tasks still in the file, so deleting completed tasks
86
+ also removes them from the chart. Older tasks without a completion date still
87
+ count toward the total, but not the daily chart.
88
+
89
+ ## Project structure
90
+
91
+ ```text
92
+ src/task_manager/
93
+ cli.py Entry point: one command or interactive mode
94
+ arguments.py Command names, flags, and ls alias
95
+ commands.py Add, edit, complete, delete, list
96
+ storage.py JSON file, validation, task IDs
97
+ productivity.py Weekly counts and progress
98
+ input.py Parse commands typed at the prompt
99
+ interactive.py Input loop and command history
100
+ demo.py Sample tasks and temporary workspace
101
+ ui/
102
+ theme.py Colors and terminal sizing
103
+ animation.py Startup and result transitions
104
+ views.py Welcome screen, help, and task list
105
+ tests/ CLI, interactive, demo, and productivity tests
106
+ test_task.py Start the demo from the project directory
107
+ ```
108
+
109
+ A command goes through `cli → arguments → commands → storage`.
110
+ Interactive mode adds `input` and `ui`; both modes use the same commands.
111
+ No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
112
+ or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
113
+
114
+ ## Where tasks are stored
115
+
116
+ The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
117
+
118
+ ## Run tests
119
+
120
+ With the virtual environment active, install pytest separately for development:
121
+
122
+ ```bash
123
+ python -m pip install pytest
124
+ python -m pytest
125
+ ```
126
+
127
+ Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
@@ -0,0 +1,20 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "student-task-manager-cli"
7
+ version = "0.1.0"
8
+ description = "A simple command-line task manager"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = []
12
+
13
+ [project.scripts]
14
+ task = "task_manager.cli:main"
15
+
16
+ [tool.setuptools.packages.find]
17
+ where = ["src"]
18
+
19
+ [tool.pytest.ini_options]
20
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: student-task-manager-cli
3
+ Version: 0.1.0
4
+ Summary: A simple command-line task manager
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+
8
+ ## Install
9
+
10
+ From the project directory, on macOS or Linux:
11
+
12
+ ```bash
13
+ python3 -m venv .venv
14
+ source .venv/bin/activate
15
+ python -m pip install -e .
16
+ ```
17
+
18
+ On Windows PowerShell:
19
+
20
+ ```powershell
21
+ py -m venv .venv
22
+ .venv\Scripts\Activate.ps1
23
+ python -m pip install -e .
24
+ ```
25
+
26
+ After activation, run `task` to open the interactive terminal view.
27
+ Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
28
+ `list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
29
+ Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
30
+ `clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
31
+
32
+ Tab completes commands and the arrow keys recall history on terminals with readline.
33
+ The welcome screen shows your next task and a small activity chart.
34
+
35
+ You can also run single commands directly, such as:
36
+ `task add "Write report"` or `task --help`.
37
+
38
+ To leave the environment, run `deactivate`.
39
+
40
+ ## Commands
41
+
42
+ | Command | Purpose |
43
+ | --- | --- |
44
+ | `task add "Write report"` | Add a task |
45
+ | `task list` or `task ls` | List To do tasks |
46
+ | `task list --done` | List completed tasks |
47
+ | `task list --undone` | List To do tasks |
48
+ | `task list --all` | List every task |
49
+ | `task done 1` | Complete task 1 |
50
+ | `task undone 1` | Make task 1 pending |
51
+ | `task delete 1` | Delete task 1 |
52
+ | `task update 1 "New title"` | Change task 1's title |
53
+ | `task show 1` | Show task 1's details |
54
+ | `task clear` | Delete completed tasks |
55
+ | `task stats` | Show progress and a 7-day completion chart |
56
+ | `task demo` | Try 26 sample tasks in a temporary workspace |
57
+ | `task help` | Show all commands |
58
+
59
+ Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
60
+
61
+ ## Try it with sample data
62
+
63
+ ```bash
64
+ task demo
65
+ ```
66
+
67
+ Or run `python test_task.py` from the project directory. Both open a separate
68
+ session with 8 pending and 18 completed tasks spread across the last week.
69
+ Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
70
+ Demo changes are discarded; your own tasks stay untouched.
71
+ `task demo --preview` prints the sample list and chart without opening a prompt.
72
+
73
+ ## Progress
74
+
75
+ `stats` shows task counts, completion percentage, and a daily chart:
76
+
77
+ ```text
78
+ Progress ━━━━━━━━━━━━━━────── 69%
79
+
80
+ This week · completed tasks
81
+
82
+ Tue 06 ━━━━ 1
83
+ Wed 07 ━━━━━━━━━━━━ 3
84
+ Thu 08 ━━━━━━━━ 2
85
+ Fri 09 ━━━━━━━━━━━━━━━━ 4
86
+ Sat 10 ━━━━ 1
87
+ Sun 11 ━━━━━━━━━━━━ 3
88
+ Mon 12 ━━━━━━━━━━━━━━━━ 4
89
+ ```
90
+
91
+ Dates follow your local timezone. `done` records the completion time; `undone`
92
+ removes it. The chart counts tasks still in the file, so deleting completed tasks
93
+ also removes them from the chart. Older tasks without a completion date still
94
+ count toward the total, but not the daily chart.
95
+
96
+ ## Project structure
97
+
98
+ ```text
99
+ src/task_manager/
100
+ cli.py Entry point: one command or interactive mode
101
+ arguments.py Command names, flags, and ls alias
102
+ commands.py Add, edit, complete, delete, list
103
+ storage.py JSON file, validation, task IDs
104
+ productivity.py Weekly counts and progress
105
+ input.py Parse commands typed at the prompt
106
+ interactive.py Input loop and command history
107
+ demo.py Sample tasks and temporary workspace
108
+ ui/
109
+ theme.py Colors and terminal sizing
110
+ animation.py Startup and result transitions
111
+ views.py Welcome screen, help, and task list
112
+ tests/ CLI, interactive, demo, and productivity tests
113
+ test_task.py Start the demo from the project directory
114
+ ```
115
+
116
+ A command goes through `cli → arguments → commands → storage`.
117
+ Interactive mode adds `input` and `ui`; both modes use the same commands.
118
+ No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
119
+ or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
120
+
121
+ ## Where tasks are stored
122
+
123
+ The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
124
+
125
+ ## Run tests
126
+
127
+ With the virtual environment active, install pytest separately for development:
128
+
129
+ ```bash
130
+ python -m pip install pytest
131
+ python -m pytest
132
+ ```
133
+
134
+ Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
@@ -0,0 +1,25 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/student_task_manager_cli.egg-info/PKG-INFO
4
+ src/student_task_manager_cli.egg-info/SOURCES.txt
5
+ src/student_task_manager_cli.egg-info/dependency_links.txt
6
+ src/student_task_manager_cli.egg-info/entry_points.txt
7
+ src/student_task_manager_cli.egg-info/top_level.txt
8
+ src/task_manager/__init__.py
9
+ src/task_manager/__main__.py
10
+ src/task_manager/arguments.py
11
+ src/task_manager/cli.py
12
+ src/task_manager/commands.py
13
+ src/task_manager/demo.py
14
+ src/task_manager/input.py
15
+ src/task_manager/interactive.py
16
+ src/task_manager/productivity.py
17
+ src/task_manager/storage.py
18
+ src/task_manager/ui/__init__.py
19
+ src/task_manager/ui/animation.py
20
+ src/task_manager/ui/theme.py
21
+ src/task_manager/ui/views.py
22
+ tests/test_demo.py
23
+ tests/test_interactive.py
24
+ tests/test_productivity.py
25
+ tests/test_tasks.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ task = task_manager.cli:main
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ raise SystemExit(main())
@@ -0,0 +1,52 @@
1
+ import argparse
2
+
3
+ from . import __version__
4
+
5
+
6
+ def positive_id(value: str) -> int:
7
+ try:
8
+ task_id = int(value)
9
+ except ValueError as error:
10
+ raise argparse.ArgumentTypeError("task ID must be a positive number") from error
11
+ if task_id < 1:
12
+ raise argparse.ArgumentTypeError("task ID must be a positive number")
13
+ return task_id
14
+
15
+
16
+ def parser_for_cli() -> argparse.ArgumentParser:
17
+ parser = argparse.ArgumentParser(prog="task", description="Manage your tasks.")
18
+ parser.add_argument("--version", action="version", version=f"task {__version__}")
19
+ commands = parser.add_subparsers(dest="command", required=True)
20
+ descriptions = {
21
+ "add": "Add a new task",
22
+ "list": "List pending tasks (or filter by status)",
23
+ "done": "Mark a task as completed",
24
+ "undone": "Mark a task as pending",
25
+ "delete": "Delete a task",
26
+ "update": "Change a task title",
27
+ "show": "Show task details",
28
+ "clear": "Delete completed tasks",
29
+ "stats": "Show weekly productivity",
30
+ "demo": "Open a session with sample tasks",
31
+ "help": "Show all commands",
32
+ }
33
+ for name, description in descriptions.items():
34
+ command = commands.add_parser(
35
+ name, aliases=["ls"] if name == "list" else [],
36
+ help=description, description=description,
37
+ )
38
+ command.set_defaults(command=name)
39
+ if name in ("done", "undone", "delete", "update", "show"):
40
+ command.add_argument("id", type=positive_id, help="positive task ID")
41
+ if name in ("add", "update"):
42
+ command.add_argument("title", help="task title")
43
+ if name == "demo":
44
+ command.add_argument("--preview", action="store_true", help="print the demo and exit")
45
+ if name == "list":
46
+ filters = command.add_mutually_exclusive_group()
47
+ filters.add_argument("--done", action="store_true", help="show completed tasks")
48
+ filters.add_argument("--undone", action="store_true", help="show pending tasks")
49
+ filters.add_argument("--all", action="store_true", help="show every task")
50
+ return parser
51
+
52
+
@@ -0,0 +1,22 @@
1
+ import sys
2
+
3
+ from .arguments import parser_for_cli
4
+ from .commands import execute
5
+
6
+
7
+ def main(argv: list[str] | None = None) -> int:
8
+ argv = sys.argv[1:] if argv is None else argv
9
+ if not argv:
10
+ from .interactive import run_interactive
11
+
12
+ return run_interactive(main)
13
+ parser = parser_for_cli()
14
+ args = parser.parse_args(argv)
15
+ if args.command == "help":
16
+ parser.print_help()
17
+ return 0
18
+ if args.command == "demo":
19
+ from .demo import run_demo
20
+
21
+ return run_demo(preview=args.preview)
22
+ return execute(args)
@@ -0,0 +1,75 @@
1
+ import sys
2
+ from datetime import datetime, timezone
3
+
4
+ from .productivity import format_stats
5
+ from .storage import StorageError, load_data, save_data
6
+
7
+
8
+ def execute(args) -> int:
9
+ if args.command in ("add", "update"):
10
+ title = args.title.strip()
11
+ if not title:
12
+ print("Error: task title cannot be empty.", file=sys.stderr)
13
+ return 1
14
+
15
+ try:
16
+ data = load_data()
17
+ tasks = data["tasks"]
18
+
19
+ if args.command == "add":
20
+ task = {
21
+ "id": data["next_id"],
22
+ "title": title,
23
+ "status": "pending",
24
+ "created_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
25
+ }
26
+ tasks.append(task)
27
+ save_data(data)
28
+ print(f"Added task {task['id']}: {title}")
29
+ elif args.command == "list":
30
+ visible = [task for task in tasks if args.all or task["status"] == ("completed" if args.done else "pending")]
31
+ if not visible:
32
+ print("No tasks yet." if not tasks else "No completed tasks." if args.done else "No pending tasks.")
33
+ for task in visible:
34
+ print(f"{task['id']}. [{task['status']}] {task['title']}")
35
+ elif args.command == "stats":
36
+ print(format_stats(tasks))
37
+ elif args.command == "clear":
38
+ remaining = [task for task in tasks if task["status"] != "completed"]
39
+ removed = len(tasks) - len(remaining)
40
+ data["tasks"] = remaining
41
+ save_data(data)
42
+ print(f"Removed {removed} completed task(s).")
43
+ else:
44
+ task = next((task for task in tasks if task["id"] == args.id), None)
45
+ if task is None:
46
+ print(f"Error: task {args.id} not found.", file=sys.stderr)
47
+ return 1
48
+ if args.command == "show":
49
+ print(f"ID: {task['id']}\nTitle: {task['title']}\nStatus: {task['status']}\nCreated: {task['created_at']}")
50
+ if task.get("completed_at"):
51
+ print(f"Completed: {task['completed_at']}")
52
+ elif args.command == "delete":
53
+ tasks.remove(task)
54
+ save_data(data)
55
+ print(f"Deleted task {args.id}.")
56
+ else:
57
+ if args.command == "update":
58
+ task["title"] = title
59
+ else:
60
+ if args.command == "done" and task["status"] != "completed":
61
+ task["completed_at"] = datetime.now(timezone.utc).isoformat(timespec="seconds")
62
+ elif args.command == "undone":
63
+ task.pop("completed_at", None)
64
+ task["status"] = "completed" if args.command == "done" else "pending"
65
+ save_data(data)
66
+ if args.command == "done":
67
+ print(f"Completed: {task['title']}")
68
+ elif args.command == "undone":
69
+ print(f"Back to To do: {task['title']}")
70
+ else:
71
+ print(f"Renamed task {task['id']}: {task['title']}")
72
+ except StorageError as error:
73
+ print(f"Error: {error}", file=sys.stderr)
74
+ return 1
75
+ return 0