1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use crate::utils::DEFAULT_TIMEOUT_SECS;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "notion-cli")]
#[command(about = "A simple Notion CLI tool", long_about = None)]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
/// Notion API key (overrides env var and config file)
#[arg(long, global = true, env = "NOTION_API_KEY")]
pub api_key: Option<String>,
/// Request timeout in seconds
#[arg(long, default_value_t = DEFAULT_TIMEOUT_SECS, global = true)]
pub timeout: u64,
}
#[derive(Subcommand)]
pub enum Commands {
/// Search for pages and databases
Search {
/// Search query
query: String,
/// Maximum results to fetch (handles pagination)
#[arg(short, long, default_value_t = 100)]
limit: usize,
},
/// Read a page content
Read {
/// Page ID
page_id: String,
},
/// Create a new page
Create {
/// Parent page ID
#[arg(short, long)]
parent: String,
/// Page title
#[arg(short, long)]
title: String,
/// Page content (optional)
#[arg(short, long)]
content: Option<String>,
},
/// Append content to a page
Append {
/// Page ID
page_id: String,
/// Content to append
content: String,
},
/// Append a code block to a page
AppendCode {
/// Page ID
page_id: String,
/// Code content
code: String,
/// Programming language (e.g., rust, python, javascript)
#[arg(short, long, default_value = "plain text")]
language: String,
},
/// Append a bookmark to a page
AppendBookmark {
/// Page ID
page_id: String,
/// Bookmark URL
url: String,
/// Optional caption
#[arg(short, long)]
caption: Option<String>,
},
/// Update a page (title, icon)
Update {
/// Page ID
page_id: String,
/// New title
#[arg(short, long)]
title: Option<String>,
/// New icon (emoji)
#[arg(short, long)]
icon: Option<String>,
},
/// Delete (archive) a page
Delete {
/// Page ID
page_id: String,
},
/// Query a database
Query {
/// Database ID
database_id: String,
/// Filter by property (format: "PropertyName=value" or "PropertyName:type=value")
/// Supported types: title, rich_text (default), select, checkbox, number
#[arg(short, long)]
filter: Option<String>,
/// Sort by property
#[arg(short, long)]
sort: Option<String>,
/// Sort direction (asc or desc)
#[arg(long, default_value = "desc")]
direction: String,
/// Maximum results
#[arg(short, long, default_value_t = 100)]
limit: usize,
},
/// Delete (archive) a block
DeleteBlock {
/// Block ID
block_id: String,
},
/// Append a heading to a page
AppendHeading {
/// Page ID
page_id: String,
/// Heading text
text: String,
/// Heading level (1, 2, or 3)
#[arg(short, long, default_value_t = 2)]
level: u8,
},
/// Append a divider to a page
AppendDivider {
/// Page ID
page_id: String,
},
/// Append a bulleted list to a page
AppendList {
/// Page ID
page_id: String,
/// List items (comma-separated)
items: String,
},
/// Append a paragraph with a link
AppendLink {
/// Page ID
page_id: String,
/// Text before the link
#[arg(long)]
prefix: Option<String>,
/// Link text
#[arg(long)]
link_text: String,
/// Link URL
#[arg(long)]
url: String,
/// Text after the link
#[arg(long)]
suffix: Option<String>,
},
/// Get block IDs for a page (for bulk operations)
GetBlockIds {
/// Page ID
page_id: String,
},
/// Move a page to a new parent
Move {
/// Source page ID
page_id: String,
/// New parent page ID
#[arg(short, long)]
parent: String,
/// Delete original page after copying
#[arg(long, default_value_t = false)]
delete: bool,
},
/// Initialize config with API key
Init {
/// API key to save (if not provided, will prompt)
#[arg(long)]
api_key: Option<String>,
},
/// Show current config
Config,
}