dblx 0.1.50 → 0.1.63
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 +113 -42
- package/dist/index.js +404 -361
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,81 +4,152 @@ CLI for [dblebox](https://app.dblebox.com) — thread-first communication.
|
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
+
The CLI uses a verb-first command structure:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bunx dblx <verb> <noun> [options]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
dblx get threads
|
|
17
|
+
dblx get threads --q "planning"
|
|
18
|
+
dblx get today
|
|
19
|
+
dblx create thread --title "New thread"
|
|
20
|
+
dblx set thread 12345678 --title "Renamed"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Command Model
|
|
24
|
+
|
|
25
|
+
Read operations use `get`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
dblx get ...
|
|
7
29
|
```
|
|
8
|
-
|
|
30
|
+
|
|
31
|
+
Write operations use `create`, `set`, and `invite`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
dblx create ...
|
|
35
|
+
dblx set ...
|
|
36
|
+
dblx invite ...
|
|
9
37
|
```
|
|
10
38
|
|
|
39
|
+
This keeps permission boundaries clear for agents and automation. A tool can be granted `dblx get ...` without also gaining write access.
|
|
40
|
+
|
|
11
41
|
## Authentication
|
|
12
42
|
|
|
13
43
|
Generate an API key from **Settings > API Keys** in the dblebox web app, then:
|
|
14
44
|
|
|
15
|
-
```
|
|
45
|
+
```bash
|
|
16
46
|
dblx auth login
|
|
17
47
|
```
|
|
18
48
|
|
|
19
49
|
You'll be prompted for your key (starts with `dblx_`). Credentials are saved to `~/.config/dblx.json`.
|
|
20
50
|
|
|
21
|
-
```
|
|
22
|
-
dblx auth whoami
|
|
23
|
-
dblx auth logout
|
|
51
|
+
```bash
|
|
52
|
+
dblx auth whoami
|
|
53
|
+
dblx auth logout
|
|
24
54
|
```
|
|
25
55
|
|
|
26
56
|
You can also set `DBLEBOX_API_KEY` and `DBLEBOX_API_URL` environment variables instead of using `auth login`.
|
|
27
57
|
|
|
28
|
-
##
|
|
58
|
+
## Read Commands
|
|
59
|
+
|
|
60
|
+
### Threads
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
dblx get threads
|
|
64
|
+
dblx get threads --archived
|
|
65
|
+
dblx get threads --snoozed
|
|
66
|
+
dblx get threads --archived --snoozed
|
|
67
|
+
dblx get threads --q "plan"
|
|
68
|
+
dblx get threads --q "#dblebox" --archived --snoozed
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Today
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
dblx get today
|
|
75
|
+
dblx get today --date 2026-03-01
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Notes
|
|
29
79
|
|
|
80
|
+
```bash
|
|
81
|
+
dblx get thread-note <thread-id>
|
|
82
|
+
dblx get today-note
|
|
83
|
+
dblx get today-note --date 2026-03-01
|
|
30
84
|
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
dblx
|
|
36
|
-
dblx threads create --title "New thread" # create a thread
|
|
37
|
-
dblx threads create --title "..." --comment "First message"
|
|
38
|
-
dblx threads create --title "..." --note "Draft spec..."
|
|
39
|
-
dblx threads update <id> --title "New title"
|
|
40
|
-
dblx threads note <id> # read thread note
|
|
41
|
-
dblx threads note <id> --set "Updated note"
|
|
42
|
-
dblx threads archive <id>
|
|
43
|
-
dblx threads unarchive <id>
|
|
44
|
-
dblx threads snooze <id> --until 2026-03-01T09:00:00
|
|
45
|
-
dblx threads unsnooze <id>
|
|
46
|
-
dblx threads set-parent <id> --parent <parent-id>
|
|
47
|
-
dblx threads set-today <id> # assign to today
|
|
48
|
-
dblx threads set-today <id> --date 2026-03-01
|
|
49
|
-
dblx threads unset-today <id>
|
|
85
|
+
|
|
86
|
+
### Comments
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
dblx get comments --thread <thread-id>
|
|
50
90
|
```
|
|
51
91
|
|
|
52
|
-
|
|
92
|
+
### Members
|
|
53
93
|
|
|
94
|
+
```bash
|
|
95
|
+
dblx get members <thread-id>
|
|
54
96
|
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
|
|
98
|
+
## Write Commands
|
|
99
|
+
|
|
100
|
+
### Threads
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
dblx create thread --title "New thread"
|
|
104
|
+
dblx create thread --title "..." --comment "First message"
|
|
105
|
+
dblx create thread --title "..." --note "Draft spec..."
|
|
106
|
+
|
|
107
|
+
dblx set thread <thread-id> --title "New title"
|
|
108
|
+
dblx set thread <thread-id> --archived true
|
|
109
|
+
dblx set thread <thread-id> --archived false
|
|
110
|
+
dblx set thread <thread-id> --snoozed-until 2026-03-01T09:00:00
|
|
111
|
+
dblx set thread <thread-id> --snoozed-until none
|
|
58
112
|
```
|
|
59
113
|
|
|
60
|
-
|
|
114
|
+
### Notes
|
|
61
115
|
|
|
116
|
+
Reading and writing notes are separate commands.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
dblx set thread-note <thread-id> --content "Updated note"
|
|
120
|
+
dblx set today-note --content "My note"
|
|
121
|
+
dblx set today-note --date 2026-03-01 --content "My note"
|
|
62
122
|
```
|
|
63
|
-
|
|
64
|
-
|
|
123
|
+
|
|
124
|
+
### Relationships
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
dblx set thread-parent <thread-id> --parent <parent-id>
|
|
128
|
+
dblx set thread-today <thread-id> --date 2026-03-01
|
|
129
|
+
dblx set thread-today <thread-id> --remove
|
|
130
|
+
dblx set thread-today <thread-id> --date 2026-03-01 --remove
|
|
65
131
|
```
|
|
66
132
|
|
|
67
|
-
|
|
133
|
+
### Comments
|
|
68
134
|
|
|
135
|
+
```bash
|
|
136
|
+
dblx create comment --thread <thread-id> --body "Hello"
|
|
137
|
+
dblx set comment <comment-id> --body "Updated text"
|
|
69
138
|
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
dblx
|
|
139
|
+
|
|
140
|
+
### Members
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
dblx invite member <thread-id> --user alice@example.com
|
|
75
144
|
```
|
|
76
145
|
|
|
77
|
-
## JSON
|
|
146
|
+
## JSON Output
|
|
78
147
|
|
|
79
148
|
All read commands support `--json` for machine-readable output:
|
|
80
149
|
|
|
81
|
-
```
|
|
82
|
-
dblx threads
|
|
83
|
-
dblx
|
|
150
|
+
```bash
|
|
151
|
+
dblx get threads --json
|
|
152
|
+
dblx get threads --q "plan" --json
|
|
153
|
+
dblx get today --json
|
|
154
|
+
dblx get thread-note <thread-id> --json
|
|
84
155
|
```
|
package/dist/index.js
CHANGED
|
@@ -2127,62 +2127,64 @@ function deleteConfig() {
|
|
|
2127
2127
|
}
|
|
2128
2128
|
}
|
|
2129
2129
|
|
|
2130
|
-
// ../node_modules/@elysiajs/eden/dist/chunk-
|
|
2131
|
-
var
|
|
2132
|
-
constructor(e,
|
|
2133
|
-
super(
|
|
2130
|
+
// ../node_modules/@elysiajs/eden/dist/chunk-I5KHAGLL.mjs
|
|
2131
|
+
var d = class extends Error {
|
|
2132
|
+
constructor(e, s) {
|
|
2133
|
+
super(s + "");
|
|
2134
2134
|
this.status = e;
|
|
2135
|
-
this.value =
|
|
2135
|
+
this.value = s;
|
|
2136
2136
|
}
|
|
2137
2137
|
};
|
|
2138
2138
|
var i = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/;
|
|
2139
2139
|
var o = /(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{2}\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT(?:\+|-)\d{4}\s\([^)]+\)/;
|
|
2140
|
-
var
|
|
2141
|
-
var
|
|
2142
|
-
var
|
|
2143
|
-
if (typeof t != "string")
|
|
2140
|
+
var u = /^(?:(?:(?:(?:0?[1-9]|[12][0-9]|3[01])[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:19|20)\d{2})|(?:(?:19|20)\d{2}[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:0?[1-9]|[12][0-9]|3[01]))))(?:\s(?:1[012]|0?[1-9]):[0-5][0-9](?::[0-5][0-9])?(?:\s[AP]M)?)?$/;
|
|
2141
|
+
var c = (t) => t.trim().length !== 0 && !Number.isNaN(Number(t));
|
|
2142
|
+
var a = (t, r) => {
|
|
2143
|
+
if (typeof t != "string" || r?.parseDate === false)
|
|
2144
2144
|
return null;
|
|
2145
|
-
let
|
|
2146
|
-
if (i.test(
|
|
2147
|
-
let
|
|
2148
|
-
if (!Number.isNaN(
|
|
2149
|
-
return
|
|
2145
|
+
let e = t.replace(/"/g, "");
|
|
2146
|
+
if (i.test(e) || o.test(e) || u.test(e)) {
|
|
2147
|
+
let s = new Date(e);
|
|
2148
|
+
if (!Number.isNaN(s.getTime()))
|
|
2149
|
+
return s;
|
|
2150
2150
|
}
|
|
2151
2151
|
return null;
|
|
2152
2152
|
};
|
|
2153
|
-
var
|
|
2153
|
+
var p = (t) => {
|
|
2154
2154
|
let r = t.charCodeAt(0), e = t.charCodeAt(t.length - 1);
|
|
2155
2155
|
return r === 123 && e === 125 || r === 91 && e === 93;
|
|
2156
2156
|
};
|
|
2157
|
-
var
|
|
2158
|
-
let n =
|
|
2159
|
-
return n ||
|
|
2157
|
+
var f = (t, r) => JSON.parse(t, (e, s) => {
|
|
2158
|
+
let n = a(s, r);
|
|
2159
|
+
return n || s;
|
|
2160
2160
|
});
|
|
2161
|
-
var g = (t) => {
|
|
2161
|
+
var g = (t, r) => {
|
|
2162
2162
|
if (!t)
|
|
2163
2163
|
return t;
|
|
2164
|
-
if (
|
|
2164
|
+
if (c(t))
|
|
2165
2165
|
return +t;
|
|
2166
2166
|
if (t === "true")
|
|
2167
2167
|
return true;
|
|
2168
2168
|
if (t === "false")
|
|
2169
2169
|
return false;
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2170
|
+
if (r?.parseDate !== false) {
|
|
2171
|
+
let e = a(t, r);
|
|
2172
|
+
if (e)
|
|
2173
|
+
return e;
|
|
2174
|
+
}
|
|
2175
|
+
if (p(t))
|
|
2174
2176
|
try {
|
|
2175
|
-
return
|
|
2177
|
+
return f(t, r);
|
|
2176
2178
|
} catch {}
|
|
2177
2179
|
return t;
|
|
2178
2180
|
};
|
|
2179
|
-
var S = (t) => {
|
|
2180
|
-
let
|
|
2181
|
-
return
|
|
2181
|
+
var S = (t, r) => {
|
|
2182
|
+
let e = t.data.toString();
|
|
2183
|
+
return e === "null" ? null : g(e, r);
|
|
2182
2184
|
};
|
|
2183
2185
|
|
|
2184
|
-
// ../node_modules/@elysiajs/eden/dist/chunk-
|
|
2185
|
-
var
|
|
2186
|
+
// ../node_modules/@elysiajs/eden/dist/chunk-AB4FCYGG.mjs
|
|
2187
|
+
var W = class {
|
|
2186
2188
|
constructor(t) {
|
|
2187
2189
|
this.url = t;
|
|
2188
2190
|
this.ws = new WebSocket(t);
|
|
@@ -2191,253 +2193,283 @@ var F = class {
|
|
|
2191
2193
|
send(t) {
|
|
2192
2194
|
return Array.isArray(t) ? (t.forEach((n) => this.send(n)), this) : (this.ws.send(typeof t == "object" ? JSON.stringify(t) : t.toString()), this);
|
|
2193
2195
|
}
|
|
2194
|
-
on(t, n,
|
|
2195
|
-
return this.addEventListener(t, n,
|
|
2196
|
+
on(t, n, r) {
|
|
2197
|
+
return this.addEventListener(t, n, r);
|
|
2196
2198
|
}
|
|
2197
|
-
off(t, n,
|
|
2198
|
-
return this.ws.removeEventListener(t, n,
|
|
2199
|
+
off(t, n, r) {
|
|
2200
|
+
return this.ws.removeEventListener(t, n, r), this;
|
|
2199
2201
|
}
|
|
2200
2202
|
subscribe(t, n) {
|
|
2201
2203
|
return this.addEventListener("message", t, n);
|
|
2202
2204
|
}
|
|
2203
|
-
addEventListener(t, n,
|
|
2204
|
-
return this.ws.addEventListener(t, (
|
|
2205
|
+
addEventListener(t, n, r) {
|
|
2206
|
+
return this.ws.addEventListener(t, (c2) => {
|
|
2205
2207
|
if (t === "message") {
|
|
2206
|
-
let
|
|
2207
|
-
n({ ...
|
|
2208
|
+
let i2 = S(c2);
|
|
2209
|
+
n({ ...c2, data: i2 });
|
|
2208
2210
|
} else
|
|
2209
|
-
n(
|
|
2210
|
-
},
|
|
2211
|
+
n(c2);
|
|
2212
|
+
}, r), this;
|
|
2211
2213
|
}
|
|
2212
|
-
removeEventListener(t, n,
|
|
2213
|
-
return this.off(t, n,
|
|
2214
|
+
removeEventListener(t, n, r) {
|
|
2215
|
+
return this.off(t, n, r), this;
|
|
2214
2216
|
}
|
|
2215
2217
|
close() {
|
|
2216
2218
|
return this.ws.close(), this;
|
|
2217
2219
|
}
|
|
2218
2220
|
};
|
|
2219
|
-
var
|
|
2220
|
-
var
|
|
2221
|
-
var
|
|
2222
|
-
var
|
|
2223
|
-
var
|
|
2221
|
+
var Q = ["get", "post", "put", "delete", "patch", "options", "head", "connect", "subscribe"];
|
|
2222
|
+
var P = (e, t) => typeof t == "function" ? t(e) : t === true;
|
|
2223
|
+
var U = ["localhost", "127.0.0.1", "0.0.0.0"];
|
|
2224
|
+
var q = typeof FileList > "u";
|
|
2225
|
+
var H = (e) => q ? e instanceof Blob : e instanceof FileList || e instanceof File;
|
|
2226
|
+
var X = (e) => {
|
|
2224
2227
|
if (!e)
|
|
2225
2228
|
return false;
|
|
2226
2229
|
for (let t in e)
|
|
2227
|
-
if (
|
|
2230
|
+
if (H(e[t]) || Array.isArray(e[t]) && e[t].find(H))
|
|
2228
2231
|
return true;
|
|
2229
2232
|
return false;
|
|
2230
2233
|
};
|
|
2231
|
-
var
|
|
2234
|
+
var K = (e) => q ? e : new Promise((t) => {
|
|
2232
2235
|
let n = new FileReader;
|
|
2233
2236
|
n.onload = () => {
|
|
2234
|
-
let
|
|
2235
|
-
t(
|
|
2237
|
+
let r = new File([n.result], e.name, { lastModified: e.lastModified, type: e.type });
|
|
2238
|
+
t(r);
|
|
2236
2239
|
}, n.readAsArrayBuffer(e);
|
|
2237
2240
|
});
|
|
2238
|
-
var
|
|
2241
|
+
var A = async (e, t, n = {}, r = {}) => {
|
|
2239
2242
|
if (Array.isArray(e)) {
|
|
2240
|
-
for (let
|
|
2241
|
-
if (!Array.isArray(
|
|
2242
|
-
|
|
2243
|
+
for (let c2 of e)
|
|
2244
|
+
if (!Array.isArray(c2))
|
|
2245
|
+
r = await A(c2, t, n, r);
|
|
2243
2246
|
else {
|
|
2244
|
-
let
|
|
2245
|
-
if (typeof
|
|
2246
|
-
|
|
2247
|
+
let i2 = c2[0];
|
|
2248
|
+
if (typeof i2 == "string")
|
|
2249
|
+
r[i2.toLowerCase()] = c2[1];
|
|
2247
2250
|
else
|
|
2248
|
-
for (let [
|
|
2249
|
-
|
|
2251
|
+
for (let [a2, l] of i2)
|
|
2252
|
+
r[a2.toLowerCase()] = l;
|
|
2250
2253
|
}
|
|
2251
|
-
return
|
|
2254
|
+
return r;
|
|
2252
2255
|
}
|
|
2253
2256
|
if (!e)
|
|
2254
|
-
return
|
|
2257
|
+
return r;
|
|
2255
2258
|
switch (typeof e) {
|
|
2256
2259
|
case "function":
|
|
2257
2260
|
if (e instanceof Headers)
|
|
2258
|
-
return
|
|
2259
|
-
let
|
|
2260
|
-
return
|
|
2261
|
+
return A(e, t, n, r);
|
|
2262
|
+
let c2 = await e(t, n);
|
|
2263
|
+
return c2 ? A(c2, t, n, r) : r;
|
|
2261
2264
|
case "object":
|
|
2262
2265
|
if (e instanceof Headers)
|
|
2263
|
-
return e.forEach((
|
|
2264
|
-
|
|
2265
|
-
}),
|
|
2266
|
-
for (let [
|
|
2267
|
-
|
|
2268
|
-
return
|
|
2266
|
+
return e.forEach((i2, a2) => {
|
|
2267
|
+
r[a2.toLowerCase()] = i2;
|
|
2268
|
+
}), r;
|
|
2269
|
+
for (let [i2, a2] of Object.entries(e))
|
|
2270
|
+
r[i2.toLowerCase()] = a2;
|
|
2271
|
+
return r;
|
|
2269
2272
|
default:
|
|
2270
|
-
return
|
|
2273
|
+
return r;
|
|
2271
2274
|
}
|
|
2272
2275
|
};
|
|
2273
|
-
|
|
2274
|
-
let
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
let i2 = typeof o2 == "string" ? o2 : s2.decode(o2);
|
|
2284
|
-
i2.includes(`
|
|
2285
|
-
|
|
2286
|
-
`) ? yield* _(i2) : yield g(i2);
|
|
2276
|
+
function _(e, t) {
|
|
2277
|
+
let n = e.split(`
|
|
2278
|
+
`), r = {};
|
|
2279
|
+
for (let c2 of n) {
|
|
2280
|
+
if (!c2 || c2.startsWith(":"))
|
|
2281
|
+
continue;
|
|
2282
|
+
let i2 = c2.indexOf(":");
|
|
2283
|
+
if (i2 > 0) {
|
|
2284
|
+
let a2 = c2.slice(0, i2).trim(), l = c2.slice(i2 + 1).replace(/^ /, "");
|
|
2285
|
+
r[a2] = l && g(l, t);
|
|
2287
2286
|
}
|
|
2288
|
-
} finally {
|
|
2289
|
-
n.releaseLock();
|
|
2290
2287
|
}
|
|
2288
|
+
return Object.keys(r).length > 0 ? r : null;
|
|
2291
2289
|
}
|
|
2292
|
-
function*
|
|
2293
|
-
let
|
|
2290
|
+
function* B(e, t) {
|
|
2291
|
+
let n;
|
|
2292
|
+
for (;(n = e.value.indexOf(`
|
|
2294
2293
|
|
|
2295
|
-
`);
|
|
2296
|
-
|
|
2297
|
-
if (
|
|
2298
|
-
|
|
2299
|
-
|
|
2294
|
+
`)) !== -1; ) {
|
|
2295
|
+
let r = e.value.slice(0, n);
|
|
2296
|
+
if (e.value = e.value.slice(n + 2), r.trim()) {
|
|
2297
|
+
let c2 = _(r, t);
|
|
2298
|
+
c2 && (yield c2);
|
|
2300
2299
|
}
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
async function* Y(e, t) {
|
|
2303
|
+
let n = e.body;
|
|
2304
|
+
if (!n)
|
|
2305
|
+
return;
|
|
2306
|
+
let r = n.getReader(), c2 = new TextDecoder("utf-8"), i2 = { value: "" };
|
|
2307
|
+
try {
|
|
2308
|
+
for (;; ) {
|
|
2309
|
+
let { done: l, value: O } = await r.read();
|
|
2310
|
+
if (l)
|
|
2311
|
+
break;
|
|
2312
|
+
let k = typeof O == "string" ? O : c2.decode(O, { stream: true });
|
|
2313
|
+
i2.value += k, yield* B(i2, t);
|
|
2309
2314
|
}
|
|
2310
|
-
|
|
2315
|
+
let a2 = c2.decode();
|
|
2316
|
+
if (a2 && (i2.value += a2), yield* B(i2, t), i2.value.trim()) {
|
|
2317
|
+
let l = _(i2.value, t);
|
|
2318
|
+
l && (yield l);
|
|
2319
|
+
}
|
|
2320
|
+
} finally {
|
|
2321
|
+
r.releaseLock();
|
|
2311
2322
|
}
|
|
2312
2323
|
}
|
|
2313
|
-
var
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
O += (O ? "&" : "?") + `${encodeURIComponent(w)}=${encodeURIComponent(u2)}`;
|
|
2324
|
+
var F = (e, t, n = [], r) => new Proxy(() => {}, { get(c2, i2) {
|
|
2325
|
+
if (!(n.length === 0 && (i2 === "then" || i2 === "catch" || i2 === "finally")))
|
|
2326
|
+
return F(e, t, [...n, i2], r);
|
|
2327
|
+
}, apply(c2, i2, [a2, l]) {
|
|
2328
|
+
if (!a2 || l || typeof a2 == "object" && Object.keys(a2).length !== 1 || Q.includes(n.at(-1))) {
|
|
2329
|
+
let O = [...n], k = O.pop(), b = "/" + O.join("/"), { fetcher: V = fetch, headers: L, onRequest: g2, onResponse: R, fetch: G } = t, E = k === "get" || k === "head" || k === "subscribe", M = E ? a2?.query : l?.query, D = "";
|
|
2330
|
+
if (M) {
|
|
2331
|
+
let s = (m, d2) => {
|
|
2332
|
+
d2 != null && (d2 instanceof Date && (d2 = d2.toISOString()), D += (D ? "&" : "?") + `${encodeURIComponent(m)}=${encodeURIComponent(typeof d2 == "object" ? JSON.stringify(d2) : d2 + "")}`);
|
|
2323
2333
|
};
|
|
2324
|
-
for (let [
|
|
2325
|
-
if (Array.isArray(
|
|
2326
|
-
for (let
|
|
2327
|
-
|
|
2334
|
+
for (let [m, d2] of Object.entries(M)) {
|
|
2335
|
+
if (Array.isArray(d2)) {
|
|
2336
|
+
for (let T of d2)
|
|
2337
|
+
s(m, T);
|
|
2328
2338
|
continue;
|
|
2329
2339
|
}
|
|
2330
|
-
|
|
2331
|
-
if (typeof u2 == "object") {
|
|
2332
|
-
r(w, JSON.stringify(u2));
|
|
2333
|
-
continue;
|
|
2334
|
-
}
|
|
2335
|
-
r(w, `${u2}`);
|
|
2336
|
-
}
|
|
2340
|
+
s(m, d2);
|
|
2337
2341
|
}
|
|
2338
2342
|
}
|
|
2339
2343
|
if (k === "subscribe") {
|
|
2340
|
-
let
|
|
2341
|
-
return new
|
|
2344
|
+
let s = e.replace(/^([^]+):\/\//, e.startsWith("https://") ? "wss://" : e.startsWith("http://") || U.find((m) => e.includes(m)) ? "ws://" : "wss://") + b + D;
|
|
2345
|
+
return new W(s);
|
|
2342
2346
|
}
|
|
2343
2347
|
return (async () => {
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
+
L = await A(L, b, l);
|
|
2349
|
+
let s = { method: k?.toUpperCase(), body: a2, ...G, headers: L };
|
|
2350
|
+
s.headers = { ...L, ...await A(E ? a2?.headers : l?.headers, b, s) };
|
|
2351
|
+
let m = E && typeof a2 == "object" ? a2.fetch : l?.fetch, T = (E && typeof a2 == "object" ? a2.throwHttpError : l?.throwHttpError) ?? t.throwHttpError;
|
|
2352
|
+
if (s = { ...s, ...m }, E && delete s.body, g2) {
|
|
2348
2353
|
Array.isArray(g2) || (g2 = [g2]);
|
|
2349
|
-
for (let
|
|
2350
|
-
let
|
|
2351
|
-
typeof
|
|
2354
|
+
for (let u2 of g2) {
|
|
2355
|
+
let o2 = await u2(b, s);
|
|
2356
|
+
typeof o2 == "object" && (s = { ...s, ...o2, headers: { ...s.headers, ...await A(o2.headers, b, s) } });
|
|
2352
2357
|
}
|
|
2353
2358
|
}
|
|
2354
|
-
if (
|
|
2355
|
-
let
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2359
|
+
if (E && delete s.body, X(a2)) {
|
|
2360
|
+
let u2 = new FormData, o2 = (f2) => {
|
|
2361
|
+
if (typeof f2 == "string" || H(f2))
|
|
2362
|
+
return false;
|
|
2363
|
+
if (typeof f2 == "object") {
|
|
2364
|
+
if (f2 !== null)
|
|
2365
|
+
return true;
|
|
2366
|
+
if (f2 instanceof Date)
|
|
2367
|
+
return false;
|
|
2368
|
+
}
|
|
2369
|
+
return false;
|
|
2370
|
+
}, w = async (f2) => f2 instanceof File ? await K(f2) : o2(f2) ? JSON.stringify(f2) : f2;
|
|
2371
|
+
for (let [f2, p2] of Object.entries(s.body)) {
|
|
2372
|
+
if (Array.isArray(p2)) {
|
|
2373
|
+
if (p2.some((S2) => typeof S2 == "object" && S2 !== null && !H(S2)))
|
|
2374
|
+
u2.append(f2, JSON.stringify(p2));
|
|
2375
|
+
else
|
|
2376
|
+
for (let S2 = 0;S2 < p2.length; S2++) {
|
|
2377
|
+
let $ = p2[S2], z = await w($);
|
|
2378
|
+
u2.append(f2, z);
|
|
2379
|
+
}
|
|
2362
2380
|
continue;
|
|
2363
2381
|
}
|
|
2364
|
-
if (
|
|
2365
|
-
if (Array.isArray(
|
|
2366
|
-
for (let
|
|
2367
|
-
|
|
2382
|
+
if (q) {
|
|
2383
|
+
if (Array.isArray(p2))
|
|
2384
|
+
for (let x of p2)
|
|
2385
|
+
u2.append(f2, await w(x));
|
|
2368
2386
|
else
|
|
2369
|
-
|
|
2387
|
+
u2.append(f2, await w(p2));
|
|
2370
2388
|
continue;
|
|
2371
2389
|
}
|
|
2372
|
-
if (
|
|
2373
|
-
|
|
2390
|
+
if (p2 instanceof File) {
|
|
2391
|
+
u2.append(f2, await K(p2));
|
|
2374
2392
|
continue;
|
|
2375
2393
|
}
|
|
2376
|
-
if (
|
|
2377
|
-
for (let
|
|
2378
|
-
|
|
2394
|
+
if (p2 instanceof FileList) {
|
|
2395
|
+
for (let x = 0;x < p2.length; x++)
|
|
2396
|
+
u2.append(f2, await K(p2[x]));
|
|
2379
2397
|
continue;
|
|
2380
2398
|
}
|
|
2381
|
-
|
|
2399
|
+
u2.append(f2, await w(p2));
|
|
2382
2400
|
}
|
|
2383
|
-
|
|
2401
|
+
s.body = u2;
|
|
2384
2402
|
} else
|
|
2385
|
-
typeof
|
|
2386
|
-
if (
|
|
2403
|
+
typeof a2 == "object" ? (s.headers["content-type"] = "application/json", s.body = JSON.stringify(a2)) : a2 != null && (s.headers["content-type"] = "text/plain");
|
|
2404
|
+
if (E && delete s.body, g2) {
|
|
2387
2405
|
Array.isArray(g2) || (g2 = [g2]);
|
|
2388
|
-
for (let
|
|
2389
|
-
let
|
|
2390
|
-
typeof
|
|
2406
|
+
for (let u2 of g2) {
|
|
2407
|
+
let o2 = await u2(b, s);
|
|
2408
|
+
typeof o2 == "object" && (s = { ...s, ...o2, headers: { ...s.headers, ...await A(o2.headers, b, s) } });
|
|
2391
2409
|
}
|
|
2392
2410
|
}
|
|
2393
|
-
|
|
2394
|
-
let
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2411
|
+
l?.headers?.["content-type"] && (s.headers["content-type"] = l?.headers["content-type"]);
|
|
2412
|
+
let I = e + b + D, y;
|
|
2413
|
+
try {
|
|
2414
|
+
y = await (r?.handle(new Request(I, s)) ?? V(I, s));
|
|
2415
|
+
} catch (u2) {
|
|
2416
|
+
let o2 = new d(503, u2);
|
|
2417
|
+
if (P(o2, T))
|
|
2418
|
+
throw o2;
|
|
2419
|
+
return { data: null, error: o2, response: undefined, status: 503, headers: undefined };
|
|
2420
|
+
}
|
|
2421
|
+
let h = null, v = null;
|
|
2422
|
+
if (R) {
|
|
2423
|
+
Array.isArray(R) || (R = [R]);
|
|
2424
|
+
for (let u2 of R)
|
|
2398
2425
|
try {
|
|
2399
|
-
let
|
|
2400
|
-
if (
|
|
2401
|
-
|
|
2426
|
+
let o2 = await u2(y.clone());
|
|
2427
|
+
if (o2 != null) {
|
|
2428
|
+
h = o2;
|
|
2402
2429
|
break;
|
|
2403
2430
|
}
|
|
2404
|
-
} catch (
|
|
2405
|
-
|
|
2431
|
+
} catch (o2) {
|
|
2432
|
+
o2 instanceof d ? v = o2 : v = new d(422, o2);
|
|
2406
2433
|
break;
|
|
2407
2434
|
}
|
|
2408
2435
|
}
|
|
2409
|
-
if (
|
|
2410
|
-
return { data:
|
|
2436
|
+
if (h !== null)
|
|
2437
|
+
return { data: h, error: v, response: y, status: y.status, headers: y.headers };
|
|
2411
2438
|
switch (y.headers.get("Content-Type")?.split(";")[0]) {
|
|
2412
2439
|
case "text/event-stream":
|
|
2413
|
-
|
|
2440
|
+
h = Y(y, { parseDate: t.parseDate });
|
|
2414
2441
|
break;
|
|
2415
2442
|
case "application/json":
|
|
2416
|
-
|
|
2417
|
-
if (typeof
|
|
2418
|
-
return
|
|
2419
|
-
let
|
|
2420
|
-
return
|
|
2443
|
+
h = JSON.parse(await y.text(), (o2, w) => {
|
|
2444
|
+
if (typeof w != "string")
|
|
2445
|
+
return w;
|
|
2446
|
+
let f2 = a(w, { parseDate: t.parseDate });
|
|
2447
|
+
return f2 || w;
|
|
2421
2448
|
});
|
|
2422
2449
|
break;
|
|
2423
2450
|
case "application/octet-stream":
|
|
2424
|
-
|
|
2451
|
+
h = await y.arrayBuffer();
|
|
2425
2452
|
break;
|
|
2426
2453
|
case "multipart/form-data":
|
|
2427
|
-
let
|
|
2428
|
-
|
|
2429
|
-
|
|
2454
|
+
let u2 = await y.formData();
|
|
2455
|
+
h = {}, u2.forEach((o2, w) => {
|
|
2456
|
+
h[w] = o2;
|
|
2430
2457
|
});
|
|
2431
2458
|
break;
|
|
2432
2459
|
default:
|
|
2433
|
-
|
|
2460
|
+
h = await y.text().then((o2) => g(o2, { parseDate: t.parseDate }));
|
|
2461
|
+
}
|
|
2462
|
+
if (y.status >= 300 || y.status < 200) {
|
|
2463
|
+
if (v = new d(y.status, h), P(v, T))
|
|
2464
|
+
throw v;
|
|
2465
|
+
h = null;
|
|
2434
2466
|
}
|
|
2435
|
-
return
|
|
2467
|
+
return { data: h, error: v, response: y, status: y.status, headers: y.headers };
|
|
2436
2468
|
})();
|
|
2437
2469
|
}
|
|
2438
|
-
return typeof
|
|
2470
|
+
return typeof a2 == "object" ? F(e, t, [...n, Object.values(a2)[0]], r) : F(e, t, n);
|
|
2439
2471
|
} });
|
|
2440
|
-
var
|
|
2472
|
+
var se = (e, t = {}) => typeof e == "string" ? (t.keepDomain || (e.includes("://") || (e = (U.find((n) => e.includes(n)) ? "http://" : "https://") + e), e.endsWith("/") && (e = e.slice(0, -1))), F(e, t)) : (typeof window < "u" && console.warn("Elysia instance server found on client side, this is not recommended for security reason. Use generic type instead."), F("http://e.ly", t, [], e));
|
|
2441
2473
|
|
|
2442
2474
|
// src/api.ts
|
|
2443
2475
|
function getApi() {
|
|
@@ -2445,14 +2477,16 @@ function getApi() {
|
|
|
2445
2477
|
if (!config) {
|
|
2446
2478
|
throw new Error("Not logged in. Run: dblx auth login");
|
|
2447
2479
|
}
|
|
2448
|
-
return
|
|
2480
|
+
return se(config.api_url, {
|
|
2481
|
+
parseDate: false,
|
|
2449
2482
|
headers: {
|
|
2450
2483
|
Authorization: `Bearer ${config.api_key}`
|
|
2451
2484
|
}
|
|
2452
2485
|
});
|
|
2453
2486
|
}
|
|
2454
2487
|
function getApiWith(apiKey, apiUrl) {
|
|
2455
|
-
return
|
|
2488
|
+
return se(apiUrl, {
|
|
2489
|
+
parseDate: false,
|
|
2456
2490
|
headers: {
|
|
2457
2491
|
Authorization: `Bearer ${apiKey}`
|
|
2458
2492
|
}
|
|
@@ -2543,7 +2577,7 @@ var authCommand = new Command("auth").description("Manage authentication").addCo
|
|
|
2543
2577
|
console.log("Logged out. Config removed.");
|
|
2544
2578
|
}));
|
|
2545
2579
|
|
|
2546
|
-
// src/commands/
|
|
2580
|
+
// src/commands/helpers.ts
|
|
2547
2581
|
function threadRows(threads) {
|
|
2548
2582
|
return threads.map((t) => ({
|
|
2549
2583
|
id: t.id.slice(0, 8),
|
|
@@ -2553,10 +2587,29 @@ function threadRows(threads) {
|
|
|
2553
2587
|
snoozed: t.snoozed ? "snoozed" : ""
|
|
2554
2588
|
}));
|
|
2555
2589
|
}
|
|
2556
|
-
|
|
2590
|
+
function localDate(dateArg) {
|
|
2591
|
+
if (dateArg)
|
|
2592
|
+
return dateArg;
|
|
2593
|
+
const now = new Date;
|
|
2594
|
+
const y = now.getFullYear();
|
|
2595
|
+
const m = String(now.getMonth() + 1).padStart(2, "0");
|
|
2596
|
+
const d2 = String(now.getDate()).padStart(2, "0");
|
|
2597
|
+
return `${y}-${m}-${d2}`;
|
|
2598
|
+
}
|
|
2599
|
+
function parseBooleanish(value) {
|
|
2600
|
+
if (value === "true")
|
|
2601
|
+
return true;
|
|
2602
|
+
if (value === "false")
|
|
2603
|
+
return false;
|
|
2604
|
+
throw new InvalidArgumentError('Expected "true" or "false".');
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
// src/commands/get.ts
|
|
2608
|
+
var getCommand = new Command("get").description("Read data from dblebox").addCommand(new Command("threads").description("List or search your threads").option("--q <query>", "Filter by partial title/body text").option("--json", "Output as JSON").option("--archived", "Include archived threads").option("--snoozed", "Include snoozed threads").action(async (opts) => {
|
|
2557
2609
|
const api = getApi();
|
|
2558
2610
|
const { data, error } = await api.api.cli.v1.threads.get({
|
|
2559
2611
|
query: {
|
|
2612
|
+
q: opts.q,
|
|
2560
2613
|
archived: opts.archived ? "true" : undefined,
|
|
2561
2614
|
snoozed: opts.snoozed ? "true" : undefined
|
|
2562
2615
|
}
|
|
@@ -2568,64 +2621,56 @@ var threadsCommand = new Command("threads").description("Manage threads").addCom
|
|
|
2568
2621
|
return;
|
|
2569
2622
|
}
|
|
2570
2623
|
output(threadRows(data.threads), { json: false });
|
|
2571
|
-
})).addCommand(new Command("
|
|
2624
|
+
})).addCommand(new Command("today").description("Show threads and note for a date").option("--date <date>", "Date (YYYY-MM-DD)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2625
|
+
const date = localDate(opts.date);
|
|
2572
2626
|
const api = getApi();
|
|
2573
|
-
const { data, error } = await api.api.cli.v1.
|
|
2574
|
-
query: {
|
|
2575
|
-
q: query,
|
|
2576
|
-
archived: opts.archived ? "true" : undefined,
|
|
2577
|
-
snoozed: opts.snoozed ? "true" : undefined
|
|
2578
|
-
}
|
|
2627
|
+
const { data, error } = await api.api.cli.v1.today.get({
|
|
2628
|
+
query: { date }
|
|
2579
2629
|
});
|
|
2580
2630
|
if (error)
|
|
2581
2631
|
throw error;
|
|
2582
2632
|
if (opts.json) {
|
|
2583
|
-
output(data
|
|
2633
|
+
output(data, { json: true });
|
|
2584
2634
|
return;
|
|
2585
2635
|
}
|
|
2586
|
-
|
|
2587
|
-
|
|
2636
|
+
console.log(`Date: ${data.date}
|
|
2637
|
+
`);
|
|
2638
|
+
if (data.threads.length > 0) {
|
|
2639
|
+
console.log("Threads:");
|
|
2640
|
+
for (const t of data.threads) {
|
|
2641
|
+
console.log(` ${t.id.slice(0, 8)} ${t.body}`);
|
|
2642
|
+
}
|
|
2643
|
+
console.log();
|
|
2644
|
+
} else {
|
|
2645
|
+
console.log(`No threads for this date.
|
|
2646
|
+
`);
|
|
2647
|
+
}
|
|
2648
|
+
if (data.note) {
|
|
2649
|
+
console.log("Note:");
|
|
2650
|
+
console.log(data.note.content || "(empty)");
|
|
2651
|
+
} else {
|
|
2652
|
+
console.log("No daily note.");
|
|
2653
|
+
}
|
|
2654
|
+
})).addCommand(new Command("thread-note").description("Read a thread note").argument("<thread-id>", "Thread ID").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2588
2655
|
const api = getApi();
|
|
2589
|
-
const
|
|
2590
|
-
const { data, error } = await api.api.cli.v1.threads.post({
|
|
2591
|
-
body: opts.title,
|
|
2592
|
-
comment: opts.comment,
|
|
2593
|
-
note_content: noteContent
|
|
2594
|
-
});
|
|
2656
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).note.get();
|
|
2595
2657
|
if (error)
|
|
2596
2658
|
throw error;
|
|
2597
2659
|
if (opts.json) {
|
|
2598
2660
|
output(data, { json: true });
|
|
2599
2661
|
return;
|
|
2600
2662
|
}
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
})).addCommand(new Command("update").description("Update a thread title").argument("<id>", "Thread ID").requiredOption("--title <title>", "New title").option("--json", "Output as JSON").action(async (id, opts) => {
|
|
2604
|
-
const api = getApi();
|
|
2605
|
-
const { data, error } = await api.api.cli.v1.threads({ id }).put({
|
|
2606
|
-
body: opts.title
|
|
2607
|
-
});
|
|
2608
|
-
if (error)
|
|
2609
|
-
throw error;
|
|
2610
|
-
if (opts.json) {
|
|
2611
|
-
output(data.thread, { json: true });
|
|
2663
|
+
if (!data.note) {
|
|
2664
|
+
console.log("No thread note.");
|
|
2612
2665
|
return;
|
|
2613
2666
|
}
|
|
2614
|
-
console.log(
|
|
2615
|
-
})).addCommand(new Command("note").description("Read
|
|
2667
|
+
console.log(data.note.content || "(empty)");
|
|
2668
|
+
})).addCommand(new Command("today-note").description("Read a daily note").option("--date <date>", "Date (YYYY-MM-DD)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2669
|
+
const date = localDate(opts.date);
|
|
2616
2670
|
const api = getApi();
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
throw error2;
|
|
2621
|
-
if (opts.json) {
|
|
2622
|
-
output(data2, { json: true });
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
|
-
console.log("Note updated.");
|
|
2626
|
-
return;
|
|
2627
|
-
}
|
|
2628
|
-
const { data, error } = await api.api.cli.v1.threads({ id }).note.get();
|
|
2671
|
+
const { data, error } = await api.api.cli.v1.today.note.get({
|
|
2672
|
+
query: { date }
|
|
2673
|
+
});
|
|
2629
2674
|
if (error)
|
|
2630
2675
|
throw error;
|
|
2631
2676
|
if (opts.json) {
|
|
@@ -2633,70 +2678,11 @@ var threadsCommand = new Command("threads").description("Manage threads").addCom
|
|
|
2633
2678
|
return;
|
|
2634
2679
|
}
|
|
2635
2680
|
if (!data.note) {
|
|
2636
|
-
console.log("No
|
|
2681
|
+
console.log("No daily note.");
|
|
2637
2682
|
return;
|
|
2638
2683
|
}
|
|
2639
2684
|
console.log(data.note.content || "(empty)");
|
|
2640
|
-
})).addCommand(new Command("
|
|
2641
|
-
const api = getApi();
|
|
2642
|
-
const { error } = await api.api.cli.v1.threads({ id }).archive.put({
|
|
2643
|
-
archived: true
|
|
2644
|
-
});
|
|
2645
|
-
if (error)
|
|
2646
|
-
throw error;
|
|
2647
|
-
console.log("Archived.");
|
|
2648
|
-
})).addCommand(new Command("unarchive").description("Unarchive a thread").argument("<id>", "Thread ID").action(async (id) => {
|
|
2649
|
-
const api = getApi();
|
|
2650
|
-
const { error } = await api.api.cli.v1.threads({ id }).archive.put({
|
|
2651
|
-
archived: false
|
|
2652
|
-
});
|
|
2653
|
-
if (error)
|
|
2654
|
-
throw error;
|
|
2655
|
-
console.log("Unarchived.");
|
|
2656
|
-
})).addCommand(new Command("snooze").description("Snooze a thread").argument("<id>", "Thread ID").requiredOption("--until <datetime>", "Snooze until (ISO datetime)").action(async (id, opts) => {
|
|
2657
|
-
const api = getApi();
|
|
2658
|
-
const { error } = await api.api.cli.v1.threads({ id }).snooze.put({
|
|
2659
|
-
until: opts.until
|
|
2660
|
-
});
|
|
2661
|
-
if (error)
|
|
2662
|
-
throw error;
|
|
2663
|
-
console.log(`Snoozed until ${opts.until}.`);
|
|
2664
|
-
})).addCommand(new Command("unsnooze").description("Remove snooze from a thread").argument("<id>", "Thread ID").action(async (id) => {
|
|
2665
|
-
const api = getApi();
|
|
2666
|
-
const { error } = await api.api.cli.v1.threads({ id }).snooze.put({
|
|
2667
|
-
until: null
|
|
2668
|
-
});
|
|
2669
|
-
if (error)
|
|
2670
|
-
throw error;
|
|
2671
|
-
console.log("Unsnoozed.");
|
|
2672
|
-
})).addCommand(new Command("set-parent").description("Set a parent thread").argument("<id>", "Thread ID").requiredOption("--parent <parent-id>", "Parent thread ID").action(async (id, opts) => {
|
|
2673
|
-
const api = getApi();
|
|
2674
|
-
const { error } = await api.api.cli.v1.threads({ id }).parent.put({
|
|
2675
|
-
parent_id: opts.parent
|
|
2676
|
-
});
|
|
2677
|
-
if (error)
|
|
2678
|
-
throw error;
|
|
2679
|
-
console.log(`Parent set to ${opts.parent.slice(0, 8)}.`);
|
|
2680
|
-
})).addCommand(new Command("set-today").description("Assign thread to a date").argument("<id>", "Thread ID").option("--date <date>", "Date (YYYY-MM-DD)", new Date().toISOString().slice(0, 10)).action(async (id, opts) => {
|
|
2681
|
-
const api = getApi();
|
|
2682
|
-
const { error } = await api.api.cli.v1.threads({ id }).today.put({
|
|
2683
|
-
date: opts.date
|
|
2684
|
-
});
|
|
2685
|
-
if (error)
|
|
2686
|
-
throw error;
|
|
2687
|
-
console.log(`Assigned to ${opts.date}.`);
|
|
2688
|
-
})).addCommand(new Command("unset-today").description("Remove thread from a date").argument("<id>", "Thread ID").option("--date <date>", "Date (YYYY-MM-DD)", new Date().toISOString().slice(0, 10)).action(async (id, opts) => {
|
|
2689
|
-
const api = getApi();
|
|
2690
|
-
const { error } = await api.api.cli.v1.threads({ id }).today.delete({
|
|
2691
|
-
date: opts.date
|
|
2692
|
-
});
|
|
2693
|
-
if (error)
|
|
2694
|
-
throw error;
|
|
2695
|
-
console.log(`Removed from ${opts.date}.`);
|
|
2696
|
-
}));
|
|
2697
|
-
|
|
2698
|
-
// src/commands/comments.ts
|
|
2699
|
-
var commentsCommand = new Command("comments").description("Manage comments").addCommand(new Command("list").description("List comments in a thread").requiredOption("--thread <id>", "Thread ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
2685
|
+
})).addCommand(new Command("comments").description("List comments in a thread").requiredOption("--thread <id>", "Thread ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
2700
2686
|
const api = getApi();
|
|
2701
2687
|
const { data, error } = await api.api.cli.v1.threads({ id: opts.thread }).comments.get();
|
|
2702
2688
|
if (error)
|
|
@@ -2712,111 +2698,155 @@ var commentsCommand = new Command("comments").description("Manage comments").add
|
|
|
2712
2698
|
created_at: c2.created_at
|
|
2713
2699
|
}));
|
|
2714
2700
|
output(rows, { json: false });
|
|
2715
|
-
})).addCommand(new Command("
|
|
2701
|
+
})).addCommand(new Command("members").description("List members of a thread").argument("<thread-id>", "Thread ID").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2716
2702
|
const api = getApi();
|
|
2717
|
-
const { data, error } = await api.api.cli.v1.threads({ id:
|
|
2703
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).members.get();
|
|
2718
2704
|
if (error)
|
|
2719
2705
|
throw error;
|
|
2720
2706
|
if (opts.json) {
|
|
2721
|
-
output(data.
|
|
2707
|
+
output(data.members, { json: true });
|
|
2722
2708
|
return;
|
|
2723
2709
|
}
|
|
2724
|
-
|
|
2725
|
-
|
|
2710
|
+
const rows = data.members.filter((m) => !m.revoked_at).map((m) => ({
|
|
2711
|
+
username: m.username,
|
|
2712
|
+
email: m.email
|
|
2713
|
+
}));
|
|
2714
|
+
output(rows, { json: false });
|
|
2715
|
+
}));
|
|
2716
|
+
|
|
2717
|
+
// src/commands/create.ts
|
|
2718
|
+
var createCommand2 = new Command("create").description("Create new dblebox objects").addCommand(new Command("thread").description("Create a thread").requiredOption("--title <title>", "Thread title").option("--comment <text>", "Optional first comment").option("--note <content>", "Create and attach a block note with content").option("--json", "Output as JSON").action(async (opts) => {
|
|
2726
2719
|
const api = getApi();
|
|
2727
|
-
const
|
|
2720
|
+
const noteContent = opts.note !== undefined ? opts.note : undefined;
|
|
2721
|
+
const { data, error } = await api.api.cli.v1.threads.post({
|
|
2722
|
+
body: opts.title,
|
|
2723
|
+
comment: opts.comment,
|
|
2724
|
+
note_content: noteContent
|
|
2725
|
+
});
|
|
2726
|
+
if (error)
|
|
2727
|
+
throw error;
|
|
2728
|
+
if (opts.json) {
|
|
2729
|
+
output(data, { json: true });
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2732
|
+
const noteSuffix = data.note ? ` (note ${data.note.id.slice(0, 8)} attached)` : "";
|
|
2733
|
+
console.log(`Created thread ${data.thread.id.slice(0, 8)}: ${data.thread.body}${noteSuffix}`);
|
|
2734
|
+
})).addCommand(new Command("comment").description("Add a comment to a thread").requiredOption("--thread <id>", "Thread ID").requiredOption("--body <text>", "Comment text").option("--json", "Output as JSON").action(async (opts) => {
|
|
2735
|
+
const api = getApi();
|
|
2736
|
+
const { data, error } = await api.api.cli.v1.threads({ id: opts.thread }).comments.post({ body: opts.body });
|
|
2728
2737
|
if (error)
|
|
2729
2738
|
throw error;
|
|
2730
2739
|
if (opts.json) {
|
|
2731
2740
|
output(data.comment, { json: true });
|
|
2732
2741
|
return;
|
|
2733
2742
|
}
|
|
2734
|
-
console.log(`Comment
|
|
2743
|
+
console.log(`Comment added (${data.comment.id.slice(0, 8)}).`);
|
|
2735
2744
|
}));
|
|
2736
2745
|
|
|
2737
|
-
// src/commands/
|
|
2738
|
-
var
|
|
2746
|
+
// src/commands/set.ts
|
|
2747
|
+
var setCommand = new Command("set").description("Update existing dblebox objects").addCommand(new Command("thread").description("Update thread title, archive state, or snooze state").argument("<thread-id>", "Thread ID").option("--title <title>", "New thread title").option("--archived <true|false>", "Set archived state", parseBooleanish).option("--snoozed-until <datetime-or-none>", 'Set snooze until (ISO datetime), or "none" to clear').option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2739
2748
|
const api = getApi();
|
|
2740
|
-
const
|
|
2741
|
-
|
|
2742
|
-
|
|
2749
|
+
const result = {};
|
|
2750
|
+
const messages = [];
|
|
2751
|
+
if (opts.title !== undefined) {
|
|
2752
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).put({
|
|
2753
|
+
body: opts.title
|
|
2754
|
+
});
|
|
2755
|
+
if (error)
|
|
2756
|
+
throw error;
|
|
2757
|
+
result.thread = data.thread;
|
|
2758
|
+
messages.push(`Updated thread ${data.thread.id.slice(0, 8)}: ${data.thread.body}`);
|
|
2759
|
+
}
|
|
2760
|
+
if (opts.archived !== undefined) {
|
|
2761
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).archive.put({
|
|
2762
|
+
archived: opts.archived
|
|
2763
|
+
});
|
|
2764
|
+
if (error)
|
|
2765
|
+
throw error;
|
|
2766
|
+
result.archived = data.archived;
|
|
2767
|
+
messages.push(data.archived ? "Archived." : "Unarchived.");
|
|
2768
|
+
}
|
|
2769
|
+
if (opts.snoozedUntil !== undefined) {
|
|
2770
|
+
const until = opts.snoozedUntil === "none" ? null : opts.snoozedUntil;
|
|
2771
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).snooze.put({
|
|
2772
|
+
until
|
|
2773
|
+
});
|
|
2774
|
+
if (error)
|
|
2775
|
+
throw error;
|
|
2776
|
+
result.snooze_until = data.snooze_until;
|
|
2777
|
+
messages.push(data.snooze_until ? `Snoozed until ${data.snooze_until}.` : "Unsnoozed.");
|
|
2778
|
+
}
|
|
2779
|
+
if (messages.length === 0) {
|
|
2780
|
+
throw new Error("No updates specified. Provide --title, --archived, or --snoozed-until.");
|
|
2781
|
+
}
|
|
2743
2782
|
if (opts.json) {
|
|
2744
|
-
output(
|
|
2783
|
+
output(result, { json: true });
|
|
2745
2784
|
return;
|
|
2746
2785
|
}
|
|
2747
|
-
const
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
output(rows, { json: false });
|
|
2752
|
-
})).addCommand(new Command("invite").description("Invite a user to a thread").argument("<thread-id>", "Thread ID").requiredOption("--user <email-or-username>", "User email or username").action(async (threadId, opts) => {
|
|
2786
|
+
for (const message of messages) {
|
|
2787
|
+
console.log(message);
|
|
2788
|
+
}
|
|
2789
|
+
})).addCommand(new Command("thread-note").description("Create or update a thread note").argument("<thread-id>", "Thread ID").requiredOption("--content <content>", "Note content").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2753
2790
|
const api = getApi();
|
|
2754
|
-
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).
|
|
2791
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).note.put({ content: opts.content });
|
|
2755
2792
|
if (error)
|
|
2756
2793
|
throw error;
|
|
2757
|
-
if (
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
console.log(data.reason || "Could not invite user.");
|
|
2794
|
+
if (opts.json) {
|
|
2795
|
+
output(data, { json: true });
|
|
2796
|
+
return;
|
|
2761
2797
|
}
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
// src/commands/today.ts
|
|
2765
|
-
function localDate(dateArg) {
|
|
2766
|
-
if (dateArg)
|
|
2767
|
-
return dateArg;
|
|
2768
|
-
const now = new Date;
|
|
2769
|
-
const y = now.getFullYear();
|
|
2770
|
-
const m = String(now.getMonth() + 1).padStart(2, "0");
|
|
2771
|
-
const d2 = String(now.getDate()).padStart(2, "0");
|
|
2772
|
-
return `${y}-${m}-${d2}`;
|
|
2773
|
-
}
|
|
2774
|
-
var todayCommand = new Command("today").description("Today view — threads and daily note").enablePositionalOptions().passThroughOptions().option("--date <date>", "Date (YYYY-MM-DD)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2798
|
+
console.log("Note updated.");
|
|
2799
|
+
})).addCommand(new Command("today-note").description("Create or update a daily note").requiredOption("--content <content>", "Note content").option("--date <date>", "Date (YYYY-MM-DD)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2775
2800
|
const date = localDate(opts.date);
|
|
2776
2801
|
const api = getApi();
|
|
2777
|
-
const { data, error } = await api.api.cli.v1.today.
|
|
2778
|
-
query: { date }
|
|
2779
|
-
});
|
|
2802
|
+
const { data, error } = await api.api.cli.v1.today.note.put({ content: opts.content }, { query: { date } });
|
|
2780
2803
|
if (error)
|
|
2781
2804
|
throw error;
|
|
2782
2805
|
if (opts.json) {
|
|
2783
2806
|
output(data, { json: true });
|
|
2784
2807
|
return;
|
|
2785
2808
|
}
|
|
2786
|
-
console.log(
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
console.log(`No threads for this date.
|
|
2796
|
-
`);
|
|
2809
|
+
console.log("Note updated.");
|
|
2810
|
+
})).addCommand(new Command("comment").description("Edit a comment").argument("<comment-id>", "Comment ID").requiredOption("--body <text>", "New comment text").option("--json", "Output as JSON").action(async (commentId, opts) => {
|
|
2811
|
+
const api = getApi();
|
|
2812
|
+
const { data, error } = await api.api.cli.v1.comments({ id: commentId }).put({ body: opts.body });
|
|
2813
|
+
if (error)
|
|
2814
|
+
throw error;
|
|
2815
|
+
if (opts.json) {
|
|
2816
|
+
output(data.comment, { json: true });
|
|
2817
|
+
return;
|
|
2797
2818
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2819
|
+
console.log(`Comment updated (${data.comment.id.slice(0, 8)}).`);
|
|
2820
|
+
})).addCommand(new Command("thread-parent").description("Set a thread parent").argument("<thread-id>", "Thread ID").requiredOption("--parent <parent-id>", "Parent thread ID").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2821
|
+
const api = getApi();
|
|
2822
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).parent.put({
|
|
2823
|
+
parent_id: opts.parent
|
|
2824
|
+
});
|
|
2825
|
+
if (error)
|
|
2826
|
+
throw error;
|
|
2827
|
+
if (opts.json) {
|
|
2828
|
+
output(data.thread, { json: true });
|
|
2829
|
+
return;
|
|
2803
2830
|
}
|
|
2804
|
-
|
|
2831
|
+
console.log(`Parent set to ${opts.parent.slice(0, 8)}.`);
|
|
2832
|
+
})).addCommand(new Command("thread-today").description("Assign or remove a thread from a date").argument("<thread-id>", "Thread ID").option("--date <date>", "Date (YYYY-MM-DD)").option("--remove", "Remove instead of assign").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2805
2833
|
const date = localDate(opts.date);
|
|
2806
2834
|
const api = getApi();
|
|
2807
|
-
if (opts.
|
|
2808
|
-
const { data: data2, error: error2 } = await api.api.cli.v1.
|
|
2835
|
+
if (opts.remove) {
|
|
2836
|
+
const { data: data2, error: error2 } = await api.api.cli.v1.threads({ id: threadId }).today.delete({
|
|
2837
|
+
date
|
|
2838
|
+
});
|
|
2809
2839
|
if (error2)
|
|
2810
2840
|
throw error2;
|
|
2811
2841
|
if (opts.json) {
|
|
2812
2842
|
output(data2, { json: true });
|
|
2813
2843
|
return;
|
|
2814
2844
|
}
|
|
2815
|
-
console.log(
|
|
2845
|
+
console.log(`Removed from ${date}.`);
|
|
2816
2846
|
return;
|
|
2817
2847
|
}
|
|
2818
|
-
const { data, error } = await api.api.cli.v1.today.
|
|
2819
|
-
|
|
2848
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).today.put({
|
|
2849
|
+
date
|
|
2820
2850
|
});
|
|
2821
2851
|
if (error)
|
|
2822
2852
|
throw error;
|
|
@@ -2824,16 +2854,29 @@ var todayCommand = new Command("today").description("Today view — threads and
|
|
|
2824
2854
|
output(data, { json: true });
|
|
2825
2855
|
return;
|
|
2826
2856
|
}
|
|
2827
|
-
|
|
2828
|
-
|
|
2857
|
+
console.log(`Assigned to ${date}.`);
|
|
2858
|
+
}));
|
|
2859
|
+
|
|
2860
|
+
// src/commands/invite.ts
|
|
2861
|
+
var inviteCommand = new Command("invite").description("Invite collaborators").addCommand(new Command("member").description("Invite a user to a thread").argument("<thread-id>", "Thread ID").requiredOption("--user <email-or-username>", "User email or username").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2862
|
+
const api = getApi();
|
|
2863
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).members.post({ user: opts.user });
|
|
2864
|
+
if (error)
|
|
2865
|
+
throw error;
|
|
2866
|
+
if (opts.json) {
|
|
2867
|
+
output(data, { json: true });
|
|
2829
2868
|
return;
|
|
2830
2869
|
}
|
|
2831
|
-
|
|
2870
|
+
if (data.invited) {
|
|
2871
|
+
console.log(`Invited ${data.user?.username || opts.user}.`);
|
|
2872
|
+
} else {
|
|
2873
|
+
console.log(data.reason || "Could not invite user.");
|
|
2874
|
+
}
|
|
2832
2875
|
}));
|
|
2833
2876
|
// package.json
|
|
2834
2877
|
var package_default = {
|
|
2835
2878
|
name: "dblx",
|
|
2836
|
-
version: "0.1.
|
|
2879
|
+
version: "0.1.63",
|
|
2837
2880
|
description: "CLI for dblebox — thread-first communication",
|
|
2838
2881
|
type: "module",
|
|
2839
2882
|
bin: {
|
|
@@ -2860,10 +2903,10 @@ var package_default = {
|
|
|
2860
2903
|
// src/index.ts
|
|
2861
2904
|
var program2 = new Command().name("dblx").description("CLI for dblebox — thread-first communication").version(package_default.version).enablePositionalOptions();
|
|
2862
2905
|
program2.addCommand(authCommand);
|
|
2863
|
-
program2.addCommand(
|
|
2864
|
-
program2.addCommand(
|
|
2865
|
-
program2.addCommand(
|
|
2866
|
-
program2.addCommand(
|
|
2906
|
+
program2.addCommand(getCommand);
|
|
2907
|
+
program2.addCommand(createCommand2);
|
|
2908
|
+
program2.addCommand(setCommand);
|
|
2909
|
+
program2.addCommand(inviteCommand);
|
|
2867
2910
|
program2.parseAsync().catch((err) => {
|
|
2868
2911
|
console.error(err.message);
|
|
2869
2912
|
process.exit(1);
|