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.
- cupt-0.6.1/LICENSE +21 -0
- cupt-0.6.1/PKG-INFO +162 -0
- cupt-0.6.1/README.md +126 -0
- cupt-0.6.1/cupt/__init__.py +39 -0
- cupt-0.6.1/cupt/ai.py +82 -0
- cupt-0.6.1/cupt/api.py +290 -0
- cupt-0.6.1/cupt/attachments.py +145 -0
- cupt-0.6.1/cupt/auth.py +246 -0
- cupt-0.6.1/cupt/config.py +153 -0
- cupt-0.6.1/cupt/context.py +42 -0
- cupt-0.6.1/cupt/exceptions.py +17 -0
- cupt-0.6.1/cupt/main.py +255 -0
- cupt-0.6.1/cupt/notes.py +52 -0
- cupt-0.6.1/cupt/services/__init__.py +5 -0
- cupt-0.6.1/cupt/services/note_service.py +16 -0
- cupt-0.6.1/cupt/services/task_service.py +305 -0
- cupt-0.6.1/cupt/services/time_service.py +29 -0
- cupt-0.6.1/cupt/summary.py +181 -0
- cupt-0.6.1/cupt/tags.py +42 -0
- cupt-0.6.1/cupt/tasks.py +891 -0
- cupt-0.6.1/cupt/time_tracker.py +107 -0
- cupt-0.6.1/cupt/utils.py +162 -0
- cupt-0.6.1/cupt.egg-info/PKG-INFO +162 -0
- cupt-0.6.1/cupt.egg-info/SOURCES.txt +42 -0
- cupt-0.6.1/cupt.egg-info/dependency_links.txt +1 -0
- cupt-0.6.1/cupt.egg-info/entry_points.txt +2 -0
- cupt-0.6.1/cupt.egg-info/requires.txt +6 -0
- cupt-0.6.1/cupt.egg-info/top_level.txt +1 -0
- cupt-0.6.1/pyproject.toml +92 -0
- cupt-0.6.1/setup.cfg +4 -0
- cupt-0.6.1/tests/test_ai.py +134 -0
- cupt-0.6.1/tests/test_api.py +271 -0
- cupt-0.6.1/tests/test_attachments.py +169 -0
- cupt-0.6.1/tests/test_auth.py +148 -0
- cupt-0.6.1/tests/test_config.py +106 -0
- cupt-0.6.1/tests/test_context.py +54 -0
- cupt-0.6.1/tests/test_main.py +148 -0
- cupt-0.6.1/tests/test_notes.py +38 -0
- cupt-0.6.1/tests/test_summary.py +266 -0
- cupt-0.6.1/tests/test_tags.py +47 -0
- cupt-0.6.1/tests/test_task_service.py +198 -0
- cupt-0.6.1/tests/test_tasks.py +925 -0
- cupt-0.6.1/tests/test_time_tracker.py +134 -0
- 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
|