dblx 0.1.50 → 0.1.64
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 +122 -42
- package/dist/index.js +445 -359
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,81 +4,161 @@ 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]
|
|
7
11
|
```
|
|
8
|
-
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
dblx get threads
|
|
17
|
+
dblx get threads <thread-id>
|
|
18
|
+
dblx get threads --q "planning"
|
|
19
|
+
dblx get today
|
|
20
|
+
dblx create thread --title "New thread"
|
|
21
|
+
dblx set thread 12345678 --title "Renamed"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Command Model
|
|
25
|
+
|
|
26
|
+
Read operations use `get`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
dblx get ...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Write operations use `create`, `set`, and `invite`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
dblx create ...
|
|
36
|
+
dblx set ...
|
|
37
|
+
dblx invite ...
|
|
9
38
|
```
|
|
10
39
|
|
|
40
|
+
This keeps permission boundaries clear for agents and automation. A tool can be granted `dblx get ...` without also gaining write access.
|
|
41
|
+
|
|
11
42
|
## Authentication
|
|
12
43
|
|
|
13
44
|
Generate an API key from **Settings > API Keys** in the dblebox web app, then:
|
|
14
45
|
|
|
15
|
-
```
|
|
46
|
+
```bash
|
|
16
47
|
dblx auth login
|
|
17
48
|
```
|
|
18
49
|
|
|
19
50
|
You'll be prompted for your key (starts with `dblx_`). Credentials are saved to `~/.config/dblx.json`.
|
|
20
51
|
|
|
21
|
-
```
|
|
22
|
-
dblx auth whoami
|
|
23
|
-
dblx auth logout
|
|
52
|
+
```bash
|
|
53
|
+
dblx auth whoami
|
|
54
|
+
dblx auth logout
|
|
24
55
|
```
|
|
25
56
|
|
|
26
57
|
You can also set `DBLEBOX_API_KEY` and `DBLEBOX_API_URL` environment variables instead of using `auth login`.
|
|
27
58
|
|
|
28
|
-
##
|
|
59
|
+
## Read Commands
|
|
60
|
+
|
|
61
|
+
### Threads
|
|
29
62
|
|
|
63
|
+
```bash
|
|
64
|
+
dblx get threads
|
|
65
|
+
dblx get threads <thread-id>
|
|
66
|
+
dblx get threads --archived
|
|
67
|
+
dblx get threads --snoozed
|
|
68
|
+
dblx get threads --archived --snoozed
|
|
69
|
+
dblx get threads --q "plan"
|
|
70
|
+
dblx get threads --q "#dblebox" --archived --snoozed
|
|
30
71
|
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
dblx threads
|
|
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>
|
|
72
|
+
|
|
73
|
+
### Get All Thread Content, Including Comments and Notes
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
dblx get threads <thread-id>
|
|
50
77
|
```
|
|
51
78
|
|
|
52
|
-
|
|
79
|
+
### Today
|
|
53
80
|
|
|
81
|
+
```bash
|
|
82
|
+
dblx get today
|
|
83
|
+
dblx get today --date 2026-03-01
|
|
54
84
|
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
85
|
+
|
|
86
|
+
### Notes
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
dblx get thread-note <thread-id>
|
|
90
|
+
dblx get today-note
|
|
91
|
+
dblx get today-note --date 2026-03-01
|
|
58
92
|
```
|
|
59
93
|
|
|
60
|
-
|
|
94
|
+
### Comments
|
|
61
95
|
|
|
96
|
+
```bash
|
|
97
|
+
dblx get comments --thread <thread-id>
|
|
62
98
|
```
|
|
63
|
-
|
|
64
|
-
|
|
99
|
+
|
|
100
|
+
### Members
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
dblx get members <thread-id>
|
|
65
104
|
```
|
|
66
105
|
|
|
67
|
-
##
|
|
106
|
+
## Write Commands
|
|
107
|
+
|
|
108
|
+
### Threads
|
|
68
109
|
|
|
110
|
+
```bash
|
|
111
|
+
dblx create thread --title "New thread"
|
|
112
|
+
dblx create thread --title "..." --comment "First message"
|
|
113
|
+
dblx create thread --title "..." --note "Draft spec..."
|
|
114
|
+
|
|
115
|
+
dblx set thread <thread-id> --title "New title"
|
|
116
|
+
dblx set thread <thread-id> --archived true
|
|
117
|
+
dblx set thread <thread-id> --archived false
|
|
118
|
+
dblx set thread <thread-id> --snoozed-until 2026-03-01T09:00:00
|
|
119
|
+
dblx set thread <thread-id> --snoozed-until none
|
|
69
120
|
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
121
|
+
|
|
122
|
+
### Notes
|
|
123
|
+
|
|
124
|
+
Reading and writing notes are separate commands.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
dblx set thread-note <thread-id> --content "Updated note"
|
|
128
|
+
dblx set today-note --content "My note"
|
|
129
|
+
dblx set today-note --date 2026-03-01 --content "My note"
|
|
75
130
|
```
|
|
76
131
|
|
|
77
|
-
|
|
132
|
+
### Relationships
|
|
78
133
|
|
|
79
|
-
|
|
134
|
+
```bash
|
|
135
|
+
dblx set thread-parent <thread-id> --parent <parent-id>
|
|
136
|
+
dblx set thread-today <thread-id> --date 2026-03-01
|
|
137
|
+
dblx set thread-today <thread-id> --remove
|
|
138
|
+
dblx set thread-today <thread-id> --date 2026-03-01 --remove
|
|
139
|
+
```
|
|
80
140
|
|
|
141
|
+
### Comments
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
dblx create comment --thread <thread-id> --body "Hello"
|
|
145
|
+
dblx set comment <comment-id> --body "Updated text"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Members
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
dblx invite member <thread-id> --user alice@example.com
|
|
81
152
|
```
|
|
82
|
-
|
|
83
|
-
|
|
153
|
+
|
|
154
|
+
## JSON Output
|
|
155
|
+
|
|
156
|
+
All read commands support `--json` for machine-readable output:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
dblx get threads --json
|
|
160
|
+
dblx get threads <thread-id> --json
|
|
161
|
+
dblx get threads --q "plan" --json
|
|
162
|
+
dblx get today --json
|
|
163
|
+
dblx get thread-note <thread-id> --json
|
|
84
164
|
```
|
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);
|
|
2314
|
+
}
|
|
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);
|
|
2309
2319
|
}
|
|
2310
|
-
|
|
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 }));
|
|
2434
2461
|
}
|
|
2435
|
-
|
|
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;
|
|
2466
|
+
}
|
|
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,26 +2587,72 @@ 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
|
+
function relatedThreadLabel(thread) {
|
|
2609
|
+
return `${thread.thread.id.slice(0, 8)} ${thread.thread.body}`;
|
|
2610
|
+
}
|
|
2611
|
+
var getCommand = new Command("get").description("Read data from dblebox").addCommand(new Command("threads").description("List or search your threads").argument("[thread-id]", "Thread ID").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 (threadId, opts) => {
|
|
2557
2612
|
const api = getApi();
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2613
|
+
if (threadId) {
|
|
2614
|
+
if (opts.q || opts.archived || opts.snoozed) {
|
|
2615
|
+
throw new Error("Thread lookup does not support --q, --archived, or --snoozed.");
|
|
2616
|
+
}
|
|
2617
|
+
const { data: data2, error: error2 } = await api.api.cli.v1.threads({ id: threadId }).get();
|
|
2618
|
+
if (error2)
|
|
2619
|
+
throw error2;
|
|
2620
|
+
if (opts.json) {
|
|
2621
|
+
output(data2, { json: true });
|
|
2622
|
+
return;
|
|
2623
|
+
}
|
|
2624
|
+
console.log(`Thread: ${data2.thread.body}`);
|
|
2625
|
+
console.log(`ID: ${data2.thread.id}`);
|
|
2626
|
+
console.log(`Created: ${data2.thread.created_at}`);
|
|
2627
|
+
console.log(`
|
|
2628
|
+
Note:`);
|
|
2629
|
+
console.log(data2.note ? data2.note.content || "(empty)" : "(none)");
|
|
2630
|
+
console.log(`
|
|
2631
|
+
Comments:`);
|
|
2632
|
+
if (data2.comments.length === 0) {
|
|
2633
|
+
console.log("(none)");
|
|
2634
|
+
} else {
|
|
2635
|
+
for (const comment of data2.comments) {
|
|
2636
|
+
console.log(`- [${comment.created_at}] @${comment.creator_username}: ${comment.body}`);
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
console.log(`
|
|
2640
|
+
Parent:`);
|
|
2641
|
+
console.log(data2.parent_thread ? relatedThreadLabel(data2.parent_thread) : "(none)");
|
|
2642
|
+
console.log(`
|
|
2643
|
+
Children:`);
|
|
2644
|
+
if (data2.child_threads.length === 0) {
|
|
2645
|
+
console.log("(none)");
|
|
2646
|
+
} else {
|
|
2647
|
+
for (const child of data2.child_threads) {
|
|
2648
|
+
console.log(`- ${relatedThreadLabel(child)}`);
|
|
2649
|
+
}
|
|
2562
2650
|
}
|
|
2563
|
-
});
|
|
2564
|
-
if (error)
|
|
2565
|
-
throw error;
|
|
2566
|
-
if (opts.json) {
|
|
2567
|
-
output(data.threads, { json: true });
|
|
2568
2651
|
return;
|
|
2569
2652
|
}
|
|
2570
|
-
output(threadRows(data.threads), { json: false });
|
|
2571
|
-
})).addCommand(new Command("search").description("Search threads by partial text").argument("<query>", "Partial title/body text to match").option("--json", "Output as JSON").option("--archived", "Include archived threads").option("--snoozed", "Include snoozed threads").action(async (query, opts) => {
|
|
2572
|
-
const api = getApi();
|
|
2573
2653
|
const { data, error } = await api.api.cli.v1.threads.get({
|
|
2574
2654
|
query: {
|
|
2575
|
-
q:
|
|
2655
|
+
q: opts.q,
|
|
2576
2656
|
archived: opts.archived ? "true" : undefined,
|
|
2577
2657
|
snoozed: opts.snoozed ? "true" : undefined
|
|
2578
2658
|
}
|
|
@@ -2584,13 +2664,11 @@ var threadsCommand = new Command("threads").description("Manage threads").addCom
|
|
|
2584
2664
|
return;
|
|
2585
2665
|
}
|
|
2586
2666
|
output(threadRows(data.threads), { json: false });
|
|
2587
|
-
})).addCommand(new Command("
|
|
2667
|
+
})).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) => {
|
|
2668
|
+
const date = localDate(opts.date);
|
|
2588
2669
|
const api = getApi();
|
|
2589
|
-
const
|
|
2590
|
-
|
|
2591
|
-
body: opts.title,
|
|
2592
|
-
comment: opts.comment,
|
|
2593
|
-
note_content: noteContent
|
|
2670
|
+
const { data, error } = await api.api.cli.v1.today.get({
|
|
2671
|
+
query: { date }
|
|
2594
2672
|
});
|
|
2595
2673
|
if (error)
|
|
2596
2674
|
throw error;
|
|
@@ -2598,34 +2676,44 @@ var threadsCommand = new Command("threads").description("Manage threads").addCom
|
|
|
2598
2676
|
output(data, { json: true });
|
|
2599
2677
|
return;
|
|
2600
2678
|
}
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2679
|
+
console.log(`Date: ${data.date}
|
|
2680
|
+
`);
|
|
2681
|
+
if (data.threads.length > 0) {
|
|
2682
|
+
console.log("Threads:");
|
|
2683
|
+
for (const t of data.threads) {
|
|
2684
|
+
console.log(` ${t.id.slice(0, 8)} ${t.body}`);
|
|
2685
|
+
}
|
|
2686
|
+
console.log();
|
|
2687
|
+
} else {
|
|
2688
|
+
console.log(`No threads for this date.
|
|
2689
|
+
`);
|
|
2690
|
+
}
|
|
2691
|
+
if (data.note) {
|
|
2692
|
+
console.log("Note:");
|
|
2693
|
+
console.log(data.note.content || "(empty)");
|
|
2694
|
+
} else {
|
|
2695
|
+
console.log("No daily note.");
|
|
2696
|
+
}
|
|
2697
|
+
})).addCommand(new Command("thread-note").description("Read a thread note").argument("<thread-id>", "Thread ID").option("--json", "Output as JSON").action(async (threadId, opts) => {
|
|
2604
2698
|
const api = getApi();
|
|
2605
|
-
const { data, error } = await api.api.cli.v1.threads({ id }).
|
|
2606
|
-
body: opts.title
|
|
2607
|
-
});
|
|
2699
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).note.get();
|
|
2608
2700
|
if (error)
|
|
2609
2701
|
throw error;
|
|
2610
2702
|
if (opts.json) {
|
|
2611
|
-
output(data
|
|
2703
|
+
output(data, { json: true });
|
|
2612
2704
|
return;
|
|
2613
2705
|
}
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
const api = getApi();
|
|
2617
|
-
if (opts.set !== undefined) {
|
|
2618
|
-
const { data: data2, error: error2 } = await api.api.cli.v1.threads({ id }).note.put({ content: opts.set });
|
|
2619
|
-
if (error2)
|
|
2620
|
-
throw error2;
|
|
2621
|
-
if (opts.json) {
|
|
2622
|
-
output(data2, { json: true });
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
|
-
console.log("Note updated.");
|
|
2706
|
+
if (!data.note) {
|
|
2707
|
+
console.log("No thread note.");
|
|
2626
2708
|
return;
|
|
2627
2709
|
}
|
|
2628
|
-
|
|
2710
|
+
console.log(data.note.content || "(empty)");
|
|
2711
|
+
})).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) => {
|
|
2712
|
+
const date = localDate(opts.date);
|
|
2713
|
+
const api = getApi();
|
|
2714
|
+
const { data, error } = await api.api.cli.v1.today.note.get({
|
|
2715
|
+
query: { date }
|
|
2716
|
+
});
|
|
2629
2717
|
if (error)
|
|
2630
2718
|
throw error;
|
|
2631
2719
|
if (opts.json) {
|
|
@@ -2633,70 +2721,11 @@ var threadsCommand = new Command("threads").description("Manage threads").addCom
|
|
|
2633
2721
|
return;
|
|
2634
2722
|
}
|
|
2635
2723
|
if (!data.note) {
|
|
2636
|
-
console.log("No
|
|
2724
|
+
console.log("No daily note.");
|
|
2637
2725
|
return;
|
|
2638
2726
|
}
|
|
2639
2727
|
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) => {
|
|
2728
|
+
})).addCommand(new Command("comments").description("List comments in a thread").requiredOption("--thread <id>", "Thread ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
2700
2729
|
const api = getApi();
|
|
2701
2730
|
const { data, error } = await api.api.cli.v1.threads({ id: opts.thread }).comments.get();
|
|
2702
2731
|
if (error)
|
|
@@ -2712,111 +2741,155 @@ var commentsCommand = new Command("comments").description("Manage comments").add
|
|
|
2712
2741
|
created_at: c2.created_at
|
|
2713
2742
|
}));
|
|
2714
2743
|
output(rows, { json: false });
|
|
2715
|
-
})).addCommand(new Command("
|
|
2744
|
+
})).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
2745
|
const api = getApi();
|
|
2717
|
-
const { data, error } = await api.api.cli.v1.threads({ id:
|
|
2746
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).members.get();
|
|
2718
2747
|
if (error)
|
|
2719
2748
|
throw error;
|
|
2720
2749
|
if (opts.json) {
|
|
2721
|
-
output(data.
|
|
2750
|
+
output(data.members, { json: true });
|
|
2722
2751
|
return;
|
|
2723
2752
|
}
|
|
2724
|
-
|
|
2725
|
-
|
|
2753
|
+
const rows = data.members.filter((m) => !m.revoked_at).map((m) => ({
|
|
2754
|
+
username: m.username,
|
|
2755
|
+
email: m.email
|
|
2756
|
+
}));
|
|
2757
|
+
output(rows, { json: false });
|
|
2758
|
+
}));
|
|
2759
|
+
|
|
2760
|
+
// src/commands/create.ts
|
|
2761
|
+
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
2762
|
const api = getApi();
|
|
2727
|
-
const
|
|
2763
|
+
const noteContent = opts.note !== undefined ? opts.note : undefined;
|
|
2764
|
+
const { data, error } = await api.api.cli.v1.threads.post({
|
|
2765
|
+
body: opts.title,
|
|
2766
|
+
comment: opts.comment,
|
|
2767
|
+
note_content: noteContent
|
|
2768
|
+
});
|
|
2769
|
+
if (error)
|
|
2770
|
+
throw error;
|
|
2771
|
+
if (opts.json) {
|
|
2772
|
+
output(data, { json: true });
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
const noteSuffix = data.note ? ` (note ${data.note.id.slice(0, 8)} attached)` : "";
|
|
2776
|
+
console.log(`Created thread ${data.thread.id.slice(0, 8)}: ${data.thread.body}${noteSuffix}`);
|
|
2777
|
+
})).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) => {
|
|
2778
|
+
const api = getApi();
|
|
2779
|
+
const { data, error } = await api.api.cli.v1.threads({ id: opts.thread }).comments.post({ body: opts.body });
|
|
2728
2780
|
if (error)
|
|
2729
2781
|
throw error;
|
|
2730
2782
|
if (opts.json) {
|
|
2731
2783
|
output(data.comment, { json: true });
|
|
2732
2784
|
return;
|
|
2733
2785
|
}
|
|
2734
|
-
console.log(`Comment
|
|
2786
|
+
console.log(`Comment added (${data.comment.id.slice(0, 8)}).`);
|
|
2735
2787
|
}));
|
|
2736
2788
|
|
|
2737
|
-
// src/commands/
|
|
2738
|
-
var
|
|
2789
|
+
// src/commands/set.ts
|
|
2790
|
+
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
2791
|
const api = getApi();
|
|
2740
|
-
const
|
|
2741
|
-
|
|
2742
|
-
|
|
2792
|
+
const result = {};
|
|
2793
|
+
const messages = [];
|
|
2794
|
+
if (opts.title !== undefined) {
|
|
2795
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).put({
|
|
2796
|
+
body: opts.title
|
|
2797
|
+
});
|
|
2798
|
+
if (error)
|
|
2799
|
+
throw error;
|
|
2800
|
+
result.thread = data.thread;
|
|
2801
|
+
messages.push(`Updated thread ${data.thread.id.slice(0, 8)}: ${data.thread.body}`);
|
|
2802
|
+
}
|
|
2803
|
+
if (opts.archived !== undefined) {
|
|
2804
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).archive.put({
|
|
2805
|
+
archived: opts.archived
|
|
2806
|
+
});
|
|
2807
|
+
if (error)
|
|
2808
|
+
throw error;
|
|
2809
|
+
result.archived = data.archived;
|
|
2810
|
+
messages.push(data.archived ? "Archived." : "Unarchived.");
|
|
2811
|
+
}
|
|
2812
|
+
if (opts.snoozedUntil !== undefined) {
|
|
2813
|
+
const until = opts.snoozedUntil === "none" ? null : opts.snoozedUntil;
|
|
2814
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).snooze.put({
|
|
2815
|
+
until
|
|
2816
|
+
});
|
|
2817
|
+
if (error)
|
|
2818
|
+
throw error;
|
|
2819
|
+
result.snooze_until = data.snooze_until;
|
|
2820
|
+
messages.push(data.snooze_until ? `Snoozed until ${data.snooze_until}.` : "Unsnoozed.");
|
|
2821
|
+
}
|
|
2822
|
+
if (messages.length === 0) {
|
|
2823
|
+
throw new Error("No updates specified. Provide --title, --archived, or --snoozed-until.");
|
|
2824
|
+
}
|
|
2743
2825
|
if (opts.json) {
|
|
2744
|
-
output(
|
|
2826
|
+
output(result, { json: true });
|
|
2745
2827
|
return;
|
|
2746
2828
|
}
|
|
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) => {
|
|
2829
|
+
for (const message of messages) {
|
|
2830
|
+
console.log(message);
|
|
2831
|
+
}
|
|
2832
|
+
})).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
2833
|
const api = getApi();
|
|
2754
|
-
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).
|
|
2834
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).note.put({ content: opts.content });
|
|
2755
2835
|
if (error)
|
|
2756
2836
|
throw error;
|
|
2757
|
-
if (
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
console.log(data.reason || "Could not invite user.");
|
|
2837
|
+
if (opts.json) {
|
|
2838
|
+
output(data, { json: true });
|
|
2839
|
+
return;
|
|
2761
2840
|
}
|
|
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) => {
|
|
2841
|
+
console.log("Note updated.");
|
|
2842
|
+
})).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
2843
|
const date = localDate(opts.date);
|
|
2776
2844
|
const api = getApi();
|
|
2777
|
-
const { data, error } = await api.api.cli.v1.today.
|
|
2778
|
-
query: { date }
|
|
2779
|
-
});
|
|
2845
|
+
const { data, error } = await api.api.cli.v1.today.note.put({ content: opts.content }, { query: { date } });
|
|
2780
2846
|
if (error)
|
|
2781
2847
|
throw error;
|
|
2782
2848
|
if (opts.json) {
|
|
2783
2849
|
output(data, { json: true });
|
|
2784
2850
|
return;
|
|
2785
2851
|
}
|
|
2786
|
-
console.log(
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
console.log(`No threads for this date.
|
|
2796
|
-
`);
|
|
2852
|
+
console.log("Note updated.");
|
|
2853
|
+
})).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) => {
|
|
2854
|
+
const api = getApi();
|
|
2855
|
+
const { data, error } = await api.api.cli.v1.comments({ id: commentId }).put({ body: opts.body });
|
|
2856
|
+
if (error)
|
|
2857
|
+
throw error;
|
|
2858
|
+
if (opts.json) {
|
|
2859
|
+
output(data.comment, { json: true });
|
|
2860
|
+
return;
|
|
2797
2861
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2862
|
+
console.log(`Comment updated (${data.comment.id.slice(0, 8)}).`);
|
|
2863
|
+
})).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) => {
|
|
2864
|
+
const api = getApi();
|
|
2865
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).parent.put({
|
|
2866
|
+
parent_id: opts.parent
|
|
2867
|
+
});
|
|
2868
|
+
if (error)
|
|
2869
|
+
throw error;
|
|
2870
|
+
if (opts.json) {
|
|
2871
|
+
output(data.thread, { json: true });
|
|
2872
|
+
return;
|
|
2803
2873
|
}
|
|
2804
|
-
|
|
2874
|
+
console.log(`Parent set to ${opts.parent.slice(0, 8)}.`);
|
|
2875
|
+
})).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
2876
|
const date = localDate(opts.date);
|
|
2806
2877
|
const api = getApi();
|
|
2807
|
-
if (opts.
|
|
2808
|
-
const { data: data2, error: error2 } = await api.api.cli.v1.
|
|
2878
|
+
if (opts.remove) {
|
|
2879
|
+
const { data: data2, error: error2 } = await api.api.cli.v1.threads({ id: threadId }).today.delete({
|
|
2880
|
+
date
|
|
2881
|
+
});
|
|
2809
2882
|
if (error2)
|
|
2810
2883
|
throw error2;
|
|
2811
2884
|
if (opts.json) {
|
|
2812
2885
|
output(data2, { json: true });
|
|
2813
2886
|
return;
|
|
2814
2887
|
}
|
|
2815
|
-
console.log(
|
|
2888
|
+
console.log(`Removed from ${date}.`);
|
|
2816
2889
|
return;
|
|
2817
2890
|
}
|
|
2818
|
-
const { data, error } = await api.api.cli.v1.today.
|
|
2819
|
-
|
|
2891
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).today.put({
|
|
2892
|
+
date
|
|
2820
2893
|
});
|
|
2821
2894
|
if (error)
|
|
2822
2895
|
throw error;
|
|
@@ -2824,16 +2897,29 @@ var todayCommand = new Command("today").description("Today view — threads and
|
|
|
2824
2897
|
output(data, { json: true });
|
|
2825
2898
|
return;
|
|
2826
2899
|
}
|
|
2827
|
-
|
|
2828
|
-
|
|
2900
|
+
console.log(`Assigned to ${date}.`);
|
|
2901
|
+
}));
|
|
2902
|
+
|
|
2903
|
+
// src/commands/invite.ts
|
|
2904
|
+
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) => {
|
|
2905
|
+
const api = getApi();
|
|
2906
|
+
const { data, error } = await api.api.cli.v1.threads({ id: threadId }).members.post({ user: opts.user });
|
|
2907
|
+
if (error)
|
|
2908
|
+
throw error;
|
|
2909
|
+
if (opts.json) {
|
|
2910
|
+
output(data, { json: true });
|
|
2829
2911
|
return;
|
|
2830
2912
|
}
|
|
2831
|
-
|
|
2913
|
+
if (data.invited) {
|
|
2914
|
+
console.log(`Invited ${data.user?.username || opts.user}.`);
|
|
2915
|
+
} else {
|
|
2916
|
+
console.log(data.reason || "Could not invite user.");
|
|
2917
|
+
}
|
|
2832
2918
|
}));
|
|
2833
2919
|
// package.json
|
|
2834
2920
|
var package_default = {
|
|
2835
2921
|
name: "dblx",
|
|
2836
|
-
version: "0.1.
|
|
2922
|
+
version: "0.1.64",
|
|
2837
2923
|
description: "CLI for dblebox — thread-first communication",
|
|
2838
2924
|
type: "module",
|
|
2839
2925
|
bin: {
|
|
@@ -2860,10 +2946,10 @@ var package_default = {
|
|
|
2860
2946
|
// src/index.ts
|
|
2861
2947
|
var program2 = new Command().name("dblx").description("CLI for dblebox — thread-first communication").version(package_default.version).enablePositionalOptions();
|
|
2862
2948
|
program2.addCommand(authCommand);
|
|
2863
|
-
program2.addCommand(
|
|
2864
|
-
program2.addCommand(
|
|
2865
|
-
program2.addCommand(
|
|
2866
|
-
program2.addCommand(
|
|
2949
|
+
program2.addCommand(getCommand);
|
|
2950
|
+
program2.addCommand(createCommand2);
|
|
2951
|
+
program2.addCommand(setCommand);
|
|
2952
|
+
program2.addCommand(inviteCommand);
|
|
2867
2953
|
program2.parseAsync().catch((err) => {
|
|
2868
2954
|
console.error(err.message);
|
|
2869
2955
|
process.exit(1);
|