teak-cli 1.0.50 → 1.0.52
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 +48 -0
- package/dist/index.js +38 -8
- package/package.json +19 -3
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Teak CLI
|
|
2
|
+
|
|
3
|
+
Command-line client for [Teak](https://teakvault.com), the personal knowledge hub for saving and rediscovering ideas, links, files, notes, and references.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g teak-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
teak --version
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Sign In
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
teak login
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The CLI opens Teak in your browser and stores the resulting session securely in macOS Keychain when available. You can also use an API key:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
teak --api-key teakapi_... cards list
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Common Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
teak add "Design note from today's review" --tags design,research
|
|
31
|
+
teak add --url https://example.com --tags reference
|
|
32
|
+
teak add --file ./screenshot.png --notes "Homepage inspiration"
|
|
33
|
+
teak search "homepage inspiration"
|
|
34
|
+
teak cards list --type link --limit 20
|
|
35
|
+
teak cards get <card-id>
|
|
36
|
+
teak cards update <card-id> --tags design,approved
|
|
37
|
+
teak fav <card-id>
|
|
38
|
+
teak rm <card-id>
|
|
39
|
+
teak tags
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use `--json` on any command for script-friendly output.
|
|
43
|
+
|
|
44
|
+
## Docs
|
|
45
|
+
|
|
46
|
+
- CLI guide: [teakvault.com/docs/cli](https://teakvault.com/docs/cli)
|
|
47
|
+
- API docs: [teakvault.com/docs/api](https://teakvault.com/docs/api)
|
|
48
|
+
- MCP docs: [teakvault.com/docs/mcp](https://teakvault.com/docs/mcp)
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,21 @@ var normalizeLimit = (limit) => {
|
|
|
73
73
|
}
|
|
74
74
|
return Math.max(1, Math.min(Math.trunc(limit ?? 50), 100));
|
|
75
75
|
};
|
|
76
|
+
var byteLengthForBody = (bytes) => {
|
|
77
|
+
if (bytes instanceof ArrayBuffer) {
|
|
78
|
+
return bytes.byteLength;
|
|
79
|
+
}
|
|
80
|
+
if (ArrayBuffer.isView(bytes)) {
|
|
81
|
+
return bytes.byteLength;
|
|
82
|
+
}
|
|
83
|
+
if (typeof Blob !== "undefined" && bytes instanceof Blob) {
|
|
84
|
+
return bytes.size;
|
|
85
|
+
}
|
|
86
|
+
if (typeof bytes === "string") {
|
|
87
|
+
return new TextEncoder().encode(bytes).byteLength;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
};
|
|
76
91
|
var buildCardsSearchParams = (input) => {
|
|
77
92
|
const search = new URLSearchParams;
|
|
78
93
|
if (input.query?.trim()) {
|
|
@@ -239,9 +254,14 @@ var createTeakClient = (options) => {
|
|
|
239
254
|
uploads: {
|
|
240
255
|
create: (input) => request("/v1/uploads", { body: JSON.stringify(input), method: "POST" }, asUpload),
|
|
241
256
|
putFile: async (uploadUrl, bytes, mimeType) => {
|
|
257
|
+
const headers = new Headers({ "Content-Type": mimeType });
|
|
258
|
+
const byteLength = byteLengthForBody(bytes);
|
|
259
|
+
if (byteLength !== null) {
|
|
260
|
+
headers.set("Content-Length", String(byteLength));
|
|
261
|
+
}
|
|
242
262
|
const response = await fetchImpl(uploadUrl, {
|
|
243
263
|
body: bytes,
|
|
244
|
-
headers
|
|
264
|
+
headers,
|
|
245
265
|
method: "PUT"
|
|
246
266
|
});
|
|
247
267
|
if (!response.ok) {
|
|
@@ -2327,6 +2347,7 @@ var VERSION = readPackageVersion();
|
|
|
2327
2347
|
var EXIT = { api: 1, auth: 3, notFound: 4, rateLimited: 5, usage: 2 };
|
|
2328
2348
|
var DEFAULT_API_URL = "https://api.teakvault.com";
|
|
2329
2349
|
var DEFAULT_AUTH_URL = "https://app.teakvault.com";
|
|
2350
|
+
var CLI_OAUTH_SCOPE = "profile email offline_access";
|
|
2330
2351
|
var SERVICE = "com.teakvault.cli";
|
|
2331
2352
|
var ACCOUNT = "default";
|
|
2332
2353
|
var readJson = (value) => {
|
|
@@ -2498,6 +2519,17 @@ var openBrowser = (url) => {
|
|
|
2498
2519
|
const args = platform() === "win32" ? ["/c", "start", "", url] : [url];
|
|
2499
2520
|
spawn(command, args, { detached: true, stdio: "ignore" }).unref();
|
|
2500
2521
|
};
|
|
2522
|
+
var createAuthorizeUrl = (options, params) => {
|
|
2523
|
+
const authUrl = new URL(authorizeEndpoint(options));
|
|
2524
|
+
authUrl.searchParams.set("response_type", "code");
|
|
2525
|
+
authUrl.searchParams.set("client_id", "teak-cli");
|
|
2526
|
+
authUrl.searchParams.set("redirect_uri", params.redirectUri);
|
|
2527
|
+
authUrl.searchParams.set("code_challenge", params.codeChallenge);
|
|
2528
|
+
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
2529
|
+
authUrl.searchParams.set("scope", CLI_OAUTH_SCOPE);
|
|
2530
|
+
authUrl.searchParams.set("state", params.state);
|
|
2531
|
+
return authUrl;
|
|
2532
|
+
};
|
|
2501
2533
|
var login = async (options) => {
|
|
2502
2534
|
const verifier = b64url(randomBytes(32));
|
|
2503
2535
|
const state = b64url(randomBytes(24));
|
|
@@ -2536,13 +2568,11 @@ var login = async (options) => {
|
|
|
2536
2568
|
}
|
|
2537
2569
|
});
|
|
2538
2570
|
server.listen(port, "127.0.0.1", () => {
|
|
2539
|
-
const authUrl =
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
2545
|
-
authUrl.searchParams.set("state", state);
|
|
2571
|
+
const authUrl = createAuthorizeUrl(options, {
|
|
2572
|
+
codeChallenge: sha256(verifier),
|
|
2573
|
+
redirectUri,
|
|
2574
|
+
state
|
|
2575
|
+
});
|
|
2546
2576
|
process.stdout.write(`${authUrl.toString()}
|
|
2547
2577
|
`);
|
|
2548
2578
|
if (options.browser !== false) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teak-cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Command
|
|
3
|
+
"version": "1.0.52",
|
|
4
|
+
"description": "Command-line client for Teak, the personal knowledge hub for saving and rediscovering ideas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"teak": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist"
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"teak",
|
|
15
|
+
"cli",
|
|
16
|
+
"knowledge-base",
|
|
17
|
+
"bookmark-manager",
|
|
18
|
+
"notes",
|
|
19
|
+
"mcp",
|
|
20
|
+
"api-client",
|
|
21
|
+
"productivity"
|
|
11
22
|
],
|
|
12
23
|
"engines": {
|
|
13
24
|
"node": ">=20"
|
|
@@ -33,5 +44,10 @@
|
|
|
33
44
|
"url": "git+https://github.com/praveenjuge/teak.git",
|
|
34
45
|
"directory": "apps/cli"
|
|
35
46
|
},
|
|
47
|
+
"homepage": "https://teakvault.com/docs/cli",
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/praveenjuge/teak/issues"
|
|
50
|
+
},
|
|
51
|
+
"author": "Praveen Juge <hello@praveenjuge.com>",
|
|
36
52
|
"license": "MIT"
|
|
37
53
|
}
|