cupt 0.6.1__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 (44) hide show
  1. cupt-0.6.1/LICENSE +21 -0
  2. cupt-0.6.1/PKG-INFO +162 -0
  3. cupt-0.6.1/README.md +126 -0
  4. cupt-0.6.1/cupt/__init__.py +39 -0
  5. cupt-0.6.1/cupt/ai.py +82 -0
  6. cupt-0.6.1/cupt/api.py +290 -0
  7. cupt-0.6.1/cupt/attachments.py +145 -0
  8. cupt-0.6.1/cupt/auth.py +246 -0
  9. cupt-0.6.1/cupt/config.py +153 -0
  10. cupt-0.6.1/cupt/context.py +42 -0
  11. cupt-0.6.1/cupt/exceptions.py +17 -0
  12. cupt-0.6.1/cupt/main.py +255 -0
  13. cupt-0.6.1/cupt/notes.py +52 -0
  14. cupt-0.6.1/cupt/services/__init__.py +5 -0
  15. cupt-0.6.1/cupt/services/note_service.py +16 -0
  16. cupt-0.6.1/cupt/services/task_service.py +305 -0
  17. cupt-0.6.1/cupt/services/time_service.py +29 -0
  18. cupt-0.6.1/cupt/summary.py +181 -0
  19. cupt-0.6.1/cupt/tags.py +42 -0
  20. cupt-0.6.1/cupt/tasks.py +891 -0
  21. cupt-0.6.1/cupt/time_tracker.py +107 -0
  22. cupt-0.6.1/cupt/utils.py +162 -0
  23. cupt-0.6.1/cupt.egg-info/PKG-INFO +162 -0
  24. cupt-0.6.1/cupt.egg-info/SOURCES.txt +42 -0
  25. cupt-0.6.1/cupt.egg-info/dependency_links.txt +1 -0
  26. cupt-0.6.1/cupt.egg-info/entry_points.txt +2 -0
  27. cupt-0.6.1/cupt.egg-info/requires.txt +6 -0
  28. cupt-0.6.1/cupt.egg-info/top_level.txt +1 -0
  29. cupt-0.6.1/pyproject.toml +92 -0
  30. cupt-0.6.1/setup.cfg +4 -0
  31. cupt-0.6.1/tests/test_ai.py +134 -0
  32. cupt-0.6.1/tests/test_api.py +271 -0
  33. cupt-0.6.1/tests/test_attachments.py +169 -0
  34. cupt-0.6.1/tests/test_auth.py +148 -0
  35. cupt-0.6.1/tests/test_config.py +106 -0
  36. cupt-0.6.1/tests/test_context.py +54 -0
  37. cupt-0.6.1/tests/test_main.py +148 -0
  38. cupt-0.6.1/tests/test_notes.py +38 -0
  39. cupt-0.6.1/tests/test_summary.py +266 -0
  40. cupt-0.6.1/tests/test_tags.py +47 -0
  41. cupt-0.6.1/tests/test_task_service.py +198 -0
  42. cupt-0.6.1/tests/test_tasks.py +925 -0
  43. cupt-0.6.1/tests/test_time_tracker.py +134 -0
  44. cupt-0.6.1/tests/test_utils.py +73 -0
cupt-0.6.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Nuzum
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.
cupt-0.6.1/PKG-INFO ADDED
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: cupt
3
+ Version: 0.6.1
4
+ Summary: ClickUp Task Management CLI and Python library
5
+ Author-email: Matthew Nuzum <matthew@nuzum.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/newz2000/cupt
8
+ Project-URL: Repository, https://github.com/newz2000/cupt
9
+ Project-URL: Issues, https://github.com/newz2000/cupt/issues
10
+ Project-URL: Changelog, https://github.com/newz2000/cupt/blob/main/CHANGELOG.md
11
+ Keywords: clickup,cli,tasks,productivity,task-management
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Office/Business
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: click>=8.0.0
30
+ Requires-Dist: requests>=2.25.0
31
+ Requires-Dist: cryptography>=3.4.0
32
+ Requires-Dist: pyyaml>=5.4.0
33
+ Requires-Dist: colorama>=0.4.4
34
+ Requires-Dist: python-dotenv>=0.19.0
35
+ Dynamic: license-file
36
+
37
+ # CUPT - ClickUp Task Management CLI
38
+
39
+ CUPT stands for “ClickUP Terminal,” a command-line interface for accessing your tasks in ClickUp in the terminal or via your favorite AI-based tool.
40
+
41
+ ## Features
42
+ - **Task Listing**: View active, overdue, and upcoming tasks with deep paging support.
43
+ - **Subtask Support**: Visual nesting (`↳`) and parent task resolution.
44
+ - **Hierarchical Context**: `cupt context <id>` shows parents and sibling subtasks.
45
+ - **Time Tracking**: Start/stop timers and add manual time entries.
46
+ - **Note Management**: Quick comments and note listing.
47
+ - **Flexible Auth**: Supports both OAuth and Personal API Tokens.
48
+ - **Offline Support**: After `cupt list` runs, it transparently caches the full details (description, comments, parent) for every task it just displayed, so a later `cupt show <id> --offline` works without a network. Run `cupt prefetch` to populate the same cache eagerly when you know you'll be offline soon.
49
+
50
+ ## Installation
51
+
52
+ ### Recommended: System-wide using `pipx`
53
+ Use `pipx` to install `cupt` in an isolated environment that is globally available:
54
+
55
+ ```bash
56
+ # From the project root
57
+ pipx install .
58
+
59
+ # To update an existing installation after code changes:
60
+ pipx install --force .
61
+ ```
62
+
63
+ If you don't have `pipx`, install it via Homebrew: `brew install pipx && pipx ensurepath`.
64
+
65
+ ### Development: Local Editable Install
66
+ If you are developing or want an isolated virtual environment:
67
+ ```bash
68
+ git clone https://github.com/newz2000/cupt.git
69
+ cd cupt
70
+ python -m venv venv
71
+ source venv/bin/activate
72
+ pip install -e .
73
+ ```
74
+
75
+ ### Configuration
76
+ ```bash
77
+ cupt auth
78
+ # Follow prompts to authenticate
79
+ ```
80
+
81
+ ## Usage
82
+ - `cupt list`: List your active tasks
83
+ - `cupt list --overdue`: Show overdue tasks
84
+ - `cupt list --tag urgent --no-tag waiting`: Filter by tag (server-side)
85
+ - `cupt list --json`: Pipeable JSON output (combines with all filters)
86
+ - `cupt show <id>`: Show task details
87
+ - `cupt context <id>`: Show task parent and siblings
88
+ - `cupt done <id>`: Mark task as complete
89
+ - `cupt tag add <id> <name>` / `cupt tag remove <id> <name>`: Manage tags
90
+ - `cupt attach list <id>` / `cupt attach get <id> <selector>` / `cupt attach add <id> <file>`: Manage attachments
91
+ - `cupt time start <id>` / `cupt time stop`: Timer control
92
+ - `cupt note <id> "Your message"`: Add a note
93
+
94
+ ## Use as a Python library
95
+
96
+ `cupt` is usable as a dependency in your own Python code. Importing it
97
+ does no I/O — no config directory is created, no network calls happen
98
+ until you make one explicitly.
99
+
100
+ ```python
101
+ from cupt import ClickUpClient, TaskService, APIError
102
+
103
+ client = ClickUpClient("pk_xxxxxxxxxxxxxxxx") # personal API token
104
+ service = TaskService(client)
105
+
106
+ try:
107
+ tasks = service.list_tasks(
108
+ team_id="123456",
109
+ tags=["urgent"], # server-side filter
110
+ include_closed=False,
111
+ )
112
+ urgent_billing = service.filter_by_tags(
113
+ tasks, required=["urgent", "billing"]
114
+ )
115
+ for t in urgent_billing:
116
+ print(t["id"], t["name"])
117
+ except APIError as e:
118
+ print(f"ClickUp request failed: {e}")
119
+ ```
120
+
121
+ Public API surface (anything importable from `cupt` top-level):
122
+
123
+ | Symbol | Purpose |
124
+ | ----------------- | -------------------------------------------------------- |
125
+ | `ClickUpClient` | Thin HTTP wrapper around the ClickUp v2 REST API. |
126
+ | `TaskService` | List/filter/complete tasks; resolve parent names. |
127
+ | `TimeService` | Start/stop timers, add time entries, fetch totals. |
128
+ | `NoteService` | Add and list task comments. |
129
+ | `CuptError` | Base exception. All `cupt` errors subclass this. |
130
+ | `APIError` | HTTP failure, timeout, or invalid JSON from ClickUp. |
131
+ | `AuthError` | Missing or invalid credentials. |
132
+ | `ConfigError` | Configuration is missing or malformed. |
133
+
134
+ Other modules (`cupt.config`, `cupt.context`, command modules) are
135
+ internal to the CLI and may change between releases.
136
+
137
+ ## Testing
138
+ `cupt` is built with a strong focus on stability and testability.
139
+ - **Coverage**: 83% total coverage
140
+ - **Tests**: 186 unit tests using `pytest` and mocks.
141
+
142
+ Run the test suite:
143
+ ```bash
144
+ pytest --cov=cupt tests/
145
+ ```
146
+
147
+ ## Future Roadmap
148
+ Exciting features planned for upcoming releases:
149
+ - **`cupt work` / `cupt gtd`**: Sequential "focused work" mode to tackle a list of tasks one by one.
150
+ - **Quick Create**: Rapidly create follow-up tasks or subtasks while you work.
151
+ - **Workflow State**: Persistent session state for long-running workflows.
152
+ - **Shell Completion**: Tab-completion for task IDs and commands.
153
+
154
+ ## Project Structure
155
+ - `cupt/`: Package root.
156
+ - `cupt/services/`: Core business logic (TaskService, TimeService, NoteService).
157
+ - `cupt/api.py`: ClickUp API client wrapper.
158
+ - `cupt/main.py`: CLI entry point.
159
+ - `tests/`: Comprehensive unit tests.
160
+
161
+ ## Contributions
162
+ If you or your favorite AI tool want to make improvements, please submit a pull request. Please respect the requirements in the AGENTS.md file and run the pre-commit hook to verify compliance with the coding standards.
cupt-0.6.1/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # CUPT - ClickUp Task Management CLI
2
+
3
+ CUPT stands for “ClickUP Terminal,” a command-line interface for accessing your tasks in ClickUp in the terminal or via your favorite AI-based tool.
4
+
5
+ ## Features
6
+ - **Task Listing**: View active, overdue, and upcoming tasks with deep paging support.
7
+ - **Subtask Support**: Visual nesting (`↳`) and parent task resolution.
8
+ - **Hierarchical Context**: `cupt context <id>` shows parents and sibling subtasks.
9
+ - **Time Tracking**: Start/stop timers and add manual time entries.
10
+ - **Note Management**: Quick comments and note listing.
11
+ - **Flexible Auth**: Supports both OAuth and Personal API Tokens.
12
+ - **Offline Support**: After `cupt list` runs, it transparently caches the full details (description, comments, parent) for every task it just displayed, so a later `cupt show <id> --offline` works without a network. Run `cupt prefetch` to populate the same cache eagerly when you know you'll be offline soon.
13
+
14
+ ## Installation
15
+
16
+ ### Recommended: System-wide using `pipx`
17
+ Use `pipx` to install `cupt` in an isolated environment that is globally available:
18
+
19
+ ```bash
20
+ # From the project root
21
+ pipx install .
22
+
23
+ # To update an existing installation after code changes:
24
+ pipx install --force .
25
+ ```
26
+
27
+ If you don't have `pipx`, install it via Homebrew: `brew install pipx && pipx ensurepath`.
28
+
29
+ ### Development: Local Editable Install
30
+ If you are developing or want an isolated virtual environment:
31
+ ```bash
32
+ git clone https://github.com/newz2000/cupt.git
33
+ cd cupt
34
+ python -m venv venv
35
+ source venv/bin/activate
36
+ pip install -e .
37
+ ```
38
+
39
+ ### Configuration
40
+ ```bash
41
+ cupt auth
42
+ # Follow prompts to authenticate
43
+ ```
44
+
45
+ ## Usage
46
+ - `cupt list`: List your active tasks
47
+ - `cupt list --overdue`: Show overdue tasks
48
+ - `cupt list --tag urgent --no-tag waiting`: Filter by tag (server-side)
49
+ - `cupt list --json`: Pipeable JSON output (combines with all filters)
50
+ - `cupt show <id>`: Show task details
51
+ - `cupt context <id>`: Show task parent and siblings
52
+ - `cupt done <id>`: Mark task as complete
53
+ - `cupt tag add <id> <name>` / `cupt tag remove <id> <name>`: Manage tags
54
+ - `cupt attach list <id>` / `cupt attach get <id> <selector>` / `cupt attach add <id> <file>`: Manage attachments
55
+ - `cupt time start <id>` / `cupt time stop`: Timer control
56
+ - `cupt note <id> "Your message"`: Add a note
57
+
58
+ ## Use as a Python library
59
+
60
+ `cupt` is usable as a dependency in your own Python code. Importing it
61
+ does no I/O — no config directory is created, no network calls happen
62
+ until you make one explicitly.
63
+
64
+ ```python
65
+ from cupt import ClickUpClient, TaskService, APIError
66
+
67
+ client = ClickUpClient("pk_xxxxxxxxxxxxxxxx") # personal API token
68
+ service = TaskService(client)
69
+
70
+ try:
71
+ tasks = service.list_tasks(
72
+ team_id="123456",
73
+ tags=["urgent"], # server-side filter
74
+ include_closed=False,
75
+ )
76
+ urgent_billing = service.filter_by_tags(
77
+ tasks, required=["urgent", "billing"]
78
+ )
79
+ for t in urgent_billing:
80
+ print(t["id"], t["name"])
81
+ except APIError as e:
82
+ print(f"ClickUp request failed: {e}")
83
+ ```
84
+
85
+ Public API surface (anything importable from `cupt` top-level):
86
+
87
+ | Symbol | Purpose |
88
+ | ----------------- | -------------------------------------------------------- |
89
+ | `ClickUpClient` | Thin HTTP wrapper around the ClickUp v2 REST API. |
90
+ | `TaskService` | List/filter/complete tasks; resolve parent names. |
91
+ | `TimeService` | Start/stop timers, add time entries, fetch totals. |
92
+ | `NoteService` | Add and list task comments. |
93
+ | `CuptError` | Base exception. All `cupt` errors subclass this. |
94
+ | `APIError` | HTTP failure, timeout, or invalid JSON from ClickUp. |
95
+ | `AuthError` | Missing or invalid credentials. |
96
+ | `ConfigError` | Configuration is missing or malformed. |
97
+
98
+ Other modules (`cupt.config`, `cupt.context`, command modules) are
99
+ internal to the CLI and may change between releases.
100
+
101
+ ## Testing
102
+ `cupt` is built with a strong focus on stability and testability.
103
+ - **Coverage**: 83% total coverage
104
+ - **Tests**: 186 unit tests using `pytest` and mocks.
105
+
106
+ Run the test suite:
107
+ ```bash
108
+ pytest --cov=cupt tests/
109
+ ```
110
+
111
+ ## Future Roadmap
112
+ Exciting features planned for upcoming releases:
113
+ - **`cupt work` / `cupt gtd`**: Sequential "focused work" mode to tackle a list of tasks one by one.
114
+ - **Quick Create**: Rapidly create follow-up tasks or subtasks while you work.
115
+ - **Workflow State**: Persistent session state for long-running workflows.
116
+ - **Shell Completion**: Tab-completion for task IDs and commands.
117
+
118
+ ## Project Structure
119
+ - `cupt/`: Package root.
120
+ - `cupt/services/`: Core business logic (TaskService, TimeService, NoteService).
121
+ - `cupt/api.py`: ClickUp API client wrapper.
122
+ - `cupt/main.py`: CLI entry point.
123
+ - `tests/`: Comprehensive unit tests.
124
+
125
+ ## Contributions
126
+ If you or your favorite AI tool want to make improvements, please submit a pull request. Please respect the requirements in the AGENTS.md file and run the pre-commit hook to verify compliance with the coding standards.
@@ -0,0 +1,39 @@
1
+ """
2
+ CUPT — ClickUp Task Management CLI and Python library.
3
+
4
+ Use as a CLI:
5
+ $ cupt list --tag urgent
6
+
7
+ Use as a library:
8
+ from cupt import ClickUpClient, TaskService
9
+
10
+ client = ClickUpClient("pk_xxxxx") # personal API token
11
+ service = TaskService(client)
12
+ tasks = service.list_tasks(team_id="123", tags=["urgent"])
13
+
14
+ Public exports are intentionally limited to the API client, services, and
15
+ typed exceptions. Internal helpers (config, CLI commands, formatting) are
16
+ not part of the public API and may change between releases.
17
+ """
18
+
19
+ from cupt.api import ClickUpClient
20
+ from cupt.exceptions import APIError, AuthError, ConfigError, CuptError
21
+ from cupt.services.note_service import NoteService
22
+ from cupt.services.task_service import TaskService
23
+ from cupt.services.time_service import TimeService
24
+
25
+ __version__ = "0.6.1"
26
+ __author__ = "Matthew Nuzum"
27
+ __email__ = "matthew@nuzum.com"
28
+
29
+ __all__ = [
30
+ "ClickUpClient",
31
+ "TaskService",
32
+ "TimeService",
33
+ "NoteService",
34
+ "CuptError",
35
+ "APIError",
36
+ "AuthError",
37
+ "ConfigError",
38
+ "__version__",
39
+ ]
cupt-0.6.1/cupt/ai.py ADDED
@@ -0,0 +1,82 @@
1
+ """
2
+ Local AI backend abstraction for CUPT.
3
+
4
+ Provider priority:
5
+ 1. Apple Intelligence (apple-fm-sdk, macOS 26+)
6
+
7
+ Future providers (not yet implemented):
8
+ 2. Windows Copilot+ (WinRT Microsoft.Windows.AI)
9
+ 3. Ollama (http://localhost:11434)
10
+ """
11
+
12
+ import asyncio
13
+ import logging
14
+ from typing import Optional
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ _SYSTEM_INSTRUCTIONS = (
19
+ "You are a concise assistant helping a professional complete task management notes. "
20
+ "Write clear, brief, first-person completion notes. No preamble or explanation."
21
+ )
22
+
23
+
24
+ def get_ai_suggestion(prompt: str) -> Optional[str]:
25
+ """
26
+ Try available local AI backends and return a suggestion, or None if unavailable.
27
+
28
+ Returns None silently when no provider is found — callers are responsible
29
+ for surfacing a user-facing message.
30
+ """
31
+ result = _try_apple_intelligence(prompt)
32
+ if result is not None:
33
+ return result
34
+
35
+ # Future: _try_windows_copilot(prompt)
36
+ # Future: _try_ollama(prompt)
37
+
38
+ return None
39
+
40
+
41
+ def is_ai_available() -> bool:
42
+ """Return True if at least one local AI provider is available."""
43
+ return _apple_intelligence_available()
44
+
45
+
46
+ # ------------------------------------------------------------------
47
+ # Apple Intelligence
48
+ # ------------------------------------------------------------------
49
+
50
+
51
+ def _apple_intelligence_available() -> bool:
52
+ try:
53
+ import apple_fm_sdk as fm
54
+
55
+ available, _ = fm.SystemLanguageModel().is_available()
56
+ return available
57
+ except ImportError:
58
+ return False
59
+ except Exception:
60
+ return False
61
+
62
+
63
+ def _try_apple_intelligence(prompt: str) -> Optional[str]:
64
+ try:
65
+ import apple_fm_sdk as fm
66
+
67
+ model = fm.SystemLanguageModel()
68
+ available, reason = model.is_available()
69
+ if not available:
70
+ logger.debug("Apple Intelligence not available: %s", reason)
71
+ return None
72
+
73
+ session = fm.LanguageModelSession(instructions=_SYSTEM_INSTRUCTIONS)
74
+ result = asyncio.run(session.respond(prompt))
75
+ return result.strip() if result else None
76
+
77
+ except ImportError:
78
+ logger.debug("apple-fm-sdk not installed")
79
+ return None
80
+ except Exception as e:
81
+ logger.debug("Apple Intelligence error: %s", e)
82
+ return None