@jordancoin/notioncli 1.0.0 → 1.2.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 +244 -58
- package/bin/notion.js +771 -43
- package/lib/helpers.js +52 -6
- package/package.json +1 -1
- package/skill/SKILL.md +100 -2
- package/skill/marketplace.json +16 -0
- package/test/debug-parent.js +32 -0
- package/test/live-relations-test.js +309 -0
- package/test/mock.test.js +39 -18
- package/test/unit.test.js +45 -6
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
|
|
9
|
-
A powerful CLI for the Notion API —
|
|
9
|
+
A powerful CLI for the Notion API — aliases, zero UUIDs, relations & rollups, and full block-level CRUD. Built for humans and AI agents.
|
|
10
10
|
|
|
11
11
|
**No more copy-pasting UUIDs.** Set up aliases once, then just type `notion query tasks` or `notion add projects --prop "Name=Ship it"`.
|
|
12
12
|
|
|
@@ -34,6 +34,51 @@ Zero UUIDs. One command. You're ready to go.
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
+
## What's New
|
|
38
|
+
|
|
39
|
+
### v1.2 — Multi-Workspace, Database Management & File Uploads
|
|
40
|
+
|
|
41
|
+
- 🏢 **Multi-workspace** — Named profiles for multiple Notion accounts (`workspace add/use/list/remove`, `--workspace` flag)
|
|
42
|
+
- 🤖 **`me`** — Show integration/bot identity and owner
|
|
43
|
+
- 📦 **`move`** — Move pages between databases by alias
|
|
44
|
+
- 📋 **`templates`** — List page templates available for a database
|
|
45
|
+
- 🏗️ **`db-create`** — Create new databases with custom property schemas
|
|
46
|
+
- ✏️ **`db-update`** — Add/remove columns, rename databases
|
|
47
|
+
- 📎 **`upload`** — Upload files to pages (MIME-aware, supports images/docs/text)
|
|
48
|
+
- 🔍 **`props`** — Quick page property inspector (cleaner than `get` for debugging)
|
|
49
|
+
- 🐛 **Fixed** canonical `database_id` resolution for the 2025 dual-ID system
|
|
50
|
+
|
|
51
|
+
### v1.1 — Relations, Rollups & Blocks
|
|
52
|
+
|
|
53
|
+
- 🔗 **Relations** — `get` resolves linked page titles automatically. New `notion relations` command for exploring connected pages.
|
|
54
|
+
- 📊 **Rollups** — Numbers, dates, and arrays are parsed into readable values. No more raw JSON blobs.
|
|
55
|
+
- 🧱 **Blocks CRUD** — Edit and delete blocks directly with `block-edit` and `block-delete`. Use `--ids` flag on `blocks` for precise targeting.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Notion as a Graph
|
|
60
|
+
|
|
61
|
+
Notion databases don't live in isolation — they're connected by relations and rollups. notioncli treats your workspace as a **graph of linked pages**:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
$ notion get tasks --filter "Name=Ship v1.1"
|
|
65
|
+
Properties:
|
|
66
|
+
Name: Ship v1.1
|
|
67
|
+
Status: Active
|
|
68
|
+
Project: Launch CLI ← relation resolved to title
|
|
69
|
+
Task Count: 3 ← rollup parsed to number
|
|
70
|
+
|
|
71
|
+
$ notion relations tasks --filter "Name=Ship v1.1"
|
|
72
|
+
Project: 1 linked page
|
|
73
|
+
id │ title │ url
|
|
74
|
+
──────────┼────────────┼──────────────────────
|
|
75
|
+
302903e2… │ Launch CLI │ https://notion.so/...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Relations resolve to human-readable titles. Rollups return real values. Blocks can be queried, edited, and deleted directly. This makes it possible to explore, automate, and reason about complex workspaces entirely from the CLI.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
37
82
|
## Setup
|
|
38
83
|
|
|
39
84
|
### 1. Create a Notion Integration
|
|
@@ -90,7 +135,7 @@ notion alias rename reading-list reads
|
|
|
90
135
|
|
|
91
136
|
### `notion query` — Query a Database
|
|
92
137
|
|
|
93
|
-
The command you'll use most. Filter, sort, and browse your data
|
|
138
|
+
The command you'll use most. Filter, sort, and browse your data. Rollups are automatically parsed into numbers, dates, or arrays instead of raw JSON.
|
|
94
139
|
|
|
95
140
|
```
|
|
96
141
|
$ notion query projects
|
|
@@ -107,12 +152,6 @@ With filters and sorting:
|
|
|
107
152
|
|
|
108
153
|
```
|
|
109
154
|
$ notion query projects --filter Status=Active --sort Date:desc --limit 5
|
|
110
|
-
Date │ Name │ Status │ Priority
|
|
111
|
-
───────────┼───────────────┼────────┼─────────
|
|
112
|
-
2026-02-09 │ Launch CLI │ Active │ High
|
|
113
|
-
2026-02-08 │ Write Docs │ Active │ Medium
|
|
114
|
-
|
|
115
|
-
2 results
|
|
116
155
|
```
|
|
117
156
|
|
|
118
157
|
### `notion add` — Add a Page
|
|
@@ -143,52 +182,70 @@ $ notion update workouts --filter "Name=LEGS #5" --prop "Notes=Great session"
|
|
|
143
182
|
|
|
144
183
|
### `notion delete` — Delete (Archive) a Page
|
|
145
184
|
|
|
146
|
-
By page ID:
|
|
147
|
-
```
|
|
148
|
-
$ notion delete a1b2c3d4-5678-90ab-cdef-1234567890ab
|
|
149
|
-
🗑️ Archived page: a1b2c3d4-...
|
|
150
|
-
(Restore it from the trash in Notion if needed)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
By alias + filter:
|
|
154
185
|
```
|
|
155
186
|
$ notion delete workouts --filter "Date=2026-02-09"
|
|
156
187
|
🗑️ Archived page: a1b2c3d4-...
|
|
188
|
+
(Restore it from the trash in Notion if needed)
|
|
157
189
|
```
|
|
158
190
|
|
|
159
191
|
### `notion get` — View Page Details
|
|
160
192
|
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
$ notion get a1b2c3d4-5678-90ab-cdef-1234567890ab
|
|
164
|
-
```
|
|
193
|
+
Relations are **automatically resolved** to linked page titles:
|
|
165
194
|
|
|
166
|
-
By alias + filter:
|
|
167
195
|
```
|
|
168
|
-
$ notion get
|
|
196
|
+
$ notion get tasks --filter "Name=Implement relations"
|
|
169
197
|
Page: a1b2c3d4-5678-90ab-cdef-1234567890ab
|
|
170
|
-
URL: https://www.notion.so
|
|
198
|
+
URL: https://www.notion.so/...
|
|
171
199
|
Created: 2026-02-10T14:30:00.000Z
|
|
172
200
|
Updated: 2026-02-10T14:30:00.000Z
|
|
173
201
|
|
|
174
202
|
Properties:
|
|
175
|
-
Name:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
203
|
+
Name: Implement relations
|
|
204
|
+
Project: Build CLI ← resolved title, not a UUID
|
|
205
|
+
Done: ✓
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### `notion relations` — Explore Connections
|
|
209
|
+
|
|
210
|
+
See what a page is linked to, with resolved titles and URLs:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
$ notion relations tasks --filter "Name=Implement relations"
|
|
214
|
+
Project: 1 linked page
|
|
215
|
+
id │ title │ url
|
|
216
|
+
──────────┼───────────┼──────────────────────
|
|
217
|
+
302903e2… │ Build CLI │ https://notion.so/...
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `notion blocks` — View & Edit Page Content
|
|
221
|
+
|
|
222
|
+
View blocks with optional IDs for targeting:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
$ notion blocks tasks --filter "Name=Ship v1.1" --ids
|
|
226
|
+
[a1b2c3d4] # Project Overview
|
|
227
|
+
[e5f67890] This is the main project page.
|
|
228
|
+
[abcd1234] • First task
|
|
229
|
+
[efgh5678] ☑ Completed item
|
|
179
230
|
```
|
|
180
231
|
|
|
181
|
-
|
|
232
|
+
In v1.1+, blocks are fully editable and deletable — not just readable:
|
|
182
233
|
|
|
183
|
-
By page ID or alias + filter:
|
|
184
234
|
```
|
|
185
|
-
$ notion
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
235
|
+
$ notion block-edit a1b2c3d4-5678-90ab-cdef-1234567890ab "Updated heading text"
|
|
236
|
+
✅ Updated heading_1 block: a1b2c3d4…
|
|
237
|
+
|
|
238
|
+
$ notion block-delete a1b2c3d4-5678-90ab-cdef-1234567890ab
|
|
239
|
+
🗑️ Deleted block: a1b2c3d4…
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Use `notion blocks --ids` to list block IDs for precise edits.
|
|
243
|
+
|
|
244
|
+
### `notion append` — Add Content to a Page
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
$ notion append tasks "Status update: phase 1 complete" --filter "Name=Ship feature"
|
|
248
|
+
✅ Appended text block to page a1b2c3d4-...
|
|
192
249
|
```
|
|
193
250
|
|
|
194
251
|
### `notion dbs` — List All Databases
|
|
@@ -207,44 +264,164 @@ f9e8d7c6-b5a4-3210-fedc-ba0987654321 │ Reading List │ https://...
|
|
|
207
264
|
|
|
208
265
|
```
|
|
209
266
|
$ notion search "meeting"
|
|
210
|
-
|
|
211
|
-
─────────────────────────────────────┼─────────────┼────────────────┼──────────────
|
|
212
|
-
a1b2c3d4-e5f6-7890-abcd-ef1234567890 │ page │ Meeting Notes │ https://...
|
|
213
|
-
f9e8d7c6-b5a4-3210-fedc-ba0987654321 │ data_source │ Meetings DB │ https://...
|
|
267
|
+
```
|
|
214
268
|
|
|
215
|
-
|
|
269
|
+
### `notion users` / `notion user <id>` — Workspace Users
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
$ notion users
|
|
216
273
|
```
|
|
217
274
|
|
|
275
|
+
### `notion comments` / `notion comment` — Page Comments
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
$ notion comments tasks --filter "Name=Ship feature"
|
|
279
|
+
$ notion comment tasks "Shipped! 🚀" --filter "Name=Ship feature"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### `notion me` — Integration Identity
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
$ notion me
|
|
286
|
+
Bot: Stargazer
|
|
287
|
+
ID: 8fd93059-5e54-44a5-8efd-800069da9497
|
|
288
|
+
Type: bot
|
|
289
|
+
Owner: Workspace
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### `notion props` — Quick Property Inspector
|
|
293
|
+
|
|
294
|
+
A fast way to inspect a single page's properties:
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
$ notion props tasks --filter "Name=Ship v1.1"
|
|
298
|
+
Page: a1b2c3d4-5678-90ab-cdef-1234567890ab
|
|
299
|
+
URL: https://www.notion.so/...
|
|
300
|
+
Name: Ship v1.1
|
|
301
|
+
Status: Done
|
|
302
|
+
Priority: High
|
|
303
|
+
Date: 2026-02-09
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### `notion move` — Move Pages Between Databases
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
$ notion move tasks --filter "Name=Archived task" --to archive
|
|
310
|
+
✅ Moved page: a1b2c3d4…
|
|
311
|
+
URL: https://notion.so/...
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Accepts alias + filter for the source page, and an alias or page ID for `--to`.
|
|
315
|
+
|
|
316
|
+
### `notion templates` — List Database Templates
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
$ notion templates projects
|
|
320
|
+
id │ title │ url
|
|
321
|
+
──────────┼────────────────────┼──────────────────
|
|
322
|
+
a1b2c3d4… │ Project Template │ https://notion.so/...
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### `notion db-create` — Create a Database
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
$ notion db-create <parent-page-id> "My New DB" --prop "Name:title" --prop "Status:select" --prop "Priority:number"
|
|
329
|
+
✅ Created database: a1b2c3d4…
|
|
330
|
+
Title: My New DB
|
|
331
|
+
Properties: Name, Status, Priority
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### `notion db-update` — Update Database Schema
|
|
335
|
+
|
|
336
|
+
Add or remove columns, rename databases:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
$ notion db-update projects --add-prop "Rating:number" --add-prop "Category:select"
|
|
340
|
+
✅ Updated database: a1b2c3d4…
|
|
341
|
+
Added: Rating:number, Category:select
|
|
342
|
+
|
|
343
|
+
$ notion db-update projects --remove-prop "Old Column"
|
|
344
|
+
✅ Updated database: a1b2c3d4…
|
|
345
|
+
Removed: Old Column
|
|
346
|
+
|
|
347
|
+
$ notion db-update projects --title "Renamed Projects"
|
|
348
|
+
✅ Updated database: a1b2c3d4…
|
|
349
|
+
Title: Renamed Projects
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### `notion upload` — Upload Files to Pages
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
$ notion upload tasks --filter "Name=Ship feature" ./screenshot.png
|
|
356
|
+
✅ Uploaded: screenshot.png (142.3 KB)
|
|
357
|
+
Page: a1b2c3d4…
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Supports images, PDFs, text files, documents, and more. MIME types are detected automatically from file extensions.
|
|
361
|
+
|
|
218
362
|
### `notion alias` — Manage Aliases
|
|
219
363
|
|
|
220
364
|
Aliases are created automatically by `notion init`, but you can manage them:
|
|
221
365
|
|
|
222
366
|
```bash
|
|
223
|
-
# See
|
|
224
|
-
notion alias
|
|
367
|
+
notion alias list # See all aliases
|
|
368
|
+
notion alias rename project-tracker projects # Rename one
|
|
369
|
+
notion alias add tasks <database-id> # Add manually
|
|
370
|
+
notion alias remove tasks # Remove one
|
|
371
|
+
```
|
|
225
372
|
|
|
226
|
-
|
|
227
|
-
|
|
373
|
+
### `notion workspace` — Multi-Workspace Profiles
|
|
374
|
+
|
|
375
|
+
Manage multiple Notion accounts (work, personal, client projects):
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Add a workspace
|
|
379
|
+
notion workspace add work --key ntn_your_work_key
|
|
380
|
+
notion workspace add personal --key ntn_your_personal_key
|
|
381
|
+
|
|
382
|
+
# List workspaces
|
|
383
|
+
notion workspace list
|
|
384
|
+
# default ← active
|
|
385
|
+
# Key: ntn_3871... | Aliases: 5
|
|
386
|
+
# work
|
|
387
|
+
# Key: ntn_ab12... | Aliases: 0
|
|
388
|
+
|
|
389
|
+
# Switch active workspace
|
|
390
|
+
notion workspace use work
|
|
228
391
|
|
|
229
|
-
#
|
|
230
|
-
notion
|
|
392
|
+
# Discover databases for a workspace
|
|
393
|
+
notion init --workspace work
|
|
231
394
|
|
|
232
|
-
#
|
|
233
|
-
notion
|
|
395
|
+
# Per-command override (no switching needed)
|
|
396
|
+
notion query tasks --workspace personal
|
|
397
|
+
notion -w work add projects --prop "Name=Q2 Plan"
|
|
398
|
+
|
|
399
|
+
# Remove a workspace
|
|
400
|
+
notion workspace remove old-client
|
|
234
401
|
```
|
|
235
402
|
|
|
403
|
+
Aliases are scoped per workspace — same alias name in different workspaces won't collide. Old single-key configs are auto-migrated to a "default" workspace.
|
|
404
|
+
|
|
236
405
|
### `--json` — Raw JSON Output
|
|
237
406
|
|
|
238
407
|
Add `--json` to any command for the raw Notion API response:
|
|
239
408
|
|
|
240
409
|
```bash
|
|
241
410
|
notion --json query projects --limit 1
|
|
242
|
-
notion --json
|
|
243
|
-
notion --json get a1b2c3d4-...
|
|
411
|
+
notion --json get tasks --filter "Name=Ship it"
|
|
244
412
|
```
|
|
245
413
|
|
|
246
414
|
Great for piping into `jq` or other tools.
|
|
247
415
|
|
|
416
|
+
### `--output` — Output Formats
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
notion query tasks --output csv # CSV
|
|
420
|
+
notion query tasks --output yaml # YAML
|
|
421
|
+
notion query tasks --output json # JSON
|
|
422
|
+
notion query tasks --output table # Default
|
|
423
|
+
```
|
|
424
|
+
|
|
248
425
|
---
|
|
249
426
|
|
|
250
427
|
## Use It With AI Agents
|
|
@@ -263,17 +440,20 @@ notion query tasks --filter Status=Todo --sort Priority:desc
|
|
|
263
440
|
notion add tasks --prop "Name=Fix bug #42" --prop "Status=In Progress"
|
|
264
441
|
notion update tasks --filter "Name=Fix bug #42" --prop "Status=Done"
|
|
265
442
|
|
|
266
|
-
#
|
|
267
|
-
notion
|
|
268
|
-
|
|
443
|
+
# Explore relations between databases
|
|
444
|
+
notion relations tasks --filter "Name=Fix bug #42"
|
|
445
|
+
|
|
446
|
+
# View and edit page content
|
|
447
|
+
notion blocks tasks --filter "Name=Fix bug #42" --ids
|
|
448
|
+
notion block-edit <block-id> "Updated content"
|
|
269
449
|
notion append tasks "Deployed to production" --filter "Name=Fix bug #42"
|
|
270
450
|
|
|
451
|
+
# Comment and collaborate
|
|
452
|
+
notion comment tasks "Shipped! 🚀" --filter "Name=Fix bug #42"
|
|
453
|
+
|
|
271
454
|
# Delete by alias + filter
|
|
272
455
|
notion delete tasks --filter "Name=Fix bug #42"
|
|
273
456
|
|
|
274
|
-
# Or use raw page IDs if you already have them
|
|
275
|
-
notion update <page-id> --prop "Status=Done"
|
|
276
|
-
|
|
277
457
|
# Get raw JSON for parsing
|
|
278
458
|
notion --json query projects --limit 10
|
|
279
459
|
```
|
|
@@ -282,7 +462,7 @@ No API key management, no curl commands, no JSON formatting — just simple shel
|
|
|
282
462
|
|
|
283
463
|
### Zero-UUID Workflow
|
|
284
464
|
|
|
285
|
-
Every page-targeted command (`update`, `delete`, `get`, `blocks`, `comments`, `comment`, `append`)
|
|
465
|
+
Every page-targeted command (`update`, `delete`, `get`, `blocks`, `relations`, `comments`, `comment`, `append`, `block-edit`, `block-delete`) accepts a **database alias + `--filter`** as an alternative to a raw page ID:
|
|
286
466
|
|
|
287
467
|
```bash
|
|
288
468
|
# Instead of: notion update a1b2c3d4-5678-90ab-cdef-1234567890ab --prop "Status=Done"
|
|
@@ -324,6 +504,12 @@ The latest Notion API introduced a dual-ID system for databases. Each database n
|
|
|
324
504
|
|
|
325
505
|
You don't need to think about this. It just works.
|
|
326
506
|
|
|
507
|
+
### Reliability
|
|
508
|
+
|
|
509
|
+
- 139 unit tests
|
|
510
|
+
- Tested against live Notion workspaces
|
|
511
|
+
- Designed to fail loudly and safely when filters match zero or multiple pages
|
|
512
|
+
|
|
327
513
|
### Built on the Official SDK
|
|
328
514
|
|
|
329
515
|
notioncli uses [`@notionhq/client`](https://github.com/makenotion/notion-sdk-js) v5.x, Notion's official JavaScript SDK.
|