trelly 0.1.0

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 (46) hide show
  1. package/README.md +191 -0
  2. package/bin/run-ts +31 -0
  3. package/bin/trelly +2 -0
  4. package/bin/trelly-mcp +2 -0
  5. package/package.json +64 -0
  6. package/src/api/client.ts +332 -0
  7. package/src/api/http.ts +86 -0
  8. package/src/auth/browser-flow.ts +217 -0
  9. package/src/auth/profiles.ts +163 -0
  10. package/src/cli/commands/actions.ts +17 -0
  11. package/src/cli/commands/api.ts +46 -0
  12. package/src/cli/commands/auth.ts +248 -0
  13. package/src/cli/commands/boards.ts +152 -0
  14. package/src/cli/commands/cards.ts +194 -0
  15. package/src/cli/commands/checklists.ts +79 -0
  16. package/src/cli/commands/custom-fields.ts +75 -0
  17. package/src/cli/commands/labels.ts +47 -0
  18. package/src/cli/commands/lists.ts +54 -0
  19. package/src/cli/commands/members.ts +14 -0
  20. package/src/cli/commands/orgs.ts +23 -0
  21. package/src/cli/commands/run.ts +32 -0
  22. package/src/cli/commands/search.ts +23 -0
  23. package/src/cli/commands/ui.ts +48 -0
  24. package/src/cli/commands/webhooks.ts +44 -0
  25. package/src/cli/context.ts +70 -0
  26. package/src/cli/index.ts +47 -0
  27. package/src/cli/ui/app.tsx +753 -0
  28. package/src/cli/ui/custom-fields.ts +75 -0
  29. package/src/cli/ui/palette.ts +69 -0
  30. package/src/cli/ui/shapes.ts +68 -0
  31. package/src/cli/ui/static.tsx +382 -0
  32. package/src/index.test.ts +117 -0
  33. package/src/mcp/handlers.ts +61 -0
  34. package/src/mcp/server.ts +17 -0
  35. package/src/mcp/tools/api.ts +27 -0
  36. package/src/mcp/tools/boards.ts +116 -0
  37. package/src/mcp/tools/cards.ts +138 -0
  38. package/src/mcp/tools/checklists.ts +40 -0
  39. package/src/mcp/tools/index.ts +22 -0
  40. package/src/mcp/tools/labels.ts +40 -0
  41. package/src/mcp/tools/lists.ts +37 -0
  42. package/src/mcp/tools/profiles.ts +40 -0
  43. package/src/mcp/tools/search.ts +31 -0
  44. package/src/mcp/tools/webhooks.ts +52 -0
  45. package/src/util/runtime.ts +39 -0
  46. package/src/version.ts +15 -0
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # trelly ~ trello CLI
2
+
3
+ Fast Trello CLI + MCP server ([npm](https://www.npmjs.com/package/trelly): `npm install -g trelly`).
4
+ **Human, Trello-styled output by default**; add `--json` for scripts and automation.
5
+ Commands: **`trelly`** (CLI) and **`trelly-mcp`** (MCP server).
6
+
7
+ ![trelly interactive UI](cli.gif)
8
+
9
+ Boards, lists, cards, checklists, labels, custom fields, search, webhooks, multi-profile
10
+ auth, interactive kanban TUI, raw `trelly api` escape hatch.
11
+
12
+ ## Quick start
13
+
14
+ ```bash
15
+ npm install -g trelly
16
+ trelly auth setup # once: API key from power-ups/admin
17
+ trelly auth login # browser → Allow
18
+ trelly boards list
19
+ ```
20
+
21
+ From source (repo [brandonkramer/trelly](https://github.com/brandonkramer/trelly)):
22
+
23
+ ```bash
24
+ git clone https://github.com/brandonkramer/trelly.git && cd trelly
25
+ bun install
26
+ ./bin/trelly auth setup
27
+ ./bin/trelly auth login
28
+ ./bin/trelly boards list
29
+ ```
30
+
31
+ No Bun? `npm install` in the clone — tsx is the fallback runtime.
32
+
33
+ Optional: `bun link` / `npm link`, or add `bin/` to `PATH`.
34
+
35
+ ## Output
36
+
37
+ | Mode | Command | stdout |
38
+ |------|---------|--------|
39
+ | Default | `trelly boards list` | Styled rows (labels, due badges, etc.) |
40
+ | JSON | `trelly --json boards list` | `{ ok, profile, data }` |
41
+ | Pretty JSON | `trelly --json --pretty boards list` | Indented envelope |
42
+
43
+ - **Errors:** red `✗ message` in human mode, exit code `1` (use `--json` for `{ ok: false, ... }`).
44
+ - **Pipes:** colors auto-disable when stdout is not a TTY.
45
+ - **Scripts:** always pass `--json` if you parse stdout. The MCP server is unchanged (never uses CLI output).
46
+
47
+ ## Interactive UI
48
+
49
+ Bare **`trelly`** (no subcommand) opens the Ink kanban board in your terminal — same as `trelly ui`.
50
+
51
+ ```bash
52
+ trelly # board picker when no id given
53
+ trelly ui # same
54
+ trelly ui BOARD_ID # jump straight to a board
55
+ ```
56
+
57
+ Requires a TTY. Keys: **arrows** / **hjkl** move focus, **Enter** card detail, **r** refresh, **q** / **Esc** back or quit.
58
+
59
+ See the demo above or run `trelly --help` for all subcommands.
60
+
61
+ ## Auth
62
+
63
+ Two steps: **API key** (app identity, once) → **token** (your account, per profile).
64
+
65
+ Register a throwaway app at [power-ups/admin](https://trello.com/power-ups/admin) — you are **not** installing a Power-Up on your boards. Pick any workspace you **admin** (personal is fine); that choice does not limit which boards you can use. Iframe URL can be any `https://` placeholder (e.g. `https://example.com`). Add `http://127.0.0.1:14189` to **Allowed Origins** for automatic browser login.
66
+
67
+ After login the CLI is **you** on Trello — same boards and permissions as the website.
68
+
69
+ ```bash
70
+ trelly auth setup
71
+ trelly auth login
72
+ trelly auth login --profile work
73
+ trelly auth login --manual # paste token if redirect blocked
74
+ trelly auth login --full-access # never-expiring token
75
+ trelly auth list
76
+ trelly auth use work
77
+ trelly auth logout --profile work
78
+ trelly auth url
79
+ ```
80
+
81
+ Non-interactive: `trelly auth setup --api-key KEY` then `trelly auth login --api-key KEY --token TOKEN`.
82
+
83
+ Environment override: `TRELLO_APP_API_KEY`, `TRELLO_API_KEY`, `TRELLO_TOKEN`, `TRELLO_PROFILE`.
84
+
85
+ Credentials: `~/.config/trelly/config.json` (mode `600`).
86
+
87
+ ## Usage
88
+
89
+ ```bash
90
+ trelly boards list
91
+ trelly --json --pretty boards list | jq '.data[].name'
92
+ trelly --profile work boards lists BOARD_ID
93
+ trelly cards create --list LIST_ID --name "Ship feature"
94
+ trelly cards comments CARD_ID
95
+ trelly cards comment CARD_ID --text "Shipped"
96
+ trelly search "customer onboarding"
97
+ trelly api -X PUT --path /cards/CARD_ID --query idList=LIST_ID
98
+ trelly api -X POST --path /cards --body '{"idList":"LIST_ID","name":"Hi"}'
99
+ ```
100
+
101
+ Flags: `-p, --profile <name>`, `--json`, `--pretty` (with `--json` only).
102
+
103
+ **Archive** (reversible) vs **delete** (permanent): prefer `cards archive` / `boards archive` over `cards delete` / `boards delete`.
104
+
105
+ ### Command reference
106
+
107
+ Top-level: `auth` · `boards` · `lists` · `cards` · `checklists` · `labels` · `custom-fields` · `search` · `webhooks` · `members` · `orgs` · `actions` · `api` · `ui`
108
+
109
+ | Group | Subcommands |
110
+ |-------|-------------|
111
+ | **auth** | `setup` · `login` · `list` · `use` · `logout` · `url` |
112
+ | **boards** | `list` · `get` · `create` · `update` · `archive` · `delete` · `lists` · `cards` · `labels` · `members` · `actions` · `custom-fields` |
113
+ | **lists** | `get` · `create` · `update` · `archive` · `cards` |
114
+ | **cards** | `get` · `list` · `create` · `update` · `move` · `comments` · `comment` · `archive` · `delete` · `members` · `add-member` · `remove-member` · `labels` · `add-label` · `remove-label` · `actions` · `attachments` · `add-attachment` · `custom-fields` |
115
+ | **checklists** | `get` · `create` · `update` · `delete` · `add-item` · `update-item` · `delete-item` |
116
+ | **labels** | `get` · `create` · `update` · `delete` |
117
+ | **custom-fields** | `get` · `create` · `update` · `delete` · `set-item` |
118
+ | **search** | `<query>` (`--model-types`, limits) |
119
+ | **webhooks** | `list` · `create` · `get` · `delete` |
120
+ | **members** | `me` |
121
+ | **orgs** | `get` · `boards` |
122
+ | **actions** | `get` |
123
+ | **api** | raw REST (`-X`, `--path`, `--query`, `--body`) |
124
+ | **ui** | `[boardId]` — or run bare `trello` / `trelly` |
125
+
126
+ List-type custom field values: use `trelly api` with `PUT /cards/{id}/customField/{fieldId}/item` and `{"idValue":"..."}` (see [skills/trelly/SKILL.md](skills/trelly/SKILL.md)).
127
+
128
+ Per-subcommand flags: `trelly <group> --help`. Curated examples and agent guidance: [skills/trelly/SKILL.md](skills/trelly/SKILL.md).
129
+
130
+ ## MCP
131
+
132
+ Add to `~/.cursor/mcp.json` (see `mcp.example.json`):
133
+
134
+ ```json
135
+ "trelly": {
136
+ "command": "trelly-mcp",
137
+ "env": { "TRELLO_PROFILE": "default" }
138
+ }
139
+ ```
140
+
141
+ After `npm install -g trelly`, `trelly-mcp` is on your PATH. From a clone, use the full path to `bin/trelly-mcp`.
142
+
143
+ Stdio server — JSON envelope on every tool (`{ ok, profile, data }`), never CLI human output. Pass **`profile`** on any tool for a non-default account. Prefer **`trello_*_archive`** over **`trello_card_delete`** (permanent; no board-delete MCP tool).
144
+
145
+ ### MCP tools (27)
146
+
147
+ | Tool | Purpose |
148
+ |------|---------|
149
+ | `trello_profiles_list` | Saved profiles + default |
150
+ | `trello_member_me` | Authenticated member |
151
+ | `trello_boards_list` | Member boards |
152
+ | `trello_board_get` | Board by id |
153
+ | `trello_board_create` | Create board |
154
+ | `trello_board_archive` | Close board (reversible) |
155
+ | `trello_board_lists` | Lists on board |
156
+ | `trello_board_cards` | All cards on board |
157
+ | `trello_list_create` | Create list |
158
+ | `trello_list_cards` | Cards in list |
159
+ | `trello_card_get` | Card by id |
160
+ | `trello_card_create` | Create card |
161
+ | `trello_card_update` | Update card fields |
162
+ | `trello_card_move` | Move to another list |
163
+ | `trello_card_comments` | List comments |
164
+ | `trello_card_comment` | Add comment |
165
+ | `trello_card_archive` | Close card (reversible) |
166
+ | `trello_card_delete` | **Permanent** delete |
167
+ | `trello_checklist_create` | Checklist on card |
168
+ | `trello_checklist_add_item` | Checklist item |
169
+ | `trello_label_create` | Board label |
170
+ | `trello_card_add_label` | Label on card |
171
+ | `trello_search` | Search Trello |
172
+ | `trello_webhooks_list` | Token webhooks |
173
+ | `trello_webhook_create` | Create webhook |
174
+ | `trello_webhook_delete` | Delete webhook |
175
+ | `trello_api` | Raw REST escape hatch |
176
+
177
+ Full tool notes and MCP vs CLI guidance: [skills/trelly-mcp/SKILL.md](skills/trelly-mcp/SKILL.md).
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ bun run typecheck && bun test && bun run lint
183
+ ```
184
+
185
+ CI runs the same via `bun install --frozen-lockfile`. See `AGENTS.md` for conventions.
186
+
187
+ **Agent skills:** [skills/](skills/README.md) — portable `SKILL.md` files for Cursor, Claude, Pi, Codex (`trelly`, `trelly-mcp`).
188
+
189
+ ## License
190
+
191
+ MIT
package/bin/run-ts ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
4
+
5
+ run_ts() {
6
+ local entry="$1"
7
+ shift
8
+
9
+ if command -v bun >/dev/null 2>&1 && bun --version >/dev/null 2>&1; then
10
+ exec bun run "$ROOT/$entry" "$@"
11
+ fi
12
+
13
+ if [[ -x "$HOME/.bun/bin/bun" ]]; then
14
+ exec "$HOME/.bun/bin/bun" run "$ROOT/$entry" "$@"
15
+ fi
16
+
17
+ if [[ -x "$ROOT/node_modules/.bin/tsx" ]]; then
18
+ exec "$ROOT/node_modules/.bin/tsx" "$ROOT/$entry" "$@"
19
+ fi
20
+
21
+ if command -v tsx >/dev/null 2>&1; then
22
+ exec tsx "$ROOT/$entry" "$@"
23
+ fi
24
+
25
+ echo "No runtime found. Install deps first:" >&2
26
+ echo " bun install" >&2
27
+ echo " # fallback (Node 22+): npm install" >&2
28
+ exit 1
29
+ }
30
+
31
+ run_ts "$@"
package/bin/trelly ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ exec "$(dirname "$0")/run-ts" "src/cli/index.ts" "$@"
package/bin/trelly-mcp ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ exec "$(dirname "$0")/run-ts" "src/mcp/server.ts" "$@"
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "trelly",
3
+ "version": "0.1.0",
4
+ "description": "trelly — fast Trello CLI with multi-profile auth, MCP server, and kanban TUI",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/brandonkramer/trelly#readme",
8
+ "keywords": [
9
+ "trello",
10
+ "cli",
11
+ "trelly",
12
+ "mcp",
13
+ "kanban",
14
+ "automation"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/brandonkramer/trelly.git"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "os": [
24
+ "darwin",
25
+ "linux"
26
+ ],
27
+ "files": [
28
+ "bin/",
29
+ "src/"
30
+ ],
31
+ "bin": {
32
+ "trelly": "./bin/trelly",
33
+ "trelly-mcp": "./bin/trelly-mcp"
34
+ },
35
+ "scripts": {
36
+ "trelly": "bun src/cli/index.ts",
37
+ "mcp": "bun src/mcp/server.ts",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "bun test",
40
+ "lint": "biome check .",
41
+ "fmt": "biome format --write .",
42
+ "fmt:check": "biome check .",
43
+ "postinstall": "chmod +x bin/trelly bin/trelly-mcp bin/run-ts 2>/dev/null || true",
44
+ "prepublishOnly": "bun run typecheck && bun test && bun run lint"
45
+ },
46
+ "engines": {
47
+ "bun": ">=1.2.0",
48
+ "node": ">=22"
49
+ },
50
+ "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.29.0",
52
+ "commander": "^15.0.0",
53
+ "ink": "^7.1.0",
54
+ "react": "^19.2.7",
55
+ "tsx": "^4.22.5",
56
+ "zod": "^4.4.3"
57
+ },
58
+ "devDependencies": {
59
+ "@biomejs/biome": "^2.5.2",
60
+ "@types/node": "^26.1.0",
61
+ "@types/react": "^19.2.17",
62
+ "typescript": "^6.0.3"
63
+ }
64
+ }
@@ -0,0 +1,332 @@
1
+ import {
2
+ type JsonValue,
3
+ parseTrelloResponse,
4
+ type Query,
5
+ type RequestOptions,
6
+ TrelloError,
7
+ trelloErrorMessage,
8
+ trelloFetch,
9
+ } from "./http.ts";
10
+
11
+ export {
12
+ type JsonValue,
13
+ type Query,
14
+ type RequestOptions,
15
+ TrelloError,
16
+ } from "./http.ts";
17
+
18
+ export class TrelloClient {
19
+ private readonly base = "https://api.trello.com/1";
20
+
21
+ constructor(
22
+ private readonly apiKey: string,
23
+ private readonly token: string,
24
+ private readonly requestOptions: RequestOptions = {},
25
+ ) {}
26
+
27
+ async request<T = JsonValue>(
28
+ method: string,
29
+ path: string,
30
+ query: Query = {},
31
+ body?: JsonValue,
32
+ ): Promise<T> {
33
+ const url = new URL(`${this.base}${path.startsWith("/") ? path : `/${path}`}`);
34
+
35
+ for (const [key, value] of Object.entries(query)) {
36
+ if (value !== undefined) {
37
+ url.searchParams.set(key, String(value));
38
+ }
39
+ }
40
+
41
+ const headers: Record<string, string> = {
42
+ Authorization: `OAuth oauth_consumer_key="${this.apiKey}", oauth_token="${this.token}"`,
43
+ };
44
+
45
+ const init: RequestInit = { method, headers };
46
+ if (body !== undefined) {
47
+ headers["Content-Type"] = "application/json";
48
+ init.body = JSON.stringify(body);
49
+ }
50
+
51
+ const res = await trelloFetch(url, init, this.requestOptions);
52
+ const text = await res.text();
53
+ const parsed = parseTrelloResponse(text);
54
+
55
+ if (!res.ok) {
56
+ throw new TrelloError(trelloErrorMessage(parsed, res.status), res.status, parsed);
57
+ }
58
+
59
+ return parsed as T;
60
+ }
61
+
62
+ get<T = JsonValue>(path: string, query?: Query): Promise<T> {
63
+ return this.request("GET", path, query);
64
+ }
65
+
66
+ post<T = JsonValue>(path: string, query?: Query, body?: JsonValue): Promise<T> {
67
+ return this.request("POST", path, query, body);
68
+ }
69
+
70
+ put<T = JsonValue>(path: string, query?: Query, body?: JsonValue): Promise<T> {
71
+ return this.request("PUT", path, query, body);
72
+ }
73
+
74
+ delete<T = JsonValue>(path: string, query?: Query): Promise<T> {
75
+ return this.request("DELETE", path, query);
76
+ }
77
+
78
+ memberMe(fields = "fullName,username,url,email") {
79
+ return this.get("/members/me", { fields });
80
+ }
81
+
82
+ memberBoards(memberId = "me", query: Query = {}) {
83
+ return this.get(`/members/${memberId}/boards`, query);
84
+ }
85
+
86
+ boardGet(id: string, query: Query = {}) {
87
+ return this.get(`/boards/${id}`, query);
88
+ }
89
+
90
+ boardCreate(query: Query) {
91
+ return this.post("/boards", query);
92
+ }
93
+
94
+ boardUpdate(id: string, query: Query) {
95
+ return this.put(`/boards/${id}`, query);
96
+ }
97
+
98
+ /** Close (archive) a board — reversible in Trello UI. */
99
+ boardArchive(id: string) {
100
+ return this.put(`/boards/${id}/closed`, { value: true });
101
+ }
102
+
103
+ /** Permanently delete a board. Irreversible. */
104
+ boardDelete(id: string) {
105
+ return this.delete(`/boards/${id}`);
106
+ }
107
+
108
+ boardLists(id: string, query: Query = {}) {
109
+ return this.get(`/boards/${id}/lists`, query);
110
+ }
111
+
112
+ boardCards(id: string, query: Query = {}) {
113
+ return this.get(`/boards/${id}/cards`, query);
114
+ }
115
+
116
+ boardLabels(id: string, query: Query = {}) {
117
+ return this.get(`/boards/${id}/labels`, query);
118
+ }
119
+
120
+ boardMembers(id: string, query: Query = {}) {
121
+ return this.get(`/boards/${id}/members`, query);
122
+ }
123
+
124
+ boardActions(id: string, query: Query = {}) {
125
+ return this.get(`/boards/${id}/actions`, query);
126
+ }
127
+
128
+ boardCustomFields(id: string) {
129
+ return this.get(`/boards/${id}/customFields`);
130
+ }
131
+
132
+ listGet(id: string, query: Query = {}) {
133
+ return this.get(`/lists/${id}`, query);
134
+ }
135
+
136
+ listCreate(query: Query) {
137
+ return this.post("/lists", query);
138
+ }
139
+
140
+ listUpdate(id: string, query: Query) {
141
+ return this.put(`/lists/${id}`, query);
142
+ }
143
+
144
+ listArchive(id: string) {
145
+ return this.put(`/lists/${id}/closed`, { value: true });
146
+ }
147
+
148
+ listCards(id: string, query: Query = {}) {
149
+ return this.get(`/lists/${id}/cards`, query);
150
+ }
151
+
152
+ cardGet(id: string, query: Query = {}) {
153
+ return this.get(`/cards/${id}`, query);
154
+ }
155
+
156
+ cardCreate(query: Query) {
157
+ return this.post("/cards", query);
158
+ }
159
+
160
+ cardUpdate(id: string, query: Query) {
161
+ return this.put(`/cards/${id}`, query);
162
+ }
163
+
164
+ /** Close (archive) a card — reversible in Trello UI. */
165
+ cardArchive(id: string) {
166
+ return this.put(`/cards/${id}/closed`, { value: true });
167
+ }
168
+
169
+ /** Permanently delete a card. Irreversible. */
170
+ cardDelete(id: string) {
171
+ return this.delete(`/cards/${id}`);
172
+ }
173
+
174
+ cardComment(id: string, text: string) {
175
+ return this.post(`/cards/${id}/actions/comments`, { text });
176
+ }
177
+
178
+ cardMembers(id: string, query: Query = {}) {
179
+ return this.get(`/cards/${id}/members`, query);
180
+ }
181
+
182
+ cardAddMember(id: string, memberId: string) {
183
+ return this.post(`/cards/${id}/idMembers`, { value: memberId });
184
+ }
185
+
186
+ cardRemoveMember(id: string, memberId: string) {
187
+ return this.delete(`/cards/${id}/idMembers/${memberId}`);
188
+ }
189
+
190
+ cardLabels(id: string) {
191
+ return this.get(`/cards/${id}/labels`);
192
+ }
193
+
194
+ cardAddLabel(id: string, labelId: string) {
195
+ return this.post(`/cards/${id}/idLabels`, { value: labelId });
196
+ }
197
+
198
+ cardRemoveLabel(id: string, labelId: string) {
199
+ return this.delete(`/cards/${id}/idLabels/${labelId}`);
200
+ }
201
+
202
+ cardActions(id: string, query: Query = {}) {
203
+ return this.get(`/cards/${id}/actions`, query);
204
+ }
205
+
206
+ cardComments(id: string, query: Query = {}) {
207
+ return this.get(`/cards/${id}/actions`, {
208
+ filter: "commentCard",
209
+ ...query,
210
+ });
211
+ }
212
+
213
+ cardAttachments(id: string) {
214
+ return this.get(`/cards/${id}/attachments`);
215
+ }
216
+
217
+ cardAddAttachment(id: string, query: Query) {
218
+ return this.post(`/cards/${id}/attachments`, query);
219
+ }
220
+
221
+ cardCustomFieldItems(id: string) {
222
+ return this.get(`/cards/${id}/customFieldItems`);
223
+ }
224
+
225
+ checklistGet(id: string, query: Query = {}) {
226
+ return this.get(`/checklists/${id}`, query);
227
+ }
228
+
229
+ checklistCreate(query: Query) {
230
+ return this.post("/checklists", query);
231
+ }
232
+
233
+ checklistUpdate(id: string, query: Query) {
234
+ return this.put(`/checklists/${id}`, query);
235
+ }
236
+
237
+ checklistDelete(id: string) {
238
+ return this.delete(`/checklists/${id}`);
239
+ }
240
+
241
+ checklistAddItem(id: string, query: Query) {
242
+ return this.post(`/checklists/${id}/checkItems`, query);
243
+ }
244
+
245
+ checklistUpdateItem(checklistId: string, itemId: string, query: Query) {
246
+ return this.put(`/checklists/${checklistId}/checkItems/${itemId}`, query);
247
+ }
248
+
249
+ checklistDeleteItem(checklistId: string, itemId: string) {
250
+ return this.delete(`/checklists/${checklistId}/checkItems/${itemId}`);
251
+ }
252
+
253
+ labelGet(id: string, query: Query = {}) {
254
+ return this.get(`/labels/${id}`, query);
255
+ }
256
+
257
+ labelCreate(query: Query) {
258
+ return this.post("/labels", query);
259
+ }
260
+
261
+ labelUpdate(id: string, query: Query) {
262
+ return this.put(`/labels/${id}`, query);
263
+ }
264
+
265
+ labelDelete(id: string) {
266
+ return this.delete(`/labels/${id}`);
267
+ }
268
+
269
+ customFieldGet(id: string) {
270
+ return this.get(`/customFields/${id}`);
271
+ }
272
+
273
+ customFieldCreate(query: Query) {
274
+ return this.post("/customFields", query);
275
+ }
276
+
277
+ customFieldUpdate(id: string, query: Query) {
278
+ return this.put(`/customFields/${id}`, query);
279
+ }
280
+
281
+ customFieldDelete(id: string) {
282
+ return this.delete(`/customFields/${id}`);
283
+ }
284
+
285
+ customFieldUpdateItem(id: string, query: Query, body?: JsonValue) {
286
+ return this.put(`/customFields/${id}/item`, query, body);
287
+ }
288
+
289
+ actionGet(id: string, query: Query = {}) {
290
+ return this.get(`/actions/${id}`, query);
291
+ }
292
+
293
+ search(query: string, opts: Query = {}) {
294
+ return this.get("/search", { query, ...opts });
295
+ }
296
+
297
+ webhooksForToken() {
298
+ return this.get("/tokens/me/webhooks");
299
+ }
300
+
301
+ webhookCreate(query: Query) {
302
+ return this.post("/webhooks", query);
303
+ }
304
+
305
+ webhookGet(id: string) {
306
+ return this.get(`/webhooks/${id}`);
307
+ }
308
+
309
+ webhookDelete(id: string) {
310
+ return this.delete(`/webhooks/${id}`);
311
+ }
312
+
313
+ orgGet(id: string, query: Query = {}) {
314
+ return this.get(`/organizations/${id}`, query);
315
+ }
316
+
317
+ orgBoards(id: string, query: Query = {}) {
318
+ return this.get(`/organizations/${id}/boards`, query);
319
+ }
320
+
321
+ batch(urls: string[]) {
322
+ return this.get("/batch", { urls: urls.join(",") });
323
+ }
324
+ }
325
+
326
+ export function createClient(
327
+ apiKey: string,
328
+ token: string,
329
+ requestOptions?: RequestOptions,
330
+ ): TrelloClient {
331
+ return new TrelloClient(apiKey, token, requestOptions);
332
+ }