notas 0.0.0 → 26.2.1

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 ADDED
@@ -0,0 +1,115 @@
1
+ # notas
2
+
3
+ Multi-provider notes & docs CLI. Notion is the first supported provider.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ # Homebrew
9
+ brew install circlesac/tap/notas
10
+
11
+ # npm
12
+ npx @circlesac/notas
13
+
14
+ # From source
15
+ bun install
16
+ bun run build
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```bash
22
+ # Authenticate (opens browser for OAuth)
23
+ notas notion auth login
24
+
25
+ # Or use an integration token
26
+ notas notion auth login --token ntn_xxx
27
+
28
+ # List databases
29
+ notas notion db list
30
+
31
+ # Query a database
32
+ notas notion db query <database-id>
33
+
34
+ # Search
35
+ notas notion search <query>
36
+
37
+ # Output as JSON
38
+ notas notion db list --output json
39
+ ```
40
+
41
+ ### Commands
42
+
43
+ ```
44
+ notas notion auth login, logout, status, refresh
45
+ notas notion databases list, get, query, create, update, delete
46
+ notas notion pages get, create, update, archive, restore
47
+ notas notion blocks list, get, append, update, delete
48
+ notas notion users list, get, me
49
+ notas notion search <query>
50
+ notas notion comments list, create
51
+ notas notion api <method> <endpoint> [--body json]
52
+ notas notion version
53
+ ```
54
+
55
+ `db` is an alias for `databases`.
56
+
57
+ ## Development
58
+
59
+ ```bash
60
+ # Run locally
61
+ bun run dev -- notion db list
62
+
63
+ # Lint (oxlint + eslint + prettier + biome + tsc)
64
+ bun run lint
65
+
66
+ # Type check
67
+ bun run type-check
68
+
69
+ # Test
70
+ bun run test
71
+
72
+ # Build native binary
73
+ bun run build
74
+
75
+ # Full pre-merge check
76
+ bun run pre-merge
77
+ ```
78
+
79
+ ## Project Structure
80
+
81
+ ```
82
+ src/
83
+ index.ts CLI entry point
84
+ lib/ Shared utilities (credentials, output, errors)
85
+ platforms/notion/ Notion provider
86
+ auth/ login, logout, status, refresh
87
+ databases/ CRUD + query
88
+ pages/ CRUD + archive/restore
89
+ blocks/ CRUD + append
90
+ users/ list, get, me
91
+ search/ full-text search
92
+ comments/ list, create
93
+ api.ts raw API passthrough
94
+ client.ts Notion client factory
95
+ properties.ts property formatting
96
+ types/ shared types
97
+ worker/ Cloudflare Worker (OAuth callback relay at notas.circles.ac)
98
+ npm/ npm distribution (shim + installer)
99
+ homebrew/ Homebrew formula template
100
+ ```
101
+
102
+ ## Deploy
103
+
104
+ ```bash
105
+ # Deploy OAuth callback worker
106
+ bun run deploy:worker
107
+ ```
108
+
109
+ ## Release
110
+
111
+ Releases are triggered via `workflow_dispatch` in GitHub Actions. The workflow runs tests, bumps the version (CalVer via `@circlesac/oneup`), builds native binaries for 4 platforms, creates a GitHub Release, publishes to npm, and updates the Homebrew formula.
112
+
113
+ ```bash
114
+ gh workflow run release.yml
115
+ ```
package/bin/install.js ADDED
@@ -0,0 +1,63 @@
1
+ import https from "https";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { execSync } from "child_process";
5
+ import { fileURLToPath } from "url";
6
+ import { createRequire } from "module";
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+
11
+ const REPO = "circlesac/notas-cli";
12
+
13
+ const PLATFORMS = {
14
+ "darwin-x64": { artifact: "notas-darwin-x64", ext: ".tar.gz" },
15
+ "darwin-arm64": { artifact: "notas-darwin-arm64", ext: ".tar.gz" },
16
+ "linux-x64": { artifact: "notas-linux-x64", ext: ".tar.gz" },
17
+ "linux-arm64": { artifact: "notas-linux-arm64", ext: ".tar.gz" },
18
+ };
19
+
20
+ function download(url) {
21
+ return new Promise((resolve, reject) => {
22
+ https.get(url, (res) => {
23
+ if (res.statusCode === 302 || res.statusCode === 301) {
24
+ return download(res.headers.location).then(resolve).catch(reject);
25
+ }
26
+ if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`));
27
+ const chunks = [];
28
+ res.on("data", (c) => chunks.push(c));
29
+ res.on("end", () => resolve(Buffer.concat(chunks)));
30
+ res.on("error", reject);
31
+ });
32
+ });
33
+ }
34
+
35
+ const nativeDir = path.join(__dirname, "native");
36
+ const binPath = path.join(nativeDir, "notas");
37
+
38
+ if (!fs.existsSync(binPath)) {
39
+ const { version } = require("../package.json");
40
+ if (version) {
41
+ const platform = `${process.platform}-${process.arch}`;
42
+ const info = PLATFORMS[platform];
43
+ if (!info) {
44
+ console.error(`Unsupported platform: ${platform}`);
45
+ process.exit(1);
46
+ }
47
+
48
+ const { artifact, ext } = info;
49
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${artifact}${ext}`;
50
+ console.info(`Downloading notas v${version} for ${platform}...`);
51
+
52
+ const data = await download(url);
53
+ fs.mkdirSync(nativeDir, { recursive: true });
54
+
55
+ const tmp = path.join(nativeDir, `tmp${ext}`);
56
+ fs.writeFileSync(tmp, data);
57
+ execSync(`tar xzf "${tmp}"`, { cwd: nativeDir });
58
+ fs.unlinkSync(tmp);
59
+
60
+ fs.chmodSync(binPath, 0o755);
61
+ console.info("Installed successfully.");
62
+ }
63
+ }
package/bin/install.sh ADDED
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ REPO="circlesac/notas-cli"
5
+ INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
6
+
7
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
8
+ ARCH=$(uname -m)
9
+
10
+ case "$OS-$ARCH" in
11
+ darwin-arm64) NAME="notas-darwin-arm64" ;;
12
+ darwin-x86_64) NAME="notas-darwin-x64" ;;
13
+ linux-aarch64) NAME="notas-linux-arm64" ;;
14
+ linux-x86_64) NAME="notas-linux-x64" ;;
15
+ *) echo "Unsupported platform: $OS-$ARCH"; exit 1 ;;
16
+ esac
17
+
18
+ VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | cut -d'"' -f4)
19
+ URL="https://github.com/$REPO/releases/download/$VERSION/${NAME}.tar.gz"
20
+
21
+ echo "Installing notas $VERSION..."
22
+ curl -fsSL "$URL" | tar xz -C "$INSTALL_DIR"
23
+ chmod +x "$INSTALL_DIR/notas"
24
+ echo "Installed to $INSTALL_DIR/notas"
package/bin/notas ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "child_process";
4
+ import { existsSync } from "fs";
5
+ import { fileURLToPath } from "url";
6
+ import path from "path";
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const bin = path.join(__dirname, "native", "notas");
10
+
11
+ if (!existsSync(bin)) {
12
+ await import("./install.js");
13
+ }
14
+ const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
15
+ process.exit(result.status ?? 1);
package/package.json CHANGED
@@ -1,7 +1,46 @@
1
1
  {
2
+ "bin": {
3
+ "notas": "bin/notas"
4
+ },
5
+ "dependencies": {
6
+ "@notionhq/client": "^5.9.0",
7
+ "citty": "^0.2.1"
8
+ },
9
+ "description": "Multi-provider notes & docs CLI",
10
+ "devDependencies": {
11
+ "@types/bun": "latest",
12
+ "@vitest/coverage-v8": "^4.0.18",
13
+ "vitest": "^4.0.18"
14
+ },
15
+ "files": [
16
+ "bin",
17
+ "skills"
18
+ ],
19
+ "license": "MIT",
20
+ "module": "src/index.ts",
2
21
  "name": "notas",
3
- "version": "0.0.0",
4
- "description": "Reserved",
5
- "main": "index.js",
6
- "license": "MIT"
22
+ "peerDependencies": {
23
+ "typescript": "^5"
24
+ },
25
+ "pi": {
26
+ "skills": [
27
+ "./skills"
28
+ ]
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/circlesac/notas-cli"
33
+ },
34
+ "scripts": {
35
+ "build": "bun build --compile --outfile=dist/notas src/index.ts",
36
+ "deploy:worker": "cd worker && npx wrangler deploy",
37
+ "dev": "bun run src/index.ts",
38
+ "lint": "npx @circlesac/lint --all",
39
+ "postinstall": "node bin/install.js",
40
+ "pre-merge": "bun run lint && bun run type-check && bun run test && bun run build",
41
+ "test": "vitest run",
42
+ "type-check": "npx tsc --noEmit"
43
+ },
44
+ "type": "module",
45
+ "version": "26.2.1"
7
46
  }
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: notion
3
+ description: Reference guide for the notas CLI Notion provider. Use this when working with Notion pages, databases, blocks, users, comments, or search.
4
+ ---
5
+
6
+ # notas CLI Reference
7
+
8
+ ## Quick Start
9
+
10
+ ```bash
11
+ notas notion auth login # OAuth login (opens browser)
12
+ notas notion search "meeting" # Search across workspace
13
+ notas notion db list # List all databases
14
+ ```
15
+
16
+ ## Global Flags
17
+
18
+ | Flag | Alias | Description |
19
+ |------|-------|-------------|
20
+ | `--workspace` | `-w` | Select workspace (when multiple configured) |
21
+ | `--json` | | Output as JSON |
22
+ | `--plain` | | Output as tab-separated plain text |
23
+
24
+ ## Authentication
25
+
26
+ ```bash
27
+ notas notion auth login # OAuth flow (default)
28
+ notas notion auth login --token ntn_xxx # Manual token
29
+ notas notion auth login --name work # Name the workspace
30
+ notas notion auth status # Show all workspaces
31
+ notas notion auth logout --name work # Remove a workspace
32
+ notas notion auth refresh # Refresh OAuth token
33
+ notas notion auth rename old-name new-name # Rename workspace
34
+ ```
35
+
36
+ Environment variable: `NOTION_TOKEN` overrides stored credentials.
37
+
38
+ ## Databases
39
+
40
+ ```bash
41
+ notas notion db list
42
+ notas notion db get <database-id>
43
+ notas notion db query <database-id>
44
+ notas notion db query <database-id> --filter '{"property":"Status","select":{"equals":"Done"}}'
45
+ notas notion db query <database-id> --sort '[{"property":"Created","direction":"descending"}]'
46
+ notas notion db query <database-id> --columns "Name,Status,Date"
47
+ notas notion db create <parent-page-id> --title "My Database"
48
+ notas notion db update <database-id> --title "New Title" --description "Updated"
49
+ notas notion db delete <database-id>
50
+ ```
51
+
52
+ Pagination: `--limit 10`, `--all`, `--cursor <cursor>`
53
+
54
+ ## Pages
55
+
56
+ ```bash
57
+ notas notion pages get <page-id>
58
+ notas notion pages create <parent-id> --title "New Page"
59
+ notas notion pages create <parent-id> --title "Page" --content "Body text"
60
+ notas notion pages create <parent-id> --title "Page" --icon "📝"
61
+ notas notion pages create <db-id> --parent-type database --title "Row" --properties '{"Status":{"select":{"name":"Draft"}}}'
62
+ notas notion pages update <page-id> --title "Updated Title"
63
+ notas notion pages archive <page-id>
64
+ notas notion pages restore <page-id>
65
+ ```
66
+
67
+ Stdin support:
68
+ ```bash
69
+ cat notes.md | notas notion pages create <parent-id> --title "From File" --stdio
70
+ ```
71
+
72
+ ## Blocks
73
+
74
+ ```bash
75
+ notas notion blocks list <page-id>
76
+ notas notion blocks list <page-id> --recursive # All nested blocks
77
+ notas notion blocks get <block-id>
78
+ notas notion blocks append <page-id> --text "Hello world"
79
+ notas notion blocks append <page-id> --type heading_1 --text "Title"
80
+ notas notion blocks append <page-id> --type code --text "console.log('hi')" --language javascript
81
+ notas notion blocks append <page-id> --type to_do --text "Task" --checked
82
+ notas notion blocks append <page-id> --type bookmark --url "https://example.com"
83
+ notas notion blocks append <page-id> --type divider
84
+ notas notion blocks append <page-id> --blocks '[{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"Complex block"}}]}}]'
85
+ notas notion blocks update <block-id> --text "Updated text"
86
+ notas notion blocks update <block-id> --body '{"paragraph":{"rich_text":[{"type":"text","text":{"content":"Raw update"}}]}}'
87
+ notas notion blocks delete <block-id>
88
+ ```
89
+
90
+ Block types: `paragraph`, `heading_1`, `heading_2`, `heading_3`, `bulleted_list_item`, `numbered_list_item`, `to_do`, `toggle`, `code`, `quote`, `callout`, `divider`, `bookmark`
91
+
92
+ Stdin support:
93
+ ```bash
94
+ cat code.py | notas notion blocks append <page-id> --type code --language python --stdio
95
+ ```
96
+
97
+ ## Search
98
+
99
+ ```bash
100
+ notas notion search "query"
101
+ notas notion search "query" --type page
102
+ notas notion search "query" --type database
103
+ notas notion search --sort ascending
104
+ notas notion search # List all (no query)
105
+ ```
106
+
107
+ ## Users
108
+
109
+ ```bash
110
+ notas notion users list
111
+ notas notion users list --filter "john"
112
+ notas notion users get <user-id>
113
+ notas notion users me
114
+ ```
115
+
116
+ ## Comments
117
+
118
+ ```bash
119
+ notas notion comments list <page-id>
120
+ notas notion comments create --page-id <page-id> --text "New comment"
121
+ notas notion comments create --discussion-id <id> --text "Reply"
122
+ echo "Comment from pipe" | notas notion comments create --page-id <id> --stdio
123
+ ```
124
+
125
+ ## Raw API
126
+
127
+ ```bash
128
+ notas notion api GET /v1/users
129
+ notas notion api POST /v1/search --body '{"query":"test"}'
130
+ notas notion api POST /v1/databases/<id>/query '{"page_size":5}'
131
+ notas notion api PATCH /v1/pages/<id> --body '{"archived":true}'
132
+ ```
133
+
134
+ ## Common Workflows
135
+
136
+ ### Create a page with content from a file
137
+ ```bash
138
+ cat document.md | notas notion pages create <parent-id> --title "My Doc" --stdio
139
+ ```
140
+
141
+ ### Query a database and pipe to jq
142
+ ```bash
143
+ notas notion db query <db-id> --json | jq '.results[].properties.Name.title[0].plain_text'
144
+ ```
145
+
146
+ ### Append multiple blocks from a script
147
+ ```bash
148
+ notas notion blocks append <page-id> --type heading_1 --text "Section Title"
149
+ notas notion blocks append <page-id> --text "Paragraph content"
150
+ cat snippet.py | notas notion blocks append <page-id> --type code --language python --stdio
151
+ ```
152
+
153
+ ### Search and get page content
154
+ ```bash
155
+ PAGE_ID=$(notas notion search "meeting notes" --json | jq -r '.results[0].id')
156
+ notas notion blocks list $PAGE_ID --recursive --plain
157
+ ```
package/index.js DELETED
@@ -1 +0,0 @@
1
-