trelloctl 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.
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.3
2
+ Name: trelloctl
3
+ Version: 0.1.0
4
+ Summary: A command-line interface for Trello
5
+ Author: Werner Robitza
6
+ Author-email: Werner Robitza <werner.robitza@gmail.com>
7
+ Requires-Dist: click>=8.3.1
8
+ Requires-Dist: httpx>=0.28.1
9
+ Requires-Dist: keyring>=25.7.0
10
+ Requires-Dist: rich>=14.3.2
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+
14
+ # trelloctl
15
+
16
+ [![PyPI version](https://img.shields.io/pypi/v/trelloctl.svg)](https://pypi.org/project/trelloctl)
17
+ [![Python package](https://github.com/slhck/trelloctl/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/trelloctl/actions/workflows/python-package.yml)
18
+
19
+ A command-line interface for Trello, written in Python.
20
+
21
+ ## Requirements
22
+
23
+ - Python 3.11+
24
+
25
+ ## Installation
26
+
27
+ Simply run it via [uv](https://docs.astral.sh/uv/getting-started/installation/):
28
+
29
+ ```bash
30
+ uvx trelloctl
31
+ ```
32
+
33
+ Or install via [pipx](https://pipx.pypa.io/latest/installation/).
34
+ Or manually via pip:
35
+
36
+ ```bash
37
+ pip install trelloctl
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ ### Authentication
43
+
44
+ Before using the CLI, you need to authenticate with Trello:
45
+
46
+ 1. Go to the [Trello Power-Up Admin Portal](https://trello.com/power-ups/admin)
47
+ 2. Create a new Power-Up (required even for personal use)
48
+ 3. Copy your API key from the Power-Up's "API Key" section
49
+ 4. Run the login command:
50
+
51
+ ```bash
52
+ trelloctl auth login
53
+ ```
54
+
55
+ The CLI will guide you through entering your API key and generating a token. Credentials are stored securely in your system keychain.
56
+
57
+ To check your authentication status:
58
+
59
+ ```bash
60
+ trelloctl auth status
61
+ ```
62
+
63
+ To remove stored credentials:
64
+
65
+ ```bash
66
+ trelloctl auth logout
67
+ ```
68
+
69
+ ### Basic Command Examples
70
+
71
+ ```bash
72
+ # List all boards
73
+ trelloctl board list
74
+
75
+ # List lists on a board (by name or ID)
76
+ trelloctl list list "My Board"
77
+ trelloctl list list Development
78
+
79
+ # List cards in a list
80
+ trelloctl list cards "To Do" --board Development
81
+
82
+ # Show board details
83
+ trelloctl board show Development
84
+
85
+ # Create a card
86
+ trelloctl card create "To Do" --board Development --name "New task"
87
+
88
+ # Move a card to another list
89
+ trelloctl card move <card_id> Done --board Development
90
+
91
+ # Output as JSON
92
+ trelloctl --format json board list
93
+
94
+ # Output as CSV
95
+ trelloctl --format csv board list
96
+ ```
97
+
98
+ Names support partial matching (case-insensitive). If multiple items match, you'll be prompted to be more specific.
99
+
100
+ ## Command Reference
101
+
102
+ ### Global Options
103
+
104
+ | Option | Description |
105
+ |--------|-------------|
106
+ | `--format`, `-f` | Output format: `table` (default), `json`, `csv`, `plain` |
107
+ | `--profile`, `-p` | Configuration profile to use (default: `default`) |
108
+ | `--version` | Show version and exit |
109
+ | `--help` | Show help and exit |
110
+
111
+ ### `trelloctl auth`
112
+
113
+ Authentication commands.
114
+
115
+ | Command | Description |
116
+ |---------|-------------|
117
+ | `auth login` | Set up authentication with Trello |
118
+ | `auth status` | Check authentication status |
119
+ | `auth logout` | Remove stored credentials |
120
+
121
+ ### `trelloctl board`
122
+
123
+ Board management commands.
124
+
125
+ | Command | Description |
126
+ |---------|-------------|
127
+ | `board list [--filter]` | List all accessible boards |
128
+ | `board show <board>` | Show details of a board |
129
+ | `board create --name <name>` | Create a new board |
130
+ | `board close <board>` | Close (archive) a board |
131
+ | `board delete <board>` | Delete a board permanently |
132
+ | `board labels <board>` | List labels on a board |
133
+ | `board members <board>` | List members of a board |
134
+
135
+ ### `trelloctl list`
136
+
137
+ List management commands.
138
+
139
+ | Command | Description |
140
+ |---------|-------------|
141
+ | `list list <board>` | List all lists on a board |
142
+ | `list show <list> --board <board>` | Show details of a list |
143
+ | `list create <board> --name <name>` | Create a new list |
144
+ | `list archive <list> --board <board>` | Archive a list |
145
+ | `list cards <list> --board <board>` | List all cards in a list |
146
+
147
+ ### `trelloctl card`
148
+
149
+ Card management commands.
150
+
151
+ | Command | Description |
152
+ |---------|-------------|
153
+ | `card show <card_id>` | Show details of a card |
154
+ | `card create <list> --board <board> --name <name>` | Create a new card |
155
+ | `card move <card_id> <target_list> --board <board>` | Move a card to another list |
156
+ | `card update <card_id> [--name] [--description] [--due]` | Update a card |
157
+ | `card archive <card_id>` | Archive a card |
158
+ | `card delete <card_id>` | Delete a card permanently |
159
+ | `card assign <card_id> <member_id>` | Assign a member to a card |
160
+ | `card unassign <card_id> <member_id>` | Remove a member from a card |
161
+ | `card comment <card_id> <text>` | Add a comment to a card |
162
+ | `card comments <card_id>` | List comments on a card |
163
+
164
+ ### Multiple Profiles
165
+
166
+ You can use multiple Trello accounts by specifying a profile:
167
+
168
+ ```bash
169
+ # Set up a work profile
170
+ TRELLOCTL_PROFILE=work trelloctl auth login
171
+
172
+ # Use the work profile
173
+ trelloctl --profile work board list
174
+ ```
175
+
176
+ ## License
177
+
178
+ MIT License
179
+
180
+ Copyright (c) 2025 Werner Robitza
181
+
182
+ Permission is hereby granted, free of charge, to any person obtaining a copy
183
+ of this software and associated documentation files (the "Software"), to deal
184
+ in the Software without restriction, including without limitation the rights
185
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
186
+ copies of the Software, and to permit persons to whom the Software is
187
+ furnished to do so, subject to the following conditions:
188
+
189
+ The above copyright notice and this permission notice shall be included in all
190
+ copies or substantial portions of the Software.
191
+
192
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
193
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
194
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
195
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
197
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
198
+ SOFTWARE.
@@ -0,0 +1,185 @@
1
+ # trelloctl
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/trelloctl.svg)](https://pypi.org/project/trelloctl)
4
+ [![Python package](https://github.com/slhck/trelloctl/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/trelloctl/actions/workflows/python-package.yml)
5
+
6
+ A command-line interface for Trello, written in Python.
7
+
8
+ ## Requirements
9
+
10
+ - Python 3.11+
11
+
12
+ ## Installation
13
+
14
+ Simply run it via [uv](https://docs.astral.sh/uv/getting-started/installation/):
15
+
16
+ ```bash
17
+ uvx trelloctl
18
+ ```
19
+
20
+ Or install via [pipx](https://pipx.pypa.io/latest/installation/).
21
+ Or manually via pip:
22
+
23
+ ```bash
24
+ pip install trelloctl
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Authentication
30
+
31
+ Before using the CLI, you need to authenticate with Trello:
32
+
33
+ 1. Go to the [Trello Power-Up Admin Portal](https://trello.com/power-ups/admin)
34
+ 2. Create a new Power-Up (required even for personal use)
35
+ 3. Copy your API key from the Power-Up's "API Key" section
36
+ 4. Run the login command:
37
+
38
+ ```bash
39
+ trelloctl auth login
40
+ ```
41
+
42
+ The CLI will guide you through entering your API key and generating a token. Credentials are stored securely in your system keychain.
43
+
44
+ To check your authentication status:
45
+
46
+ ```bash
47
+ trelloctl auth status
48
+ ```
49
+
50
+ To remove stored credentials:
51
+
52
+ ```bash
53
+ trelloctl auth logout
54
+ ```
55
+
56
+ ### Basic Command Examples
57
+
58
+ ```bash
59
+ # List all boards
60
+ trelloctl board list
61
+
62
+ # List lists on a board (by name or ID)
63
+ trelloctl list list "My Board"
64
+ trelloctl list list Development
65
+
66
+ # List cards in a list
67
+ trelloctl list cards "To Do" --board Development
68
+
69
+ # Show board details
70
+ trelloctl board show Development
71
+
72
+ # Create a card
73
+ trelloctl card create "To Do" --board Development --name "New task"
74
+
75
+ # Move a card to another list
76
+ trelloctl card move <card_id> Done --board Development
77
+
78
+ # Output as JSON
79
+ trelloctl --format json board list
80
+
81
+ # Output as CSV
82
+ trelloctl --format csv board list
83
+ ```
84
+
85
+ Names support partial matching (case-insensitive). If multiple items match, you'll be prompted to be more specific.
86
+
87
+ ## Command Reference
88
+
89
+ ### Global Options
90
+
91
+ | Option | Description |
92
+ |--------|-------------|
93
+ | `--format`, `-f` | Output format: `table` (default), `json`, `csv`, `plain` |
94
+ | `--profile`, `-p` | Configuration profile to use (default: `default`) |
95
+ | `--version` | Show version and exit |
96
+ | `--help` | Show help and exit |
97
+
98
+ ### `trelloctl auth`
99
+
100
+ Authentication commands.
101
+
102
+ | Command | Description |
103
+ |---------|-------------|
104
+ | `auth login` | Set up authentication with Trello |
105
+ | `auth status` | Check authentication status |
106
+ | `auth logout` | Remove stored credentials |
107
+
108
+ ### `trelloctl board`
109
+
110
+ Board management commands.
111
+
112
+ | Command | Description |
113
+ |---------|-------------|
114
+ | `board list [--filter]` | List all accessible boards |
115
+ | `board show <board>` | Show details of a board |
116
+ | `board create --name <name>` | Create a new board |
117
+ | `board close <board>` | Close (archive) a board |
118
+ | `board delete <board>` | Delete a board permanently |
119
+ | `board labels <board>` | List labels on a board |
120
+ | `board members <board>` | List members of a board |
121
+
122
+ ### `trelloctl list`
123
+
124
+ List management commands.
125
+
126
+ | Command | Description |
127
+ |---------|-------------|
128
+ | `list list <board>` | List all lists on a board |
129
+ | `list show <list> --board <board>` | Show details of a list |
130
+ | `list create <board> --name <name>` | Create a new list |
131
+ | `list archive <list> --board <board>` | Archive a list |
132
+ | `list cards <list> --board <board>` | List all cards in a list |
133
+
134
+ ### `trelloctl card`
135
+
136
+ Card management commands.
137
+
138
+ | Command | Description |
139
+ |---------|-------------|
140
+ | `card show <card_id>` | Show details of a card |
141
+ | `card create <list> --board <board> --name <name>` | Create a new card |
142
+ | `card move <card_id> <target_list> --board <board>` | Move a card to another list |
143
+ | `card update <card_id> [--name] [--description] [--due]` | Update a card |
144
+ | `card archive <card_id>` | Archive a card |
145
+ | `card delete <card_id>` | Delete a card permanently |
146
+ | `card assign <card_id> <member_id>` | Assign a member to a card |
147
+ | `card unassign <card_id> <member_id>` | Remove a member from a card |
148
+ | `card comment <card_id> <text>` | Add a comment to a card |
149
+ | `card comments <card_id>` | List comments on a card |
150
+
151
+ ### Multiple Profiles
152
+
153
+ You can use multiple Trello accounts by specifying a profile:
154
+
155
+ ```bash
156
+ # Set up a work profile
157
+ TRELLOCTL_PROFILE=work trelloctl auth login
158
+
159
+ # Use the work profile
160
+ trelloctl --profile work board list
161
+ ```
162
+
163
+ ## License
164
+
165
+ MIT License
166
+
167
+ Copyright (c) 2025 Werner Robitza
168
+
169
+ Permission is hereby granted, free of charge, to any person obtaining a copy
170
+ of this software and associated documentation files (the "Software"), to deal
171
+ in the Software without restriction, including without limitation the rights
172
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
173
+ copies of the Software, and to permit persons to whom the Software is
174
+ furnished to do so, subject to the following conditions:
175
+
176
+ The above copyright notice and this permission notice shall be included in all
177
+ copies or substantial portions of the Software.
178
+
179
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
180
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
182
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
183
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
184
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
185
+ SOFTWARE.
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "trelloctl"
3
+ version = "0.1.0"
4
+ description = "A command-line interface for Trello"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Werner Robitza", email = "werner.robitza@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "click>=8.3.1",
12
+ "httpx>=0.28.1",
13
+ "keyring>=25.7.0",
14
+ "rich>=14.3.2",
15
+ ]
16
+
17
+ [project.scripts]
18
+ trelloctl = "trelloctl.cli:main"
19
+
20
+ [build-system]
21
+ requires = ["uv_build>=0.9.26,<0.10.0"]
22
+ build-backend = "uv_build"
23
+
24
+ [dependency-groups]
25
+ dev = [
26
+ "mypy>=1.19.1",
27
+ "pre-commit>=4.2.0",
28
+ "pytest>=9.0.2",
29
+ "pytest-mock>=3.14.0",
30
+ "ruff>=0.15.0",
31
+ ]
@@ -0,0 +1,5 @@
1
+ """trelloctl - A command-line interface for Trello."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("trelloctl")
@@ -0,0 +1,91 @@
1
+ """Main CLI entry point."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+
8
+ import click
9
+
10
+ from trelloctl import __version__
11
+ from trelloctl.client import TrelloClient
12
+ from trelloctl.config import Config
13
+ from trelloctl.output import OutputFormat, print_error
14
+ from trelloctl.resolver import Resolver
15
+
16
+
17
+ class Context:
18
+ """CLI context object holding shared state."""
19
+
20
+ def __init__(self) -> None:
21
+ self.profile = os.environ.get("TRELLOCTL_PROFILE", "default")
22
+ self.config = Config(self.profile)
23
+ self.client: TrelloClient | None = None
24
+ self._resolver: Resolver | None = None
25
+ self.format = OutputFormat.TABLE
26
+
27
+ def ensure_client(self) -> TrelloClient:
28
+ """Ensure we have an authenticated client."""
29
+ if self.client is None:
30
+ api_key = self.config.get_api_key()
31
+ token = self.config.get_token()
32
+
33
+ if not api_key or not token:
34
+ print_error("Not authenticated. Run 'trelloctl auth login' first.")
35
+ sys.exit(1)
36
+
37
+ self.client = TrelloClient(api_key, token)
38
+
39
+ return self.client
40
+
41
+ @property
42
+ def resolver(self) -> Resolver:
43
+ """Get the name resolver."""
44
+ if self._resolver is None:
45
+ self._resolver = Resolver(self.ensure_client())
46
+ return self._resolver
47
+
48
+
49
+ pass_context = click.make_pass_decorator(Context, ensure=True)
50
+
51
+
52
+ @click.group()
53
+ @click.version_option(version=__version__, prog_name="trelloctl")
54
+ @click.option(
55
+ "--format",
56
+ "-f",
57
+ type=click.Choice(["table", "json", "csv", "plain"]),
58
+ default="table",
59
+ help="Output format",
60
+ )
61
+ @click.option(
62
+ "--profile",
63
+ "-p",
64
+ envvar="TRELLOCTL_PROFILE",
65
+ default="default",
66
+ help="Configuration profile to use",
67
+ )
68
+ @pass_context
69
+ def main(ctx: Context, format: str, profile: str) -> None:
70
+ """trelloctl - Manage your Trello boards from the command line."""
71
+ ctx.format = OutputFormat(format)
72
+ ctx.profile = profile
73
+ ctx.config = Config(profile)
74
+
75
+
76
+ def _register_commands() -> None:
77
+ """Register command groups with the main CLI."""
78
+ from trelloctl.commands import auth, board, card
79
+ from trelloctl.commands import list as list_cmd
80
+
81
+ main.add_command(auth.auth)
82
+ main.add_command(board.board)
83
+ main.add_command(card.card)
84
+ main.add_command(list_cmd.list_)
85
+
86
+
87
+ _register_commands()
88
+
89
+
90
+ if __name__ == "__main__":
91
+ main()
@@ -0,0 +1,179 @@
1
+ """Trello API client."""
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ BASE_URL = "https://api.trello.com/1"
8
+
9
+
10
+ class TrelloClient:
11
+ """HTTP client for Trello API."""
12
+
13
+ def __init__(self, api_key: str, token: str) -> None:
14
+ self.api_key = api_key
15
+ self.token = token
16
+ self._client = httpx.Client(timeout=30.0)
17
+
18
+ def _auth_params(self) -> dict[str, str]:
19
+ """Return authentication parameters."""
20
+ return {"key": self.api_key, "token": self.token}
21
+
22
+ def _request(
23
+ self,
24
+ method: str,
25
+ path: str,
26
+ params: dict | None = None,
27
+ json: dict | None = None,
28
+ ) -> Any:
29
+ """Make an authenticated request to Trello API."""
30
+ url = f"{BASE_URL}{path}"
31
+ all_params = self._auth_params()
32
+ if params:
33
+ all_params.update(params)
34
+
35
+ response = self._client.request(method, url, params=all_params, json=json)
36
+ response.raise_for_status()
37
+
38
+ if response.status_code == 204:
39
+ return None
40
+ return response.json()
41
+
42
+ def get(self, path: str, params: dict | None = None) -> Any:
43
+ """Make a GET request."""
44
+ return self._request("GET", path, params=params)
45
+
46
+ def post(
47
+ self, path: str, params: dict | None = None, json: dict | None = None
48
+ ) -> Any:
49
+ """Make a POST request."""
50
+ return self._request("POST", path, params=params, json=json)
51
+
52
+ def put(
53
+ self, path: str, params: dict | None = None, json: dict | None = None
54
+ ) -> Any:
55
+ """Make a PUT request."""
56
+ return self._request("PUT", path, params=params, json=json)
57
+
58
+ def delete(self, path: str, params: dict | None = None) -> Any:
59
+ """Make a DELETE request."""
60
+ return self._request("DELETE", path, params=params)
61
+
62
+ # Board methods
63
+ def get_boards(self, filter: str = "open") -> list[dict]:
64
+ """Get all boards for the authenticated user."""
65
+ return self.get("/members/me/boards", params={"filter": filter})
66
+
67
+ def get_board(self, board_id: str) -> dict:
68
+ """Get a board by ID."""
69
+ return self.get(f"/boards/{board_id}")
70
+
71
+ def create_board(self, name: str, desc: str = "") -> dict:
72
+ """Create a new board."""
73
+ return self.post("/boards", params={"name": name, "desc": desc})
74
+
75
+ def close_board(self, board_id: str, closed: bool = True) -> dict:
76
+ """Close or reopen a board."""
77
+ return self.put(f"/boards/{board_id}", params={"closed": str(closed).lower()})
78
+
79
+ def delete_board(self, board_id: str) -> None:
80
+ """Delete a board."""
81
+ self.delete(f"/boards/{board_id}")
82
+
83
+ def get_board_lists(self, board_id: str, filter: str = "open") -> list[dict]:
84
+ """Get all lists on a board."""
85
+ return self.get(f"/boards/{board_id}/lists", params={"filter": filter})
86
+
87
+ def get_board_labels(self, board_id: str) -> list[dict]:
88
+ """Get all labels on a board."""
89
+ return self.get(f"/boards/{board_id}/labels")
90
+
91
+ def get_board_members(self, board_id: str) -> list[dict]:
92
+ """Get all members of a board."""
93
+ return self.get(f"/boards/{board_id}/members")
94
+
95
+ # List methods
96
+ def get_list(self, list_id: str) -> dict:
97
+ """Get a list by ID."""
98
+ return self.get(f"/lists/{list_id}")
99
+
100
+ def create_list(self, board_id: str, name: str, pos: str = "bottom") -> dict:
101
+ """Create a new list on a board."""
102
+ return self.post(
103
+ "/lists", params={"idBoard": board_id, "name": name, "pos": pos}
104
+ )
105
+
106
+ def archive_list(self, list_id: str, closed: bool = True) -> dict:
107
+ """Archive or unarchive a list."""
108
+ return self.put(f"/lists/{list_id}", params={"closed": str(closed).lower()})
109
+
110
+ def get_list_cards(self, list_id: str) -> list[dict]:
111
+ """Get all cards in a list."""
112
+ return self.get(f"/lists/{list_id}/cards")
113
+
114
+ # Card methods
115
+ def get_card(self, card_id: str) -> dict:
116
+ """Get a card by ID."""
117
+ return self.get(f"/cards/{card_id}")
118
+
119
+ def create_card(
120
+ self,
121
+ list_id: str,
122
+ name: str,
123
+ desc: str = "",
124
+ pos: str = "bottom",
125
+ due: str | None = None,
126
+ labels: list[str] | None = None,
127
+ members: list[str] | None = None,
128
+ ) -> dict:
129
+ """Create a new card."""
130
+ params: dict[str, Any] = {
131
+ "idList": list_id,
132
+ "name": name,
133
+ "desc": desc,
134
+ "pos": pos,
135
+ }
136
+ if due:
137
+ params["due"] = due
138
+ if labels:
139
+ params["idLabels"] = ",".join(labels)
140
+ if members:
141
+ params["idMembers"] = ",".join(members)
142
+ return self.post("/cards", params=params)
143
+
144
+ def update_card(self, card_id: str, **kwargs: Any) -> dict:
145
+ """Update a card."""
146
+ return self.put(f"/cards/{card_id}", params=kwargs)
147
+
148
+ def move_card(self, card_id: str, list_id: str, pos: str = "bottom") -> dict:
149
+ """Move a card to a different list."""
150
+ return self.put(f"/cards/{card_id}", params={"idList": list_id, "pos": pos})
151
+
152
+ def archive_card(self, card_id: str, closed: bool = True) -> dict:
153
+ """Archive or unarchive a card."""
154
+ return self.put(f"/cards/{card_id}", params={"closed": str(closed).lower()})
155
+
156
+ def delete_card(self, card_id: str) -> None:
157
+ """Delete a card."""
158
+ self.delete(f"/cards/{card_id}")
159
+
160
+ def add_card_member(self, card_id: str, member_id: str) -> list[dict]:
161
+ """Add a member to a card."""
162
+ return self.post(f"/cards/{card_id}/idMembers", params={"value": member_id})
163
+
164
+ def remove_card_member(self, card_id: str, member_id: str) -> list[dict]:
165
+ """Remove a member from a card."""
166
+ return self.delete(f"/cards/{card_id}/idMembers/{member_id}")
167
+
168
+ def add_card_comment(self, card_id: str, text: str) -> dict:
169
+ """Add a comment to a card."""
170
+ return self.post(f"/cards/{card_id}/actions/comments", params={"text": text})
171
+
172
+ def get_card_comments(self, card_id: str) -> list[dict]:
173
+ """Get comments on a card."""
174
+ return self.get(f"/cards/{card_id}/actions", params={"filter": "commentCard"})
175
+
176
+ # Member methods
177
+ def get_me(self) -> dict:
178
+ """Get the authenticated user."""
179
+ return self.get("/members/me")
@@ -0,0 +1 @@
1
+ """Command modules for Trello CLI."""