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.
- package/README.md +191 -0
- package/bin/run-ts +31 -0
- package/bin/trelly +2 -0
- package/bin/trelly-mcp +2 -0
- package/package.json +64 -0
- package/src/api/client.ts +332 -0
- package/src/api/http.ts +86 -0
- package/src/auth/browser-flow.ts +217 -0
- package/src/auth/profiles.ts +163 -0
- package/src/cli/commands/actions.ts +17 -0
- package/src/cli/commands/api.ts +46 -0
- package/src/cli/commands/auth.ts +248 -0
- package/src/cli/commands/boards.ts +152 -0
- package/src/cli/commands/cards.ts +194 -0
- package/src/cli/commands/checklists.ts +79 -0
- package/src/cli/commands/custom-fields.ts +75 -0
- package/src/cli/commands/labels.ts +47 -0
- package/src/cli/commands/lists.ts +54 -0
- package/src/cli/commands/members.ts +14 -0
- package/src/cli/commands/orgs.ts +23 -0
- package/src/cli/commands/run.ts +32 -0
- package/src/cli/commands/search.ts +23 -0
- package/src/cli/commands/ui.ts +48 -0
- package/src/cli/commands/webhooks.ts +44 -0
- package/src/cli/context.ts +70 -0
- package/src/cli/index.ts +47 -0
- package/src/cli/ui/app.tsx +753 -0
- package/src/cli/ui/custom-fields.ts +75 -0
- package/src/cli/ui/palette.ts +69 -0
- package/src/cli/ui/shapes.ts +68 -0
- package/src/cli/ui/static.tsx +382 -0
- package/src/index.test.ts +117 -0
- package/src/mcp/handlers.ts +61 -0
- package/src/mcp/server.ts +17 -0
- package/src/mcp/tools/api.ts +27 -0
- package/src/mcp/tools/boards.ts +116 -0
- package/src/mcp/tools/cards.ts +138 -0
- package/src/mcp/tools/checklists.ts +40 -0
- package/src/mcp/tools/index.ts +22 -0
- package/src/mcp/tools/labels.ts +40 -0
- package/src/mcp/tools/lists.ts +37 -0
- package/src/mcp/tools/profiles.ts +40 -0
- package/src/mcp/tools/search.ts +31 -0
- package/src/mcp/tools/webhooks.ts +52 -0
- package/src/util/runtime.ts +39 -0
- 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
|
+

|
|
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
package/bin/trelly-mcp
ADDED
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
|
+
}
|