@andrzejchm/notion-cli 0.9.1 → 0.11.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/{docs → .agents}/skills/using-notion-cli/SKILL.md +41 -11
- package/README.md +2 -0
- package/dist/cli.js +214 -26
- package/dist/cli.js.map +1 -1
- package/docs/FEATURE-PARITY.md +4 -5
- package/docs/README.agents.md +15 -1
- package/package.json +2 -1
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-notion-cli
|
|
3
|
-
description:
|
|
3
|
+
description: Use when reading or writing Notion pages, searching a Notion workspace, querying or creating Notion databases, appending or editing page content, creating pages, updating page properties, moving pages, adding comments, or archiving pages — via the `notion` CLI tool in the terminal.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
## Overview - skill version 0.11.0
|
|
7
|
+
|
|
8
|
+
`notion` is a CLI tool for reading and writing Notion content from the terminal or agent workflows. Use it any time you need to interact with Notion: read pages, search, query databases, append or edit content, create pages, update properties, move pages, post comments, or archive pages.
|
|
9
|
+
|
|
10
|
+
> **Version check:** Run `notion --version`. If your installed version is older than 0.11.0, update with `npm install -g @andrzejchm/notion-cli` and refresh this skill with `notion skill`.
|
|
11
|
+
|
|
6
12
|
## Setup
|
|
7
13
|
|
|
8
14
|
Install once:
|
|
15
|
+
|
|
9
16
|
```bash
|
|
10
17
|
npm install -g @andrzejchm/notion-cli
|
|
11
18
|
notion auth login # interactive setup — choose OAuth or integration token
|
|
12
19
|
```
|
|
13
20
|
|
|
14
21
|
Or set env var (preferred for CI/agents):
|
|
22
|
+
|
|
15
23
|
```bash
|
|
16
24
|
export NOTION_API_TOKEN=ntn_your_token_here
|
|
17
25
|
```
|
|
@@ -21,6 +29,7 @@ Get token: https://www.notion.so/profile/integrations/internal
|
|
|
21
29
|
Pages must be shared with your integration: open page → `⋯` → **Add connections**.
|
|
22
30
|
|
|
23
31
|
**Integration capabilities** (set at notion.so/profile/integrations/internal → your integration → Capabilities):
|
|
32
|
+
|
|
24
33
|
- Read-only commands: **Read content** only
|
|
25
34
|
- `notion append`, `notion append --after`, `notion create-page` (page parent): also need **Insert content**
|
|
26
35
|
- `notion create-page --parent <db>`: also need **Insert content** + database must be shared with integration
|
|
@@ -33,11 +42,11 @@ Pages must be shared with your integration: open page → `⋯` → **Add connec
|
|
|
33
42
|
|
|
34
43
|
Two auth methods are available. If both are configured, **OAuth takes precedence**.
|
|
35
44
|
|
|
36
|
-
| Method
|
|
37
|
-
|
|
38
|
-
| Interactive setup | `notion auth login`
|
|
39
|
-
| OAuth user login
|
|
40
|
-
| Integration token | select "Integration token" in `notion auth login` | Integration bot
|
|
45
|
+
| Method | Command | Attribution | Notes |
|
|
46
|
+
| ----------------- | ------------------------------------------------- | ------------------- | ------------------------------------------------------- |
|
|
47
|
+
| Interactive setup | `notion auth login` | — | Guides you to choose; TTY required |
|
|
48
|
+
| OAuth user login | select "OAuth user login" in `notion auth login` | Your Notion account | Browser required; `--manual` for headless |
|
|
49
|
+
| Integration token | select "Integration token" in `notion auth login` | Integration bot | Works in CI/headless; must connect integration to pages |
|
|
41
50
|
|
|
42
51
|
```bash
|
|
43
52
|
notion auth login # interactive selector — OAuth or integration token
|
|
@@ -47,6 +56,7 @@ notion auth logout # remove a profile (interactive selector)
|
|
|
47
56
|
notion auth logout --profile <name> # remove specific profile directly
|
|
48
57
|
notion auth list # list all saved profiles
|
|
49
58
|
notion auth use <name> # switch active profile
|
|
59
|
+
notion --profile <name> <command> # use a specific profile for one command
|
|
50
60
|
```
|
|
51
61
|
|
|
52
62
|
**Headless/CI agents:** Use `NOTION_API_TOKEN=<token>` env var — overrides all config, no TTY needed.
|
|
@@ -55,14 +65,15 @@ notion auth use <name> # switch active profile
|
|
|
55
65
|
|
|
56
66
|
## Output Modes
|
|
57
67
|
|
|
58
|
-
| Context
|
|
59
|
-
|
|
60
|
-
| Terminal (TTY) | Formatted tables
|
|
61
|
-
| Piped / agent
|
|
68
|
+
| Context | Default | Override |
|
|
69
|
+
| -------------- | ----------------- | -------- |
|
|
70
|
+
| Terminal (TTY) | Formatted tables | `--json` |
|
|
71
|
+
| Piped / agent | Plain text tables | `--json` |
|
|
62
72
|
|
|
63
73
|
`notion read` always outputs **markdown** — in terminal and when piped.
|
|
64
74
|
|
|
65
75
|
Pipe any command to get JSON:
|
|
76
|
+
|
|
66
77
|
```bash
|
|
67
78
|
notion search "query" | jq '.[0].id'
|
|
68
79
|
notion ls | jq '.[] | select(.type == "database")'
|
|
@@ -78,7 +89,9 @@ notion ls | jq '.[] | select(.type == "database")'
|
|
|
78
89
|
notion search "query" # search all pages/databases by title
|
|
79
90
|
notion search "query" --type page # pages only
|
|
80
91
|
notion search "query" --type database # databases only
|
|
92
|
+
notion search "query" --sort asc # sort by last edited time (asc or desc)
|
|
81
93
|
notion ls # list everything accessible to integration
|
|
94
|
+
notion ls --sort desc # sort by last edited time
|
|
82
95
|
notion users # list workspace members
|
|
83
96
|
notion comments <id|url> # list page comments
|
|
84
97
|
notion open <id|url> # open in browser
|
|
@@ -100,6 +113,8 @@ notion db query <id|url> --filter "Status=Done" # filter (repeatable)
|
|
|
100
113
|
notion db query <id|url> --sort "Created:desc" # sort (repeatable)
|
|
101
114
|
notion db query <id|url> --columns "Title,Status" # limit columns
|
|
102
115
|
notion db query <id|url> --json | jq '.[] | .properties'
|
|
116
|
+
|
|
117
|
+
notion db create --parent <page-id|url> --title "My Database" # create a new database
|
|
103
118
|
```
|
|
104
119
|
|
|
105
120
|
### Write Operations
|
|
@@ -123,7 +138,14 @@ notion create-page --parent <id|url> --title "Page" --cover "https://example.com
|
|
|
123
138
|
|
|
124
139
|
URL=$(notion create-page --parent <id|url> --title "Summary" -m "...") # capture URL
|
|
125
140
|
|
|
126
|
-
notion comment <id|url> -m "Reviewed and approved."
|
|
141
|
+
notion comment <id|url> -m "Reviewed and approved." # add comment to a page
|
|
142
|
+
notion comment <id|url> -m "Reply" --reply-to <discussion-id> # reply to a discussion thread
|
|
143
|
+
notion comment <id|url> -m "Note" --block <block-id> # comment on a specific block
|
|
144
|
+
|
|
145
|
+
notion archive <id|url> # move page to trash
|
|
146
|
+
|
|
147
|
+
notion move <ids|urls...> --to <id|url> # move pages to a new parent page
|
|
148
|
+
notion move <ids|urls...> --to-db <id|url> # move pages to a database parent
|
|
127
149
|
```
|
|
128
150
|
|
|
129
151
|
#### Updating Page Properties
|
|
@@ -174,6 +196,7 @@ notion append <id|url> -m "New content" --after "## Status...end of status"
|
|
|
174
196
|
## ID Formats
|
|
175
197
|
|
|
176
198
|
All commands accept any of:
|
|
199
|
+
|
|
177
200
|
- `abc123def456789012345678901234ab` (32-char hex)
|
|
178
201
|
- `abc123de-f456-7890-1234-5678901234ab` (UUID)
|
|
179
202
|
- `https://www.notion.so/workspace/Page-Title-abc123` (full URL)
|
|
@@ -229,6 +252,13 @@ notion create-page --parent "$DB_ID" --title "Fix login bug" \
|
|
|
229
252
|
# Insert a new sub-section after an existing section
|
|
230
253
|
notion append "$PAGE_ID" -m "## New Sub-section\nContent here" \
|
|
231
254
|
--after "## Existing Section...last line of section"
|
|
255
|
+
|
|
256
|
+
# Move pages to a different parent
|
|
257
|
+
ARCHIVE_ID=$(notion search "Archive" --type page | jq -r '.[0].id')
|
|
258
|
+
notion move "$PAGE_ID" --to "$ARCHIVE_ID"
|
|
259
|
+
|
|
260
|
+
# Move multiple pages into a database
|
|
261
|
+
notion move page1-id page2-id --to-db "$DB_ID"
|
|
232
262
|
```
|
|
233
263
|
|
|
234
264
|
---
|
package/README.md
CHANGED
|
@@ -107,6 +107,8 @@ notion ls
|
|
|
107
107
|
| `notion create-page --parent <id\|url> --title <title>` | Create a new page, prints URL |
|
|
108
108
|
| `notion update <id\|url> --prop "Name=Value"` | Update properties on a page |
|
|
109
109
|
| `notion archive <id\|url>` | Archive (trash) a page |
|
|
110
|
+
| `notion move <ids\|urls...> --to <id\|url>` | Move pages to a new parent page |
|
|
111
|
+
| `notion move <ids\|urls...> --to-db <id\|url>` | Move pages to a database parent |
|
|
110
112
|
| `notion completion bash\|zsh\|fish` | Install shell tab completion |
|
|
111
113
|
|
|
112
114
|
### `notion search` / `notion ls` flags
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { readFileSync } from "fs";
|
|
5
|
-
import { dirname, join as
|
|
4
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
5
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
-
import { Command as
|
|
7
|
+
import { Command as Command26 } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/commands/append.ts
|
|
10
10
|
import { Command } from "commander";
|
|
@@ -1436,7 +1436,7 @@ _notion_completion() {
|
|
|
1436
1436
|
local cur prev words cword
|
|
1437
1437
|
_init_completion || return
|
|
1438
1438
|
|
|
1439
|
-
local commands="init profile completion --help --version --verbose --color"
|
|
1439
|
+
local commands="init profile completion skill --help --version --verbose --color"
|
|
1440
1440
|
local profile_commands="list use remove"
|
|
1441
1441
|
|
|
1442
1442
|
case "$prev" in
|
|
@@ -1469,6 +1469,7 @@ _notion() {
|
|
|
1469
1469
|
'init:authenticate with Notion and save a profile'
|
|
1470
1470
|
'profile:manage authentication profiles'
|
|
1471
1471
|
'completion:output shell completion script'
|
|
1472
|
+
'skill:install the agent skill file'
|
|
1472
1473
|
)
|
|
1473
1474
|
|
|
1474
1475
|
local -a global_opts
|
|
@@ -1520,6 +1521,7 @@ complete -c notion -l color -d 'force color output'
|
|
|
1520
1521
|
complete -c notion -n '__fish_use_subcommand' -a init -d 'authenticate with Notion and save a profile'
|
|
1521
1522
|
complete -c notion -n '__fish_use_subcommand' -a profile -d 'manage authentication profiles'
|
|
1522
1523
|
complete -c notion -n '__fish_use_subcommand' -a completion -d 'output shell completion script'
|
|
1524
|
+
complete -c notion -n '__fish_use_subcommand' -a skill -d 'install the agent skill file'
|
|
1523
1525
|
|
|
1524
1526
|
# profile subcommands
|
|
1525
1527
|
complete -c notion -n '__fish_seen_subcommand_from profile' -a list -d 'list all authentication profiles'
|
|
@@ -2479,13 +2481,71 @@ function lsCommand() {
|
|
|
2479
2481
|
return cmd;
|
|
2480
2482
|
}
|
|
2481
2483
|
|
|
2484
|
+
// src/commands/move.ts
|
|
2485
|
+
import { Command as Command16 } from "commander";
|
|
2486
|
+
function moveCommand() {
|
|
2487
|
+
const cmd = new Command16("move");
|
|
2488
|
+
cmd.description("move pages to a new parent").argument("<ids/urls...>", "Notion page IDs or URLs to move").option("--to <id/url>", "target page parent ID or URL").option(
|
|
2489
|
+
"--to-db <id/url>",
|
|
2490
|
+
"target database parent ID or URL (resolves to data source)"
|
|
2491
|
+
).action(
|
|
2492
|
+
withErrorHandling(async (idsOrUrls, opts) => {
|
|
2493
|
+
if (!opts.to && !opts.toDb) {
|
|
2494
|
+
throw new CliError(
|
|
2495
|
+
ErrorCodes.INVALID_ARG,
|
|
2496
|
+
"No target parent specified.",
|
|
2497
|
+
"Provide --to <page-id> or --to-db <database-id>"
|
|
2498
|
+
);
|
|
2499
|
+
}
|
|
2500
|
+
if (opts.to && opts.toDb) {
|
|
2501
|
+
throw new CliError(
|
|
2502
|
+
ErrorCodes.INVALID_ARG,
|
|
2503
|
+
"Cannot specify both --to and --to-db.",
|
|
2504
|
+
"Provide only one: --to <page-id> or --to-db <database-id>"
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
const { token, source } = await resolveToken();
|
|
2508
|
+
reportTokenSource(source);
|
|
2509
|
+
const client = createNotionClient(token);
|
|
2510
|
+
let parent;
|
|
2511
|
+
if (opts.toDb) {
|
|
2512
|
+
const dsId = await resolveDataSourceId(client, opts.toDb);
|
|
2513
|
+
parent = { type: "data_source_id", data_source_id: dsId };
|
|
2514
|
+
} else if (opts.to) {
|
|
2515
|
+
const targetId = toUuid(parseNotionId(opts.to));
|
|
2516
|
+
parent = { type: "page_id", page_id: targetId };
|
|
2517
|
+
} else {
|
|
2518
|
+
throw new CliError(
|
|
2519
|
+
ErrorCodes.INVALID_ARG,
|
|
2520
|
+
"No target parent specified."
|
|
2521
|
+
);
|
|
2522
|
+
}
|
|
2523
|
+
const results = [];
|
|
2524
|
+
for (const idOrUrl of idsOrUrls) {
|
|
2525
|
+
const uuid = toUuid(parseNotionId(idOrUrl));
|
|
2526
|
+
const result = await client.pages.move({ page_id: uuid, parent });
|
|
2527
|
+
results.push(result);
|
|
2528
|
+
}
|
|
2529
|
+
const mode = getOutputMode();
|
|
2530
|
+
if (mode === "json") {
|
|
2531
|
+
process.stdout.write(`${formatJSON(results)}
|
|
2532
|
+
`);
|
|
2533
|
+
} else {
|
|
2534
|
+
process.stdout.write(`Moved ${results.length} page(s).
|
|
2535
|
+
`);
|
|
2536
|
+
}
|
|
2537
|
+
})
|
|
2538
|
+
);
|
|
2539
|
+
return cmd;
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2482
2542
|
// src/commands/open.ts
|
|
2483
2543
|
import { exec } from "child_process";
|
|
2484
2544
|
import { promisify } from "util";
|
|
2485
|
-
import { Command as
|
|
2545
|
+
import { Command as Command17 } from "commander";
|
|
2486
2546
|
var execAsync = promisify(exec);
|
|
2487
2547
|
function openCommand() {
|
|
2488
|
-
const cmd = new
|
|
2548
|
+
const cmd = new Command17("open");
|
|
2489
2549
|
cmd.description("open a Notion page in the default browser").argument("<id/url>", "Notion page ID or URL").action(
|
|
2490
2550
|
withErrorHandling(async (idOrUrl) => {
|
|
2491
2551
|
const id = parseNotionId(idOrUrl);
|
|
@@ -2501,9 +2561,9 @@ function openCommand() {
|
|
|
2501
2561
|
}
|
|
2502
2562
|
|
|
2503
2563
|
// src/commands/profile/list.ts
|
|
2504
|
-
import { Command as
|
|
2564
|
+
import { Command as Command18 } from "commander";
|
|
2505
2565
|
function profileListCommand() {
|
|
2506
|
-
const cmd = new
|
|
2566
|
+
const cmd = new Command18("list");
|
|
2507
2567
|
cmd.description("list all authentication profiles").action(
|
|
2508
2568
|
withErrorHandling(async () => {
|
|
2509
2569
|
const config = await readGlobalConfig();
|
|
@@ -2532,9 +2592,9 @@ function profileListCommand() {
|
|
|
2532
2592
|
}
|
|
2533
2593
|
|
|
2534
2594
|
// src/commands/profile/remove.ts
|
|
2535
|
-
import { Command as
|
|
2595
|
+
import { Command as Command19 } from "commander";
|
|
2536
2596
|
function profileRemoveCommand() {
|
|
2537
|
-
const cmd = new
|
|
2597
|
+
const cmd = new Command19("remove");
|
|
2538
2598
|
cmd.description("remove an authentication profile").argument("<name>", "profile name to remove").action(
|
|
2539
2599
|
withErrorHandling(async (name) => {
|
|
2540
2600
|
const config = await readGlobalConfig();
|
|
@@ -2560,9 +2620,9 @@ function profileRemoveCommand() {
|
|
|
2560
2620
|
}
|
|
2561
2621
|
|
|
2562
2622
|
// src/commands/profile/use.ts
|
|
2563
|
-
import { Command as
|
|
2623
|
+
import { Command as Command20 } from "commander";
|
|
2564
2624
|
function profileUseCommand() {
|
|
2565
|
-
const cmd = new
|
|
2625
|
+
const cmd = new Command20("use");
|
|
2566
2626
|
cmd.description("switch the active profile").argument("<name>", "profile name to activate").action(
|
|
2567
2627
|
withErrorHandling(async (name) => {
|
|
2568
2628
|
const config = await readGlobalConfig();
|
|
@@ -2585,7 +2645,7 @@ function profileUseCommand() {
|
|
|
2585
2645
|
}
|
|
2586
2646
|
|
|
2587
2647
|
// src/commands/read.ts
|
|
2588
|
-
import { Command as
|
|
2648
|
+
import { Command as Command21 } from "commander";
|
|
2589
2649
|
|
|
2590
2650
|
// src/output/markdown.ts
|
|
2591
2651
|
import { Chalk as Chalk2 } from "chalk";
|
|
@@ -2725,7 +2785,7 @@ async function fetchPageMarkdown(client, pageId) {
|
|
|
2725
2785
|
|
|
2726
2786
|
// src/commands/read.ts
|
|
2727
2787
|
function readCommand() {
|
|
2728
|
-
return new
|
|
2788
|
+
return new Command21("read").description("Read a Notion page as markdown").argument("<id>", "Notion page ID or URL").action(
|
|
2729
2789
|
withErrorHandling(async (id) => {
|
|
2730
2790
|
const { token } = await resolveToken();
|
|
2731
2791
|
const client = createNotionClient(token);
|
|
@@ -2751,7 +2811,7 @@ function readCommand() {
|
|
|
2751
2811
|
|
|
2752
2812
|
// src/commands/search.ts
|
|
2753
2813
|
import { isFullPageOrDataSource as isFullPageOrDataSource2 } from "@notionhq/client";
|
|
2754
|
-
import { Command as
|
|
2814
|
+
import { Command as Command22 } from "commander";
|
|
2755
2815
|
function getTitle2(item) {
|
|
2756
2816
|
if (item.object === "data_source") {
|
|
2757
2817
|
return item.title.map((t) => t.plain_text).join("") || "(untitled)";
|
|
@@ -2771,7 +2831,7 @@ function displayType2(item) {
|
|
|
2771
2831
|
return item.object === "data_source" ? "database" : item.object;
|
|
2772
2832
|
}
|
|
2773
2833
|
function searchCommand() {
|
|
2774
|
-
const cmd = new
|
|
2834
|
+
const cmd = new Command22("search");
|
|
2775
2835
|
cmd.description("search Notion workspace by keyword").argument("<query>", "search keyword").option(
|
|
2776
2836
|
"--type <type>",
|
|
2777
2837
|
"filter by object type (page or database)",
|
|
@@ -2841,14 +2901,140 @@ function searchCommand() {
|
|
|
2841
2901
|
return cmd;
|
|
2842
2902
|
}
|
|
2843
2903
|
|
|
2904
|
+
// src/commands/skill.ts
|
|
2905
|
+
import {
|
|
2906
|
+
copyFileSync,
|
|
2907
|
+
existsSync,
|
|
2908
|
+
mkdirSync,
|
|
2909
|
+
readFileSync,
|
|
2910
|
+
realpathSync
|
|
2911
|
+
} from "fs";
|
|
2912
|
+
import { homedir as homedir2 } from "os";
|
|
2913
|
+
import { dirname, join as join3 } from "path";
|
|
2914
|
+
import chalk from "chalk";
|
|
2915
|
+
import { Command as Command23 } from "commander";
|
|
2916
|
+
function skillPath() {
|
|
2917
|
+
if (!process.argv[1]) {
|
|
2918
|
+
throw new Error("Cannot determine install path. Run with: notion skill");
|
|
2919
|
+
}
|
|
2920
|
+
const entryPoint = realpathSync(process.argv[1]);
|
|
2921
|
+
const packageRoot = dirname(dirname(entryPoint));
|
|
2922
|
+
const candidates = [
|
|
2923
|
+
join3(packageRoot, ".agents", "skills", "using-notion-cli", "SKILL.md"),
|
|
2924
|
+
join3(
|
|
2925
|
+
dirname(entryPoint),
|
|
2926
|
+
"..",
|
|
2927
|
+
".agents",
|
|
2928
|
+
"skills",
|
|
2929
|
+
"using-notion-cli",
|
|
2930
|
+
"SKILL.md"
|
|
2931
|
+
)
|
|
2932
|
+
];
|
|
2933
|
+
for (const c2 of candidates) {
|
|
2934
|
+
if (existsSync(c2)) return c2;
|
|
2935
|
+
}
|
|
2936
|
+
throw new Error(
|
|
2937
|
+
"SKILL.md not found. Reinstall with: npm install -g @andrzejchm/notion-cli"
|
|
2938
|
+
);
|
|
2939
|
+
}
|
|
2940
|
+
function getAgentTargets() {
|
|
2941
|
+
const home = homedir2();
|
|
2942
|
+
const targets = [
|
|
2943
|
+
{
|
|
2944
|
+
name: "Claude Code",
|
|
2945
|
+
dir: join3(home, ".claude", "skills", "using-notion-cli")
|
|
2946
|
+
},
|
|
2947
|
+
{ name: "Codex", dir: join3(home, ".agents", "skills", "using-notion-cli") },
|
|
2948
|
+
{
|
|
2949
|
+
name: "OpenCode",
|
|
2950
|
+
dir: join3(home, ".config", "opencode", "skills", "using-notion-cli")
|
|
2951
|
+
}
|
|
2952
|
+
];
|
|
2953
|
+
return targets.map((t) => ({
|
|
2954
|
+
...t,
|
|
2955
|
+
detected: existsSync(dirname(t.dir))
|
|
2956
|
+
}));
|
|
2957
|
+
}
|
|
2958
|
+
function installTo(source, target) {
|
|
2959
|
+
if (!existsSync(target.dir)) mkdirSync(target.dir, { recursive: true });
|
|
2960
|
+
const dest = join3(target.dir, "SKILL.md");
|
|
2961
|
+
copyFileSync(source, dest);
|
|
2962
|
+
return dest;
|
|
2963
|
+
}
|
|
2964
|
+
async function installInteractive(source, targets) {
|
|
2965
|
+
const { checkbox } = await import("@inquirer/prompts");
|
|
2966
|
+
const selected = await checkbox({
|
|
2967
|
+
message: "Install skill for which agents?",
|
|
2968
|
+
choices: targets.map((t) => ({
|
|
2969
|
+
name: `${t.name}${t.detected ? chalk.dim(" (detected)") : ""}`,
|
|
2970
|
+
value: t.name,
|
|
2971
|
+
checked: t.detected
|
|
2972
|
+
}))
|
|
2973
|
+
});
|
|
2974
|
+
if (selected.length === 0) {
|
|
2975
|
+
process.stderr.write("No agents selected.\n");
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
process.stdout.write("\n");
|
|
2979
|
+
for (const name of selected) {
|
|
2980
|
+
const target = targets.find((t) => t.name === name);
|
|
2981
|
+
if (!target) continue;
|
|
2982
|
+
const dest = installTo(source, target);
|
|
2983
|
+
process.stdout.write(` Installed: ${target.name}: ${dest}
|
|
2984
|
+
`);
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
function installNonInteractive(source, targets) {
|
|
2988
|
+
const detected = targets.filter((t) => t.detected);
|
|
2989
|
+
if (detected.length === 0) {
|
|
2990
|
+
process.stderr.write(
|
|
2991
|
+
"No agents detected. Use --path to specify install location:\n notion skill --path ~/.claude/skills/using-notion-cli/SKILL.md\n"
|
|
2992
|
+
);
|
|
2993
|
+
return;
|
|
2994
|
+
}
|
|
2995
|
+
for (const target of detected) {
|
|
2996
|
+
const dest = installTo(source, target);
|
|
2997
|
+
process.stdout.write(`Installed: ${target.name}: ${dest}
|
|
2998
|
+
`);
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
function skillCommand() {
|
|
3002
|
+
const cmd = new Command23("skill");
|
|
3003
|
+
cmd.description("Install the agent skill file for your coding agents").option("--print", "Print the skill file content instead of installing").option("--path <path>", "Install to a specific file path").action(
|
|
3004
|
+
withErrorHandling(async (opts) => {
|
|
3005
|
+
if (opts.print) {
|
|
3006
|
+
process.stdout.write(readFileSync(skillPath(), "utf-8"));
|
|
3007
|
+
return;
|
|
3008
|
+
}
|
|
3009
|
+
const source = skillPath();
|
|
3010
|
+
if (opts.path) {
|
|
3011
|
+
const dir = dirname(opts.path);
|
|
3012
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
3013
|
+
copyFileSync(source, opts.path);
|
|
3014
|
+
process.stdout.write(`Installed to ${opts.path}
|
|
3015
|
+
`);
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
const targets = getAgentTargets();
|
|
3019
|
+
const isTTY = process.stdout.isTTY ?? false;
|
|
3020
|
+
if (isTTY) {
|
|
3021
|
+
await installInteractive(source, targets);
|
|
3022
|
+
} else {
|
|
3023
|
+
installNonInteractive(source, targets);
|
|
3024
|
+
}
|
|
3025
|
+
})
|
|
3026
|
+
);
|
|
3027
|
+
return cmd;
|
|
3028
|
+
}
|
|
3029
|
+
|
|
2844
3030
|
// src/commands/update.ts
|
|
2845
|
-
import { Command as
|
|
3031
|
+
import { Command as Command24 } from "commander";
|
|
2846
3032
|
function collectProps3(val, acc) {
|
|
2847
3033
|
acc.push(val);
|
|
2848
3034
|
return acc;
|
|
2849
3035
|
}
|
|
2850
3036
|
function updateCommand() {
|
|
2851
|
-
const cmd = new
|
|
3037
|
+
const cmd = new Command24("update");
|
|
2852
3038
|
cmd.description("update properties on a Notion page").argument("<id/url>", "Notion page ID or URL").option(
|
|
2853
3039
|
"--prop <property=value>",
|
|
2854
3040
|
"set a property value (repeatable)",
|
|
@@ -2906,7 +3092,7 @@ function updateCommand() {
|
|
|
2906
3092
|
}
|
|
2907
3093
|
|
|
2908
3094
|
// src/commands/users.ts
|
|
2909
|
-
import { Command as
|
|
3095
|
+
import { Command as Command25 } from "commander";
|
|
2910
3096
|
function getEmailOrWorkspace(user) {
|
|
2911
3097
|
if (user.type === "person") {
|
|
2912
3098
|
return user.person.email ?? "\u2014";
|
|
@@ -2918,7 +3104,7 @@ function getEmailOrWorkspace(user) {
|
|
|
2918
3104
|
return "\u2014";
|
|
2919
3105
|
}
|
|
2920
3106
|
function usersCommand() {
|
|
2921
|
-
const cmd = new
|
|
3107
|
+
const cmd = new Command25("users");
|
|
2922
3108
|
cmd.description("list all users in the workspace").option("--json", "output as JSON").action(
|
|
2923
3109
|
withErrorHandling(async (opts) => {
|
|
2924
3110
|
if (opts.json) setOutputMode("json");
|
|
@@ -2945,11 +3131,11 @@ function usersCommand() {
|
|
|
2945
3131
|
|
|
2946
3132
|
// src/cli.ts
|
|
2947
3133
|
var __filename = fileURLToPath(import.meta.url);
|
|
2948
|
-
var __dirname =
|
|
3134
|
+
var __dirname = dirname2(__filename);
|
|
2949
3135
|
var pkg = JSON.parse(
|
|
2950
|
-
|
|
3136
|
+
readFileSync2(join4(__dirname, "../package.json"), "utf-8")
|
|
2951
3137
|
);
|
|
2952
|
-
var program = new
|
|
3138
|
+
var program = new Command26();
|
|
2953
3139
|
program.name("notion").description("Notion CLI \u2014 read Notion pages and databases from the terminal").version(pkg.version);
|
|
2954
3140
|
program.option("--verbose", "show API requests/responses").option("--color", "force color output").option("--json", "force JSON output (overrides TTY detection)").option("--md", "force markdown output for page content");
|
|
2955
3141
|
program.configureOutput({
|
|
@@ -2970,7 +3156,7 @@ program.hook("preAction", (thisCommand) => {
|
|
|
2970
3156
|
setOutputMode("md");
|
|
2971
3157
|
}
|
|
2972
3158
|
});
|
|
2973
|
-
var authCmd = new
|
|
3159
|
+
var authCmd = new Command26("auth").description("manage Notion authentication");
|
|
2974
3160
|
authCmd.action(authDefaultAction(authCmd));
|
|
2975
3161
|
authCmd.addCommand(loginCommand());
|
|
2976
3162
|
authCmd.addCommand(logoutCommand());
|
|
@@ -2980,7 +3166,7 @@ authCmd.addCommand(profileUseCommand());
|
|
|
2980
3166
|
authCmd.addCommand(profileRemoveCommand());
|
|
2981
3167
|
program.addCommand(authCmd);
|
|
2982
3168
|
program.addCommand(initCommand(), { hidden: true });
|
|
2983
|
-
var profileCmd = new
|
|
3169
|
+
var profileCmd = new Command26("profile").description(
|
|
2984
3170
|
"manage authentication profiles"
|
|
2985
3171
|
);
|
|
2986
3172
|
profileCmd.addCommand(profileListCommand());
|
|
@@ -2999,11 +3185,13 @@ program.addCommand(createPageCommand());
|
|
|
2999
3185
|
program.addCommand(editPageCommand());
|
|
3000
3186
|
program.addCommand(updateCommand());
|
|
3001
3187
|
program.addCommand(archiveCommand());
|
|
3002
|
-
|
|
3188
|
+
program.addCommand(moveCommand());
|
|
3189
|
+
var dbCmd = new Command26("db").description("Database operations");
|
|
3003
3190
|
dbCmd.addCommand(dbCreateCommand());
|
|
3004
3191
|
dbCmd.addCommand(dbSchemaCommand());
|
|
3005
3192
|
dbCmd.addCommand(dbQueryCommand());
|
|
3006
3193
|
program.addCommand(dbCmd);
|
|
3007
3194
|
program.addCommand(completionCommand());
|
|
3195
|
+
program.addCommand(skillCommand());
|
|
3008
3196
|
await program.parseAsync();
|
|
3009
3197
|
//# sourceMappingURL=cli.js.map
|