@getnote/cli 0.1.2
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 +153 -0
- package/package.json +28 -0
- package/scripts/postinstall.js +105 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# getnote-cli
|
|
2
|
+
|
|
3
|
+
CLI tool for [Get笔记](https://biji.com) — manage notes and knowledge bases from the terminal.
|
|
4
|
+
|
|
5
|
+
Designed for both humans and AI agents.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### npm (recommended)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @getnote/cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Manual
|
|
16
|
+
|
|
17
|
+
Download the latest binary from [Releases](https://github.com/iswalle/getnote-cli/releases) and place it on your `$PATH`.
|
|
18
|
+
|
|
19
|
+
### Build from source
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/iswalle/getnote-cli.git
|
|
23
|
+
cd getnote-cli
|
|
24
|
+
make install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Authenticate (OAuth browser flow)
|
|
31
|
+
getnote auth login
|
|
32
|
+
|
|
33
|
+
# Save a URL
|
|
34
|
+
getnote save https://example.com/article --title "Great article"
|
|
35
|
+
|
|
36
|
+
# Save plain text
|
|
37
|
+
getnote save "Remember to review the docs" --tag work
|
|
38
|
+
|
|
39
|
+
# List recent notes
|
|
40
|
+
getnote notes
|
|
41
|
+
|
|
42
|
+
# List all notes (auto-paginate)
|
|
43
|
+
getnote notes --all
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Commands
|
|
47
|
+
|
|
48
|
+
### Authentication
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
getnote auth login Authenticate via OAuth (browser)
|
|
52
|
+
getnote auth login --api-key <key> Authenticate with API key directly
|
|
53
|
+
getnote auth status Show authentication status
|
|
54
|
+
getnote auth logout Remove saved credentials
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Save & Tasks
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
getnote save <url|text> Save a URL or text note
|
|
61
|
+
--title <title> Optional title
|
|
62
|
+
--tag <tag> Tag (repeatable)
|
|
63
|
+
|
|
64
|
+
getnote task <task_id> Check the progress of an async save task
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Notes
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
getnote notes List recent notes (default 20)
|
|
71
|
+
--limit <n> Number of notes (default 20)
|
|
72
|
+
--since-id <id> Pagination cursor
|
|
73
|
+
--all Fetch all notes (auto-paginate)
|
|
74
|
+
|
|
75
|
+
getnote note <id> Show note details
|
|
76
|
+
--field <name> Output a single field as plain text
|
|
77
|
+
(id, title, content, type,
|
|
78
|
+
created_at, updated_at, url, excerpt)
|
|
79
|
+
|
|
80
|
+
getnote note update <id> Update a note
|
|
81
|
+
--title <title>
|
|
82
|
+
--content <content> plain_text notes only
|
|
83
|
+
--tag <tags> Comma-separated, replaces existing tags
|
|
84
|
+
|
|
85
|
+
getnote note delete <id> Delete a note (moves to trash)
|
|
86
|
+
-y, --yes Skip confirmation
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Knowledge Bases
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
getnote kbs List all knowledge bases
|
|
93
|
+
|
|
94
|
+
getnote kb <topic_id> List notes in a knowledge base
|
|
95
|
+
--limit <n> Number of notes (default 20)
|
|
96
|
+
--all Fetch all notes (auto-paginate)
|
|
97
|
+
|
|
98
|
+
getnote kb create <name> Create a knowledge base
|
|
99
|
+
--desc <description>
|
|
100
|
+
|
|
101
|
+
getnote kb add <topic_id> <note_id> [note_id...] Add notes
|
|
102
|
+
getnote kb remove <topic_id> <note_id> [note_id...] Remove notes
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Global Flags
|
|
106
|
+
|
|
107
|
+
| Flag | Description |
|
|
108
|
+
|------|-------------|
|
|
109
|
+
| `--api-key <key>` | Override API key for this command |
|
|
110
|
+
| `-o, --output json\|table` | Output format (default: `table`) |
|
|
111
|
+
| `--env prod\|dev` | Target environment (default: `prod`) |
|
|
112
|
+
|
|
113
|
+
## Field Output (Pipe-friendly)
|
|
114
|
+
|
|
115
|
+
Use `--field` to extract a single value for use in scripts:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Get note content
|
|
119
|
+
getnote note 1234567890 --field content
|
|
120
|
+
|
|
121
|
+
# Get source URL of a link note
|
|
122
|
+
getnote note 1234567890 --field url
|
|
123
|
+
|
|
124
|
+
# Pipe into another command
|
|
125
|
+
getnote note 1234567890 --field content | pbcopy
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
Credentials are stored in `~/.getnote/config.json`:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"api_key": "gk_live_xxx",
|
|
135
|
+
"client_id": "cli_xxx"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Environment variables (higher priority than config file):
|
|
140
|
+
|
|
141
|
+
| Variable | Description |
|
|
142
|
+
|----------|-------------|
|
|
143
|
+
| `GETNOTE_API_KEY` | API key |
|
|
144
|
+
| `GETNOTE_CLIENT_ID` | Client ID |
|
|
145
|
+
| `GETNOTE_API_URL` | Override the API base URL |
|
|
146
|
+
|
|
147
|
+
## AI Agent Usage
|
|
148
|
+
|
|
149
|
+
All commands support `-o json` for machine-readable output. See the [skills/](./skills/) directory for agent skill documentation.
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getnote/cli",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "CLI tool for Get笔记 — manage notes and knowledge bases from the terminal",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"getnote",
|
|
7
|
+
"cli",
|
|
8
|
+
"notes",
|
|
9
|
+
"knowledge-base"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/iswalle/getnote-cli",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/iswalle/getnote-cli.git"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"bin": {
|
|
18
|
+
"getnote": "./bin/getnote"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"postinstall": "node scripts/postinstall.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/",
|
|
25
|
+
"scripts/",
|
|
26
|
+
"README.md"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// postinstall.js — downloads the getnote binary for the current platform.
|
|
3
|
+
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const { execSync } = require('child_process');
|
|
11
|
+
|
|
12
|
+
const pkg = require('../package.json');
|
|
13
|
+
const VERSION = pkg.version;
|
|
14
|
+
const REPO = 'iswalle/getnote-cli';
|
|
15
|
+
|
|
16
|
+
function getPlatform() {
|
|
17
|
+
const platform = os.platform();
|
|
18
|
+
const arch = os.arch();
|
|
19
|
+
|
|
20
|
+
const platformMap = {
|
|
21
|
+
darwin: 'darwin',
|
|
22
|
+
linux: 'linux',
|
|
23
|
+
win32: 'windows',
|
|
24
|
+
};
|
|
25
|
+
const archMap = {
|
|
26
|
+
x64: 'amd64',
|
|
27
|
+
arm64: 'arm64',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const p = platformMap[platform];
|
|
31
|
+
const a = archMap[arch];
|
|
32
|
+
if (!p || !a) {
|
|
33
|
+
throw new Error(`Unsupported platform: ${platform}/${arch}`);
|
|
34
|
+
}
|
|
35
|
+
return { platform: p, arch: a };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getBinaryName(platform) {
|
|
39
|
+
return platform.platform === 'windows' ? 'getnote.exe' : 'getnote';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getDownloadURL(platform) {
|
|
43
|
+
const ext = platform.platform === 'windows' ? '.zip' : '.tar.gz';
|
|
44
|
+
const asset = `getnote-cli_${VERSION}_${platform.platform}_${platform.arch}${ext}`;
|
|
45
|
+
return `https://github.com/${REPO}/releases/download/v${VERSION}/${asset}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function download(url, dest) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const file = fs.createWriteStream(dest);
|
|
51
|
+
const get = (u) => {
|
|
52
|
+
https.get(u, (res) => {
|
|
53
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
54
|
+
file.close();
|
|
55
|
+
get(res.headers.location);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (res.statusCode !== 200) {
|
|
59
|
+
reject(new Error(`Download failed: ${res.statusCode} ${u}`));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
res.pipe(file);
|
|
63
|
+
file.on('finish', () => file.close(resolve));
|
|
64
|
+
}).on('error', (err) => {
|
|
65
|
+
fs.unlink(dest, () => {});
|
|
66
|
+
reject(err);
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
get(url);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function main() {
|
|
74
|
+
const platform = getPlatform();
|
|
75
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
76
|
+
const binaryName = getBinaryName(platform);
|
|
77
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
78
|
+
const url = getDownloadURL(platform);
|
|
79
|
+
const tmpFile = path.join(os.tmpdir(), `getnote-download-${Date.now()}`);
|
|
80
|
+
|
|
81
|
+
console.log(`Downloading getnote v${VERSION} for ${platform.platform}/${platform.arch}...`);
|
|
82
|
+
console.log(`URL: ${url}`);
|
|
83
|
+
|
|
84
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await download(url, tmpFile);
|
|
88
|
+
|
|
89
|
+
if (platform.platform === 'windows') {
|
|
90
|
+
execSync(`unzip -o "${tmpFile}" "${binaryName}" -d "${binDir}"`);
|
|
91
|
+
} else {
|
|
92
|
+
execSync(`tar -xzf "${tmpFile}" -C "${binDir}" "${binaryName}"`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
96
|
+
console.log(`getnote installed at ${binaryPath}`);
|
|
97
|
+
} finally {
|
|
98
|
+
try { fs.unlinkSync(tmpFile); } catch (_) {}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main().catch((err) => {
|
|
103
|
+
console.error('Failed to install getnote:', err.message);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
});
|