@arjun-shah/agentbar-cli 0.1.9 → 0.1.11
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 +7 -1
- package/bin/agentbar.js +140 -203
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,13 @@ agentbar stats
|
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
The CLI writes `agentbar.config.json` in your project directory. `agentbar init` only asks
|
|
27
|
-
for your site URL
|
|
27
|
+
for your site URL and syncs settings to the hosted dashboard so your embed is a single line:
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<script src="https://agent-pug.vercel.app/agentbar.js" data-site-key="your-site-key"></script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Open the deployed dashboard to edit settings and copy the snippet again.
|
|
28
34
|
|
|
29
35
|
## Customization
|
|
30
36
|
|
package/bin/agentbar.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
|
-
import readline from "node:readline";
|
|
5
5
|
import process from "node:process";
|
|
6
|
+
import readline from "node:readline";
|
|
6
7
|
|
|
7
8
|
const CONFIG_FILE = "agentbar.config.json";
|
|
8
9
|
const DEFAULT_CONFIG = {
|
|
9
10
|
apiBase: "https://agent-pug.vercel.app",
|
|
11
|
+
authToken: "",
|
|
12
|
+
accountEmail: "",
|
|
10
13
|
siteUrl: "",
|
|
11
14
|
siteKey: "",
|
|
12
15
|
depth: 1,
|
|
@@ -119,202 +122,72 @@ const resolveSiteKey = (config) => {
|
|
|
119
122
|
}
|
|
120
123
|
};
|
|
121
124
|
|
|
125
|
+
const authHeaders = (config) =>
|
|
126
|
+
config.authToken
|
|
127
|
+
? {
|
|
128
|
+
Authorization: `Bearer ${config.authToken}`,
|
|
129
|
+
}
|
|
130
|
+
: {};
|
|
131
|
+
|
|
122
132
|
const renderSnippet = (config) => {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
lines.push(` data-subtitle=\"${config.subtitle}\"`);
|
|
145
|
-
}
|
|
146
|
-
if (config.buttonLabel) {
|
|
147
|
-
lines.push(` data-button-label=\"${config.buttonLabel}\"`);
|
|
148
|
-
}
|
|
149
|
-
if (config.fontFamily) {
|
|
150
|
-
lines.push(` data-font-family=\"${config.fontFamily}\"`);
|
|
151
|
-
}
|
|
152
|
-
if (config.panelBackground) {
|
|
153
|
-
lines.push(` data-panel-background=\"${config.panelBackground}\"`);
|
|
154
|
-
}
|
|
155
|
-
if (config.textColor) {
|
|
156
|
-
lines.push(` data-text-color=\"${config.textColor}\"`);
|
|
157
|
-
}
|
|
158
|
-
if (config.mutedTextColor) {
|
|
159
|
-
lines.push(` data-muted-text-color=\"${config.mutedTextColor}\"`);
|
|
160
|
-
}
|
|
161
|
-
if (config.borderColor) {
|
|
162
|
-
lines.push(` data-border-color=\"${config.borderColor}\"`);
|
|
163
|
-
}
|
|
164
|
-
if (config.buttonBackground) {
|
|
165
|
-
lines.push(` data-button-background=\"${config.buttonBackground}\"`);
|
|
166
|
-
}
|
|
167
|
-
if (config.buttonTextColor) {
|
|
168
|
-
lines.push(` data-button-text-color=\"${config.buttonTextColor}\"`);
|
|
169
|
-
}
|
|
170
|
-
if (config.accentTextColor) {
|
|
171
|
-
lines.push(` data-accent-text-color=\"${config.accentTextColor}\"`);
|
|
172
|
-
}
|
|
173
|
-
if (config.buttonShadow) {
|
|
174
|
-
lines.push(` data-button-shadow=\"${config.buttonShadow}\"`);
|
|
175
|
-
}
|
|
176
|
-
if (config.panelShadow) {
|
|
177
|
-
lines.push(` data-panel-shadow=\"${config.panelShadow}\"`);
|
|
178
|
-
}
|
|
179
|
-
if (config.badgeLabel) {
|
|
180
|
-
lines.push(` data-badge-label=\"${config.badgeLabel}\"`);
|
|
181
|
-
}
|
|
182
|
-
if (config.badgeBackground) {
|
|
183
|
-
lines.push(` data-badge-background=\"${config.badgeBackground}\"`);
|
|
184
|
-
}
|
|
185
|
-
if (config.badgeTextColor) {
|
|
186
|
-
lines.push(` data-badge-text-color=\"${config.badgeTextColor}\"`);
|
|
187
|
-
}
|
|
188
|
-
if (config.userBubbleBackground) {
|
|
189
|
-
lines.push(` data-user-bubble-background=\"${config.userBubbleBackground}\"`);
|
|
190
|
-
}
|
|
191
|
-
if (config.userBubbleText) {
|
|
192
|
-
lines.push(` data-user-bubble-text=\"${config.userBubbleText}\"`);
|
|
193
|
-
}
|
|
194
|
-
if (config.userBubbleBorder) {
|
|
195
|
-
lines.push(` data-user-bubble-border=\"${config.userBubbleBorder}\"`);
|
|
196
|
-
}
|
|
197
|
-
if (config.assistantBubbleBackground) {
|
|
198
|
-
lines.push(` data-assistant-bubble-background=\"${config.assistantBubbleBackground}\"`);
|
|
199
|
-
}
|
|
200
|
-
if (config.assistantBubbleText) {
|
|
201
|
-
lines.push(` data-assistant-bubble-text=\"${config.assistantBubbleText}\"`);
|
|
202
|
-
}
|
|
203
|
-
if (config.assistantBubbleBorder) {
|
|
204
|
-
lines.push(` data-assistant-bubble-border=\"${config.assistantBubbleBorder}\"`);
|
|
205
|
-
}
|
|
206
|
-
if (config.panelWidth) {
|
|
207
|
-
lines.push(` data-panel-width=\"${config.panelWidth}\"`);
|
|
208
|
-
}
|
|
209
|
-
if (config.panelMaxHeight) {
|
|
210
|
-
lines.push(` data-panel-max-height=\"${config.panelMaxHeight}\"`);
|
|
211
|
-
}
|
|
212
|
-
if (config.panelRadius) {
|
|
213
|
-
lines.push(` data-panel-radius=\"${config.panelRadius}\"`);
|
|
214
|
-
}
|
|
215
|
-
if (config.buttonRadius) {
|
|
216
|
-
lines.push(` data-button-radius=\"${config.buttonRadius}\"`);
|
|
217
|
-
}
|
|
218
|
-
if (typeof config.offsetX === "number") {
|
|
219
|
-
lines.push(` data-offset-x=\"${config.offsetX}\"`);
|
|
220
|
-
}
|
|
221
|
-
if (typeof config.offsetY === "number") {
|
|
222
|
-
lines.push(` data-offset-y=\"${config.offsetY}\"`);
|
|
223
|
-
}
|
|
224
|
-
if (config.inputPlaceholder) {
|
|
225
|
-
lines.push(` data-input-placeholder=\"${config.inputPlaceholder}\"`);
|
|
226
|
-
}
|
|
227
|
-
if (config.sendLabel) {
|
|
228
|
-
lines.push(` data-send-label=\"${config.sendLabel}\"`);
|
|
229
|
-
}
|
|
230
|
-
if (config.suggestions?.length) {
|
|
231
|
-
lines.push(` data-suggestions=\"${config.suggestions.join(" | ")}\"`);
|
|
232
|
-
}
|
|
233
|
-
if (config.greeting) {
|
|
234
|
-
lines.push(` data-greeting=\"${config.greeting}\"`);
|
|
235
|
-
}
|
|
236
|
-
if (typeof config.draggable === "boolean") {
|
|
237
|
-
lines.push(` data-draggable=\"${config.draggable}\"`);
|
|
238
|
-
}
|
|
239
|
-
if (typeof config.dragOffset === "number" && config.dragOffset !== 0) {
|
|
240
|
-
lines.push(` data-drag-offset=\"${config.dragOffset}\"`);
|
|
241
|
-
}
|
|
242
|
-
if (typeof config.persistPosition === "boolean") {
|
|
243
|
-
lines.push(` data-persist-position=\"${config.persistPosition}\"`);
|
|
244
|
-
}
|
|
245
|
-
if (config.positionKey) {
|
|
246
|
-
lines.push(` data-position-key=\"${config.positionKey}\"`);
|
|
247
|
-
}
|
|
248
|
-
if (config.openOnLoad) {
|
|
249
|
-
lines.push(` data-open=\"${config.openOnLoad}\"`);
|
|
250
|
-
}
|
|
251
|
-
if (config.showReset) {
|
|
252
|
-
lines.push(` data-show-reset=\"${config.showReset}\"`);
|
|
253
|
-
}
|
|
254
|
-
if (config.persist) {
|
|
255
|
-
lines.push(` data-persist=\"${config.persist}\"`);
|
|
256
|
-
}
|
|
257
|
-
if (config.storageKey) {
|
|
258
|
-
lines.push(` data-storage-key=\"${config.storageKey}\"`);
|
|
259
|
-
}
|
|
260
|
-
if (typeof config.showTypingIndicator === "boolean") {
|
|
261
|
-
lines.push(` data-show-typing-indicator=\"${config.showTypingIndicator}\"`);
|
|
262
|
-
}
|
|
263
|
-
if (typeof config.showExport === "boolean") {
|
|
264
|
-
lines.push(` data-show-export=\"${config.showExport}\"`);
|
|
265
|
-
}
|
|
266
|
-
if (config.exportLabel) {
|
|
267
|
-
lines.push(` data-export-label=\"${config.exportLabel}\"`);
|
|
268
|
-
}
|
|
269
|
-
if (typeof config.showScrollButton === "boolean") {
|
|
270
|
-
lines.push(` data-show-scroll-button=\"${config.showScrollButton}\"`);
|
|
271
|
-
}
|
|
272
|
-
if (config.scrollLabel) {
|
|
273
|
-
lines.push(` data-scroll-label=\"${config.scrollLabel}\"`);
|
|
274
|
-
}
|
|
275
|
-
if (typeof config.showMinimize === "boolean") {
|
|
276
|
-
lines.push(` data-show-minimize=\"${config.showMinimize}\"`);
|
|
277
|
-
}
|
|
278
|
-
if (typeof config.minimizedOnLoad === "boolean") {
|
|
279
|
-
lines.push(` data-minimized-on-load=\"${config.minimizedOnLoad}\"`);
|
|
280
|
-
}
|
|
281
|
-
if (config.minimizeLabel) {
|
|
282
|
-
lines.push(` data-minimize-label=\"${config.minimizeLabel}\"`);
|
|
283
|
-
}
|
|
284
|
-
if (config.expandLabel) {
|
|
285
|
-
lines.push(` data-expand-label=\"${config.expandLabel}\"`);
|
|
286
|
-
}
|
|
287
|
-
if (typeof config.showTimestamps === "boolean") {
|
|
288
|
-
lines.push(` data-show-timestamps=\"${config.showTimestamps}\"`);
|
|
289
|
-
}
|
|
290
|
-
if (config.timestampLocale) {
|
|
291
|
-
lines.push(` data-timestamp-locale=\"${config.timestampLocale}\"`);
|
|
292
|
-
}
|
|
293
|
-
if (typeof config.autoScroll === "boolean") {
|
|
294
|
-
lines.push(` data-auto-scroll=\"${config.autoScroll}\"`);
|
|
295
|
-
}
|
|
296
|
-
if (typeof config.autoScrollThreshold === "number") {
|
|
297
|
-
lines.push(` data-auto-scroll-threshold=\"${config.autoScrollThreshold}\"`);
|
|
298
|
-
}
|
|
299
|
-
if (config.messageMaxWidth) {
|
|
300
|
-
lines.push(` data-message-max-width=\"${config.messageMaxWidth}\"`);
|
|
301
|
-
}
|
|
302
|
-
if (config.launcherTooltip) {
|
|
303
|
-
lines.push(` data-launcher-tooltip=\"${config.launcherTooltip}\"`);
|
|
133
|
+
const apiBase = (config.apiBase || DEFAULT_CONFIG.apiBase).replace(/\/$/, "");
|
|
134
|
+
const siteKey = resolveSiteKey(config) || "your-site-key";
|
|
135
|
+
return `<script src="${apiBase}/agentbar.js" data-site-key="${siteKey}"></script>`;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const openBrowser = (url) => {
|
|
139
|
+
try {
|
|
140
|
+
if (process.platform === "darwin") {
|
|
141
|
+
spawn("open", [url], { stdio: "ignore", detached: true }).unref();
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (process.platform === "win32") {
|
|
145
|
+
spawn("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true }).unref();
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
if (process.platform === "linux") {
|
|
149
|
+
spawn("xdg-open", [url], { stdio: "ignore", detached: true }).unref();
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
304
154
|
}
|
|
305
|
-
|
|
306
|
-
|
|
155
|
+
return false;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
159
|
+
|
|
160
|
+
const syncConfig = async (config) => {
|
|
161
|
+
const apiBase = (config.apiBase || DEFAULT_CONFIG.apiBase).replace(/\/$/, "");
|
|
162
|
+
const siteKey = resolveSiteKey(config);
|
|
163
|
+
if (!siteKey || !config.authToken) {
|
|
164
|
+
return;
|
|
307
165
|
}
|
|
308
|
-
|
|
309
|
-
|
|
166
|
+
try {
|
|
167
|
+
const response = await fetch(`${apiBase}/api/config`, {
|
|
168
|
+
method: "POST",
|
|
169
|
+
headers: {
|
|
170
|
+
"Content-Type": "application/json",
|
|
171
|
+
...authHeaders(config),
|
|
172
|
+
},
|
|
173
|
+
body: JSON.stringify({
|
|
174
|
+
siteKey,
|
|
175
|
+
config: { ...config, siteKey },
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
const data = await response.json().catch(() => ({}));
|
|
180
|
+
throw new Error(data?.error || "Could not sync hosted settings.");
|
|
181
|
+
}
|
|
182
|
+
} catch (_error) {
|
|
183
|
+
console.warn("Could not sync settings to the hosted dashboard.");
|
|
310
184
|
}
|
|
311
|
-
lines.push("></script>");
|
|
312
|
-
return lines.join("\n");
|
|
313
185
|
};
|
|
314
186
|
|
|
315
187
|
const printHelp = () => {
|
|
316
188
|
console.log("Agent Plugin Bar CLI\n");
|
|
317
189
|
console.log("Commands:");
|
|
190
|
+
console.log(" agentbar login Open the web login flow and save an auth token");
|
|
318
191
|
console.log(" agentbar init Interactive setup and snippet output");
|
|
319
192
|
console.log(" agentbar snippet Print current embed snippet");
|
|
320
193
|
console.log(" agentbar set <key> <v> Update config value");
|
|
@@ -323,7 +196,7 @@ const printHelp = () => {
|
|
|
323
196
|
console.log(" agentbar help Show help\n");
|
|
324
197
|
console.log("Config keys:");
|
|
325
198
|
console.log(
|
|
326
|
-
" siteUrl, apiBase, depth, maxPages, siteKey, themeColor, position, title, subtitle,"
|
|
199
|
+
" siteUrl, apiBase, authToken, accountEmail, depth, maxPages, siteKey, themeColor, position, title, subtitle,"
|
|
327
200
|
);
|
|
328
201
|
console.log(
|
|
329
202
|
" buttonLabel, fontFamily, panelBackground, textColor, mutedTextColor, borderColor,"
|
|
@@ -365,8 +238,60 @@ const ask = (rl, prompt, fallback) =>
|
|
|
365
238
|
});
|
|
366
239
|
});
|
|
367
240
|
|
|
241
|
+
const login = async (existingConfig = loadConfig()) => {
|
|
242
|
+
const config = { ...existingConfig };
|
|
243
|
+
const apiBase = (config.apiBase || DEFAULT_CONFIG.apiBase).replace(/\/$/, "");
|
|
244
|
+
|
|
245
|
+
const response = await fetch(`${apiBase}/api/auth/device/start`, {
|
|
246
|
+
method: "POST",
|
|
247
|
+
headers: { "Content-Type": "application/json" },
|
|
248
|
+
});
|
|
249
|
+
const data = await response.json().catch(() => ({}));
|
|
250
|
+
if (!response.ok) {
|
|
251
|
+
throw new Error(data?.error || "Failed to start login.");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
console.log(`User code: ${data.userCode}`);
|
|
255
|
+
console.log(`Verification URL: ${data.verificationUrl}`);
|
|
256
|
+
if (!openBrowser(data.verificationUrl)) {
|
|
257
|
+
console.log("Open that URL in your browser to continue.");
|
|
258
|
+
}
|
|
259
|
+
console.log("Waiting for approval...\n");
|
|
260
|
+
|
|
261
|
+
const intervalMs = Math.max(1000, Number(data.interval || 2) * 1000);
|
|
262
|
+
const expiresAt = Number(data.expiresAt || 0);
|
|
263
|
+
|
|
264
|
+
while (!expiresAt || Date.now() < expiresAt) {
|
|
265
|
+
await sleep(intervalMs);
|
|
266
|
+
const pollResponse = await fetch(`${apiBase}/api/auth/device/poll`, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: { "Content-Type": "application/json" },
|
|
269
|
+
body: JSON.stringify({ deviceCode: data.deviceCode }),
|
|
270
|
+
});
|
|
271
|
+
const pollData = await pollResponse.json().catch(() => ({}));
|
|
272
|
+
if (!pollResponse.ok) {
|
|
273
|
+
throw new Error(pollData?.error || "Login polling failed.");
|
|
274
|
+
}
|
|
275
|
+
if (!pollData.approved) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
config.authToken = pollData.accessToken || "";
|
|
279
|
+
config.accountEmail = pollData.user?.email || "";
|
|
280
|
+
saveConfig(config);
|
|
281
|
+
console.log(`Logged in as ${config.accountEmail || "your account"}.`);
|
|
282
|
+
return config;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
throw new Error("Login request expired before approval.");
|
|
286
|
+
};
|
|
287
|
+
|
|
368
288
|
const init = async () => {
|
|
369
|
-
|
|
289
|
+
let config = loadConfig();
|
|
290
|
+
if (!config.authToken) {
|
|
291
|
+
console.log("No saved login found. Opening the web login flow...\n");
|
|
292
|
+
config = await login(config);
|
|
293
|
+
}
|
|
294
|
+
|
|
370
295
|
const rl = readline.createInterface({
|
|
371
296
|
input: process.stdin,
|
|
372
297
|
output: process.stdout,
|
|
@@ -384,9 +309,11 @@ const init = async () => {
|
|
|
384
309
|
}
|
|
385
310
|
|
|
386
311
|
saveConfig(config);
|
|
312
|
+
await syncConfig(config);
|
|
387
313
|
console.log("\nSaved config to", configPath);
|
|
388
314
|
console.log("\nEmbed snippet:\n");
|
|
389
315
|
console.log(renderSnippet(config));
|
|
316
|
+
console.log(`\nDashboard: ${(config.apiBase || DEFAULT_CONFIG.apiBase).replace(/\/$/, "")}\n`);
|
|
390
317
|
};
|
|
391
318
|
|
|
392
319
|
const printStats = async () => {
|
|
@@ -399,8 +326,15 @@ const printStats = async () => {
|
|
|
399
326
|
process.exit(1);
|
|
400
327
|
}
|
|
401
328
|
|
|
329
|
+
if (!config.authToken) {
|
|
330
|
+
console.error("Missing auth token. Run `agentbar login` first.");
|
|
331
|
+
process.exit(1);
|
|
332
|
+
}
|
|
333
|
+
|
|
402
334
|
try {
|
|
403
|
-
const response = await fetch(`${apiBase}/api/status
|
|
335
|
+
const response = await fetch(`${apiBase}/api/status`, {
|
|
336
|
+
headers: authHeaders(config),
|
|
337
|
+
});
|
|
404
338
|
if (!response.ok) {
|
|
405
339
|
const data = await response.json().catch(() => ({}));
|
|
406
340
|
throw new Error(data?.error || `Status request failed (${response.status})`);
|
|
@@ -410,7 +344,7 @@ const printStats = async () => {
|
|
|
410
344
|
const matched = items.filter((item) => item.key === siteKey);
|
|
411
345
|
if (!matched.length) {
|
|
412
346
|
console.log("No indexed content found for", siteKey);
|
|
413
|
-
console.log("
|
|
347
|
+
console.log("Save the site config and run reindex from the console first.");
|
|
414
348
|
return;
|
|
415
349
|
}
|
|
416
350
|
matched.forEach((item) => {
|
|
@@ -427,7 +361,7 @@ const printStats = async () => {
|
|
|
427
361
|
}
|
|
428
362
|
};
|
|
429
363
|
|
|
430
|
-
const setValue = (key, value) => {
|
|
364
|
+
const setValue = async (key, value) => {
|
|
431
365
|
if (!key || typeof value === "undefined") {
|
|
432
366
|
console.error("Usage: agentbar set <key> <value>");
|
|
433
367
|
process.exit(1);
|
|
@@ -448,7 +382,7 @@ const setValue = (key, value) => {
|
|
|
448
382
|
process.exit(1);
|
|
449
383
|
}
|
|
450
384
|
config[key] = parsed;
|
|
451
|
-
} else if (key === "offsetX" || key === "offsetY") {
|
|
385
|
+
} else if (key === "offsetX" || key === "offsetY" || key === "dragOffset") {
|
|
452
386
|
const parsed = Number(value);
|
|
453
387
|
if (!Number.isFinite(parsed)) {
|
|
454
388
|
console.error(`${key} must be a number.`);
|
|
@@ -472,23 +406,20 @@ const setValue = (key, value) => {
|
|
|
472
406
|
key === "autoScroll"
|
|
473
407
|
) {
|
|
474
408
|
config[key] = value === "true" || value === true;
|
|
475
|
-
} else if (key === "dragOffset") {
|
|
476
|
-
const parsed = Number(value);
|
|
477
|
-
if (!Number.isFinite(parsed)) {
|
|
478
|
-
console.error(`${key} must be a number.`);
|
|
479
|
-
process.exit(1);
|
|
480
|
-
}
|
|
481
|
-
config[key] = parsed;
|
|
482
409
|
} else if (key === "suggestions") {
|
|
483
410
|
config[key] = String(value)
|
|
484
411
|
.split(/[|,]/)
|
|
485
412
|
.map((item) => item.trim())
|
|
486
413
|
.filter(Boolean);
|
|
414
|
+
} else if (key === "siteUrl") {
|
|
415
|
+
config[key] = normalizeUrl(value);
|
|
416
|
+
config.siteKey = resolveSiteKey(config);
|
|
487
417
|
} else {
|
|
488
418
|
config[key] = value;
|
|
489
419
|
}
|
|
490
420
|
|
|
491
421
|
saveConfig(config);
|
|
422
|
+
await syncConfig(config);
|
|
492
423
|
console.log("Updated", key, "in", configPath);
|
|
493
424
|
};
|
|
494
425
|
|
|
@@ -496,6 +427,9 @@ const main = async () => {
|
|
|
496
427
|
const [command, arg1, arg2] = process.argv.slice(2);
|
|
497
428
|
|
|
498
429
|
switch (command) {
|
|
430
|
+
case "login":
|
|
431
|
+
await login();
|
|
432
|
+
return;
|
|
499
433
|
case "init":
|
|
500
434
|
await init();
|
|
501
435
|
return;
|
|
@@ -508,7 +442,7 @@ const main = async () => {
|
|
|
508
442
|
await printStats();
|
|
509
443
|
return;
|
|
510
444
|
case "set":
|
|
511
|
-
setValue(arg1, arg2);
|
|
445
|
+
await setValue(arg1, arg2);
|
|
512
446
|
return;
|
|
513
447
|
case "config":
|
|
514
448
|
console.log(JSON.stringify(loadConfig(), null, 2));
|
|
@@ -525,4 +459,7 @@ const main = async () => {
|
|
|
525
459
|
}
|
|
526
460
|
};
|
|
527
461
|
|
|
528
|
-
main()
|
|
462
|
+
main().catch((error) => {
|
|
463
|
+
console.error(error instanceof Error ? error.message : "Unknown error");
|
|
464
|
+
process.exit(1);
|
|
465
|
+
});
|