agendex-cli 0.5.0 → 0.6.0
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/dist/cli.js +87 -51
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2127,11 +2127,13 @@ function normalizeStoredConfig(raw) {
|
|
|
2127
2127
|
const token = typeof raw.token === "string" && raw.token.trim() ? raw.token : undefined;
|
|
2128
2128
|
const cloudToken = typeof raw.cloudToken === "string" && raw.cloudToken.trim() ? raw.cloudToken : undefined;
|
|
2129
2129
|
const convexUrl = typeof raw.convexUrl === "string" && raw.convexUrl.trim() ? raw.convexUrl : undefined;
|
|
2130
|
+
const deviceId = typeof raw.deviceId === "string" && raw.deviceId.trim() ? raw.deviceId : undefined;
|
|
2130
2131
|
return {
|
|
2131
2132
|
configVersion: 3,
|
|
2132
2133
|
token,
|
|
2133
2134
|
cloudToken,
|
|
2134
2135
|
convexUrl,
|
|
2136
|
+
deviceId,
|
|
2135
2137
|
enabledAdapters: normalizeAdapterIds(raw.enabledAdapters)
|
|
2136
2138
|
};
|
|
2137
2139
|
}
|
|
@@ -2145,6 +2147,7 @@ function saveConfig(config) {
|
|
|
2145
2147
|
token: config.token,
|
|
2146
2148
|
cloudToken: config.cloudToken,
|
|
2147
2149
|
convexUrl: config.convexUrl,
|
|
2150
|
+
deviceId: config.deviceId,
|
|
2148
2151
|
enabledAdapters: sanitizeEnabledAdapterIds(config.enabledAdapters)
|
|
2149
2152
|
};
|
|
2150
2153
|
writeFileSync(configPath, JSON.stringify(payload, null, 2));
|
|
@@ -2170,6 +2173,19 @@ function loadOrCreateToken() {
|
|
|
2170
2173
|
`);
|
|
2171
2174
|
return token;
|
|
2172
2175
|
}
|
|
2176
|
+
function loadOrCreateDeviceId() {
|
|
2177
|
+
const existing = loadConfig();
|
|
2178
|
+
if (existing?.deviceId)
|
|
2179
|
+
return existing.deviceId;
|
|
2180
|
+
const deviceId = randomBytes(16).toString("hex");
|
|
2181
|
+
saveConfig({
|
|
2182
|
+
...existing ?? {},
|
|
2183
|
+
configVersion: 3,
|
|
2184
|
+
deviceId,
|
|
2185
|
+
enabledAdapters: existing?.enabledAdapters ?? []
|
|
2186
|
+
});
|
|
2187
|
+
return deviceId;
|
|
2188
|
+
}
|
|
2173
2189
|
async function loadOrInitConfig(options = {}) {
|
|
2174
2190
|
const configureAdapters = Boolean(options.configureAdapters);
|
|
2175
2191
|
const existing = loadConfig();
|
|
@@ -2195,11 +2211,13 @@ async function loadOrInitConfig(options = {}) {
|
|
|
2195
2211
|
if (enabledAdapters.length === 0)
|
|
2196
2212
|
enabledAdapters = getDefaultAdapterIds();
|
|
2197
2213
|
}
|
|
2214
|
+
const deviceId = existing?.deviceId || randomBytes(16).toString("hex");
|
|
2198
2215
|
const nextConfig = {
|
|
2199
2216
|
configVersion: 3,
|
|
2200
2217
|
token: tokenFromEnv ? existing?.token : currentToken,
|
|
2201
2218
|
cloudToken: existing?.cloudToken,
|
|
2202
2219
|
convexUrl: existing?.convexUrl,
|
|
2220
|
+
deviceId,
|
|
2203
2221
|
enabledAdapters
|
|
2204
2222
|
};
|
|
2205
2223
|
saveConfig(nextConfig);
|
|
@@ -2477,11 +2495,17 @@ function startWatching(onChange) {
|
|
|
2477
2495
|
// src/auth.ts
|
|
2478
2496
|
import { spawn } from "node:child_process";
|
|
2479
2497
|
import { createServer } from "node:http";
|
|
2480
|
-
var
|
|
2498
|
+
var PROD_SITE_URL = "https://app.agendex.dev";
|
|
2499
|
+
var DEV_SITE_URL = "http://app.agendex.local:5174";
|
|
2500
|
+
function getDefaultSiteUrl() {
|
|
2501
|
+
if (process.env.AGENDEX_SITE_URL)
|
|
2502
|
+
return process.env.AGENDEX_SITE_URL;
|
|
2503
|
+
return process.env.AGENDEX_DEV === "1" ? DEV_SITE_URL : PROD_SITE_URL;
|
|
2504
|
+
}
|
|
2481
2505
|
async function login(siteUrlOverride) {
|
|
2482
2506
|
const { port, result } = await startCallbackServer();
|
|
2483
2507
|
const callbackUrl = `http://127.0.0.1:${port}/callback`;
|
|
2484
|
-
const siteUrl = siteUrlOverride ??
|
|
2508
|
+
const siteUrl = siteUrlOverride ?? getDefaultSiteUrl();
|
|
2485
2509
|
const authUrl = `${siteUrl}/auth/cli?callback=${encodeURIComponent(callbackUrl)}`;
|
|
2486
2510
|
console.log(`[agendex] Opening browser for authentication...`);
|
|
2487
2511
|
console.log(`[agendex] If it doesn't open, visit: ${authUrl}`);
|
|
@@ -2670,6 +2694,56 @@ import { fileURLToPath } from "node:url";
|
|
|
2670
2694
|
// src/api.ts
|
|
2671
2695
|
import { request as httpRequest } from "node:http";
|
|
2672
2696
|
import { request as httpsRequest } from "node:https";
|
|
2697
|
+
import { hostname as osHostname } from "node:os";
|
|
2698
|
+
|
|
2699
|
+
// src/pid.ts
|
|
2700
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2701
|
+
import { homedir as homedir9, hostname } from "node:os";
|
|
2702
|
+
import { dirname, join as join10 } from "node:path";
|
|
2703
|
+
var pidPath = join10(homedir9(), ".agendex", "daemon.pid");
|
|
2704
|
+
function writePid() {
|
|
2705
|
+
mkdirSync2(dirname(pidPath), { recursive: true });
|
|
2706
|
+
const info = {
|
|
2707
|
+
pid: process.pid,
|
|
2708
|
+
startedAtMs: Date.now(),
|
|
2709
|
+
hostname: hostname()
|
|
2710
|
+
};
|
|
2711
|
+
writeFileSync2(pidPath, JSON.stringify(info));
|
|
2712
|
+
}
|
|
2713
|
+
function readPidInfo() {
|
|
2714
|
+
if (!existsSync6(pidPath))
|
|
2715
|
+
return null;
|
|
2716
|
+
const raw = readFileSync3(pidPath, "utf-8").trim();
|
|
2717
|
+
const asNumber = Number(raw);
|
|
2718
|
+
if (Number.isFinite(asNumber) && asNumber > 0 && !raw.startsWith("{")) {
|
|
2719
|
+
return { pid: asNumber };
|
|
2720
|
+
}
|
|
2721
|
+
try {
|
|
2722
|
+
const parsed = JSON.parse(raw);
|
|
2723
|
+
if (Number.isFinite(parsed.pid) && parsed.pid > 0)
|
|
2724
|
+
return parsed;
|
|
2725
|
+
} catch {}
|
|
2726
|
+
return null;
|
|
2727
|
+
}
|
|
2728
|
+
function readPid() {
|
|
2729
|
+
return readPidInfo()?.pid ?? null;
|
|
2730
|
+
}
|
|
2731
|
+
function removePid() {
|
|
2732
|
+
try {
|
|
2733
|
+
unlinkSync(pidPath);
|
|
2734
|
+
} catch {}
|
|
2735
|
+
}
|
|
2736
|
+
function isRunning(pid) {
|
|
2737
|
+
try {
|
|
2738
|
+
process.kill(pid, 0);
|
|
2739
|
+
return true;
|
|
2740
|
+
} catch {
|
|
2741
|
+
return false;
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
// src/api.ts
|
|
2746
|
+
var cachedDeviceId;
|
|
2673
2747
|
function getCloudConfig() {
|
|
2674
2748
|
const config = loadConfig();
|
|
2675
2749
|
if (!config?.cloudToken)
|
|
@@ -2724,6 +2798,12 @@ async function refreshStoredToken(currentToken, convexUrl) {
|
|
|
2724
2798
|
async function sendHeartbeat() {
|
|
2725
2799
|
try {
|
|
2726
2800
|
const { token, convexUrl } = getCloudConfig();
|
|
2801
|
+
const pidInfo = readPidInfo();
|
|
2802
|
+
const heartbeatBody = JSON.stringify({
|
|
2803
|
+
deviceId: cachedDeviceId ??= loadOrCreateDeviceId(),
|
|
2804
|
+
hostname: pidInfo?.hostname ?? osHostname(),
|
|
2805
|
+
startedAtMs: pidInfo?.startedAtMs
|
|
2806
|
+
});
|
|
2727
2807
|
let activeToken = token;
|
|
2728
2808
|
let res = await requestText(`${convexUrl}/api/cli/heartbeat`, {
|
|
2729
2809
|
method: "POST",
|
|
@@ -2731,7 +2811,8 @@ async function sendHeartbeat() {
|
|
|
2731
2811
|
Authorization: `Bearer ${activeToken}`,
|
|
2732
2812
|
Connection: "close",
|
|
2733
2813
|
"Content-Type": "application/json"
|
|
2734
|
-
}
|
|
2814
|
+
},
|
|
2815
|
+
body: heartbeatBody
|
|
2735
2816
|
});
|
|
2736
2817
|
if (res.status === 401) {
|
|
2737
2818
|
const refreshedToken = await refreshStoredToken(activeToken, convexUrl);
|
|
@@ -2744,7 +2825,8 @@ async function sendHeartbeat() {
|
|
|
2744
2825
|
Authorization: `Bearer ${activeToken}`,
|
|
2745
2826
|
Connection: "close",
|
|
2746
2827
|
"Content-Type": "application/json"
|
|
2747
|
-
}
|
|
2828
|
+
},
|
|
2829
|
+
body: heartbeatBody
|
|
2748
2830
|
});
|
|
2749
2831
|
}
|
|
2750
2832
|
if (res.status === 401) {
|
|
@@ -2798,52 +2880,6 @@ function requestText(urlString, options) {
|
|
|
2798
2880
|
});
|
|
2799
2881
|
}
|
|
2800
2882
|
|
|
2801
|
-
// src/pid.ts
|
|
2802
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2803
|
-
import { homedir as homedir9, hostname } from "node:os";
|
|
2804
|
-
import { dirname, join as join10 } from "node:path";
|
|
2805
|
-
var pidPath = join10(homedir9(), ".agendex", "daemon.pid");
|
|
2806
|
-
function writePid() {
|
|
2807
|
-
mkdirSync2(dirname(pidPath), { recursive: true });
|
|
2808
|
-
const info = {
|
|
2809
|
-
pid: process.pid,
|
|
2810
|
-
startedAtMs: Date.now(),
|
|
2811
|
-
hostname: hostname()
|
|
2812
|
-
};
|
|
2813
|
-
writeFileSync2(pidPath, JSON.stringify(info));
|
|
2814
|
-
}
|
|
2815
|
-
function readPidInfo() {
|
|
2816
|
-
if (!existsSync6(pidPath))
|
|
2817
|
-
return null;
|
|
2818
|
-
const raw = readFileSync3(pidPath, "utf-8").trim();
|
|
2819
|
-
const asNumber = Number(raw);
|
|
2820
|
-
if (Number.isFinite(asNumber) && asNumber > 0 && !raw.startsWith("{")) {
|
|
2821
|
-
return { pid: asNumber };
|
|
2822
|
-
}
|
|
2823
|
-
try {
|
|
2824
|
-
const parsed = JSON.parse(raw);
|
|
2825
|
-
if (Number.isFinite(parsed.pid) && parsed.pid > 0)
|
|
2826
|
-
return parsed;
|
|
2827
|
-
} catch {}
|
|
2828
|
-
return null;
|
|
2829
|
-
}
|
|
2830
|
-
function readPid() {
|
|
2831
|
-
return readPidInfo()?.pid ?? null;
|
|
2832
|
-
}
|
|
2833
|
-
function removePid() {
|
|
2834
|
-
try {
|
|
2835
|
-
unlinkSync(pidPath);
|
|
2836
|
-
} catch {}
|
|
2837
|
-
}
|
|
2838
|
-
function isRunning(pid) {
|
|
2839
|
-
try {
|
|
2840
|
-
process.kill(pid, 0);
|
|
2841
|
-
return true;
|
|
2842
|
-
} catch {
|
|
2843
|
-
return false;
|
|
2844
|
-
}
|
|
2845
|
-
}
|
|
2846
|
-
|
|
2847
2883
|
// src/daemon.ts
|
|
2848
2884
|
var MAX_RESTARTS = 5;
|
|
2849
2885
|
var RESTART_WINDOW_MS = 60000;
|
|
@@ -3029,7 +3065,7 @@ import { join as join11 } from "node:path";
|
|
|
3029
3065
|
// package.json
|
|
3030
3066
|
var package_default = {
|
|
3031
3067
|
name: "agendex-cli",
|
|
3032
|
-
version: "0.
|
|
3068
|
+
version: "0.6.0",
|
|
3033
3069
|
description: "Agendex CLI for login, sync, and daemon workflows",
|
|
3034
3070
|
homepage: "https://github.com/Tyru5/Agendex#readme",
|
|
3035
3071
|
repository: {
|