agendex-cli 0.9.0 → 0.10.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/README.md +10 -2
- package/dist/cli.js +42 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `agendex-cli`
|
|
2
2
|
|
|
3
|
-
Node-compatible Agendex CLI for browser login, one-shot sync, daemon supervision, status checks, and daemon cleanup.
|
|
3
|
+
Node-compatible Agendex CLI for browser login, opening the web app, one-shot sync, daemon supervision, status checks, and daemon cleanup.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -16,6 +16,8 @@ bun install -g agendex-cli
|
|
|
16
16
|
```bash
|
|
17
17
|
agendex login # Authenticate via browser OAuth (agendex.dev)
|
|
18
18
|
agendex login --url <url> # Login to a self-hosted instance
|
|
19
|
+
agendex open # Open the Agendex web app in your default browser
|
|
20
|
+
agendex open --url <url> # Open a self-hosted deployment
|
|
19
21
|
agendex logout # Clear stored cloud token
|
|
20
22
|
agendex configure # Select which agents/adapters to index
|
|
21
23
|
agendex start # Start daemon (backgrounds itself)
|
|
@@ -86,7 +88,7 @@ Before running `start`, `configure`, or `sync`, the CLI checks for a newer publi
|
|
|
86
88
|
[agendex] run: npm i -g agendex-cli
|
|
87
89
|
```
|
|
88
90
|
|
|
89
|
-
The check is skipped for `stop`, `status`, `login`, `logout`, `cleanup`, and `help`.
|
|
91
|
+
The check is skipped for `stop`, `status`, `login`, `logout`, `open`, `cleanup`, and `help`.
|
|
90
92
|
|
|
91
93
|
## Supported Runtime
|
|
92
94
|
|
|
@@ -106,3 +108,9 @@ agendex login --url https://agendex.yourdomain.com
|
|
|
106
108
|
This opens your deployment's OAuth flow and stores the returned `cloudToken` and `convexUrl` in your active config directory (`~/.agendex/config.json` for prod, `~/.agendex-dev/config.json` when using `--dev` or `AGENDEX_DEV=1`).
|
|
107
109
|
|
|
108
110
|
The target can also be set via `AGENDEX_SITE_URL` env var. For local development against the default dev app URL, use `agendex login --dev` or set `AGENDEX_DEV=1` (see [Dev vs prod](#dev-vs-prod-config-directory) above).
|
|
111
|
+
|
|
112
|
+
## Open the web app
|
|
113
|
+
|
|
114
|
+
`agendex open` launches your default browser to the same base URL as the default login target (`https://app.agendex.dev` in prod, or the local EE dev URL when using `--dev` / `AGENDEX_DEV=1`). Override with `agendex open --url <url>` or `AGENDEX_SITE_URL`.
|
|
115
|
+
|
|
116
|
+
If launching the browser is undesirable (for example in CI), set `AGENDEX_DISABLE_BROWSER=1`; the CLI still prints the URL to visit.
|
package/dist/cli.js
CHANGED
|
@@ -2398,7 +2398,7 @@ async function loadOrInitConfig(options = {}) {
|
|
|
2398
2398
|
}
|
|
2399
2399
|
// ../shared/src/daemon-status.ts
|
|
2400
2400
|
var CLI_DAEMON_HEARTBEAT_INTERVAL_MS = 30000;
|
|
2401
|
-
var CLI_DAEMON_STALE_AFTER_MS = CLI_DAEMON_HEARTBEAT_INTERVAL_MS *
|
|
2401
|
+
var CLI_DAEMON_STALE_AFTER_MS = CLI_DAEMON_HEARTBEAT_INTERVAL_MS * 5;
|
|
2402
2402
|
// ../shared/src/services/plan-service.ts
|
|
2403
2403
|
import { existsSync as existsSync4, readdirSync as readdirSync3, statSync } from "node:fs";
|
|
2404
2404
|
import { lstat, mkdir, readdir as readdir2, readFile as readFile6, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
|
|
@@ -2817,6 +2817,13 @@ async function sendHeartbeat() {
|
|
|
2817
2817
|
}
|
|
2818
2818
|
} catch {}
|
|
2819
2819
|
}
|
|
2820
|
+
async function sendShutdown() {
|
|
2821
|
+
try {
|
|
2822
|
+
const { token, convexUrl } = getCloudConfig();
|
|
2823
|
+
cachedDeviceId ??= loadOrCreateDeviceId();
|
|
2824
|
+
await deleteDaemons([cachedDeviceId]);
|
|
2825
|
+
} catch {}
|
|
2826
|
+
}
|
|
2820
2827
|
async function refreshToken(currentToken, convexUrl) {
|
|
2821
2828
|
const res = await requestText(`${convexUrl}/api/cli/refresh`, {
|
|
2822
2829
|
method: "POST",
|
|
@@ -3201,7 +3208,7 @@ async function runWorker() {
|
|
|
3201
3208
|
const adapters = resolveAdapters(config.enabledAdapters);
|
|
3202
3209
|
setActiveAdapters(adapters);
|
|
3203
3210
|
console.log(`[agendex] daemon starting with ${config.enabledAdapters.length} adapters`);
|
|
3204
|
-
sendHeartbeat();
|
|
3211
|
+
await sendHeartbeat();
|
|
3205
3212
|
const syncCache = loadSyncCache();
|
|
3206
3213
|
const syncQueue = [];
|
|
3207
3214
|
let syncing = false;
|
|
@@ -3289,6 +3296,12 @@ async function runWorker() {
|
|
|
3289
3296
|
processSyncQueue();
|
|
3290
3297
|
});
|
|
3291
3298
|
console.log(`[agendex] daemon running. Watching for file changes...`);
|
|
3299
|
+
async function gracefulShutdown() {
|
|
3300
|
+
await sendShutdown();
|
|
3301
|
+
process.exit(0);
|
|
3302
|
+
}
|
|
3303
|
+
process.on("SIGTERM", () => void gracefulShutdown());
|
|
3304
|
+
process.on("SIGINT", () => void gracefulShutdown());
|
|
3292
3305
|
await new Promise(() => {});
|
|
3293
3306
|
}
|
|
3294
3307
|
async function startSupervisor() {
|
|
@@ -3396,7 +3409,7 @@ import { join as join12 } from "node:path";
|
|
|
3396
3409
|
// package.json
|
|
3397
3410
|
var package_default = {
|
|
3398
3411
|
name: "agendex-cli",
|
|
3399
|
-
version: "0.
|
|
3412
|
+
version: "0.10.0",
|
|
3400
3413
|
description: "Agendex CLI for login, sync, and daemon workflows",
|
|
3401
3414
|
homepage: "https://github.com/Tyru5/Agendex#readme",
|
|
3402
3415
|
repository: {
|
|
@@ -3506,6 +3519,19 @@ function isNewer(latest, current) {
|
|
|
3506
3519
|
return false;
|
|
3507
3520
|
}
|
|
3508
3521
|
|
|
3522
|
+
// src/web.ts
|
|
3523
|
+
async function openAgendexWeb(siteUrlOverride) {
|
|
3524
|
+
const base = siteUrlOverride ?? getDefaultSiteUrl();
|
|
3525
|
+
const url = base.replace(/\/$/, "");
|
|
3526
|
+
console.log("[agendex] Opening Agendex in your browser...");
|
|
3527
|
+
console.log(`[agendex] If it doesn't open, visit: ${url}`);
|
|
3528
|
+
if (process.env.AGENDEX_DISABLE_BROWSER === "1") {
|
|
3529
|
+
console.log("[agendex] Browser launch disabled by AGENDEX_DISABLE_BROWSER=1.");
|
|
3530
|
+
} else {
|
|
3531
|
+
openBrowser(url);
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
|
|
3509
3535
|
// src/cli.ts
|
|
3510
3536
|
var args = process.argv.slice(2);
|
|
3511
3537
|
var devFlag = args.includes("--dev");
|
|
@@ -3532,6 +3558,7 @@ async function main() {
|
|
|
3532
3558
|
"status",
|
|
3533
3559
|
"login",
|
|
3534
3560
|
"logout",
|
|
3561
|
+
"open",
|
|
3535
3562
|
"cleanup",
|
|
3536
3563
|
"help",
|
|
3537
3564
|
"--help",
|
|
@@ -3546,6 +3573,12 @@ async function main() {
|
|
|
3546
3573
|
}
|
|
3547
3574
|
}
|
|
3548
3575
|
switch (command) {
|
|
3576
|
+
case "open": {
|
|
3577
|
+
const urlIdx = args.indexOf("--url");
|
|
3578
|
+
const siteUrl = urlIdx !== -1 ? args[urlIdx + 1] : undefined;
|
|
3579
|
+
await openAgendexWeb(siteUrl);
|
|
3580
|
+
return 0;
|
|
3581
|
+
}
|
|
3549
3582
|
case "start": {
|
|
3550
3583
|
if (args.includes("--daemon")) {
|
|
3551
3584
|
await startSupervisor();
|
|
@@ -3592,6 +3625,7 @@ async function main() {
|
|
|
3592
3625
|
writeStderr("[agendex] daemon did not stop in time");
|
|
3593
3626
|
} else {
|
|
3594
3627
|
removePid();
|
|
3628
|
+
await sendShutdown();
|
|
3595
3629
|
writeStdout(`[agendex] daemon stopped (PID ${pid})`);
|
|
3596
3630
|
}
|
|
3597
3631
|
return isRunning(pid) ? 1 : 0;
|
|
@@ -3713,6 +3747,7 @@ async function main() {
|
|
|
3713
3747
|
const allDevices = await fetchDevices();
|
|
3714
3748
|
if (allDevices.length > 0) {
|
|
3715
3749
|
const now = Date.now();
|
|
3750
|
+
const localDeviceId = config.deviceId;
|
|
3716
3751
|
writeStdout(`[agendex] All daemons:`);
|
|
3717
3752
|
for (const device of allDevices) {
|
|
3718
3753
|
const age = device.lastSeenAt ? now - device.lastSeenAt : Number.POSITIVE_INFINITY;
|
|
@@ -3720,7 +3755,8 @@ async function main() {
|
|
|
3720
3755
|
const uptimeStr = device.startedAtMs != null ? formatDuration(now - device.startedAtMs) : "~";
|
|
3721
3756
|
const pidStr = device.pid != null ? String(device.pid) : "~";
|
|
3722
3757
|
const hostnameStr = device.hostname ?? "~";
|
|
3723
|
-
|
|
3758
|
+
const isLocal = localDeviceId && device.deviceId === localDeviceId;
|
|
3759
|
+
writeStdout(`- hostname: ${hostnameStr}${isLocal ? " (this machine)" : ""}
|
|
3724
3760
|
pid: ${pidStr}
|
|
3725
3761
|
uptime: ${uptimeStr}
|
|
3726
3762
|
status: ${status}`);
|
|
@@ -3744,6 +3780,8 @@ Usage:
|
|
|
3744
3780
|
agendex stop Stop the running daemon
|
|
3745
3781
|
agendex login Authenticate via browser OAuth (agendex.dev)
|
|
3746
3782
|
agendex login --url <url> Login to a self-hosted instance
|
|
3783
|
+
agendex open Open the Agendex web app in your browser
|
|
3784
|
+
agendex open --url <url> Open a self-hosted instance
|
|
3747
3785
|
agendex logout Clear stored cloud token
|
|
3748
3786
|
agendex configure Select which agents/adapters to index
|
|
3749
3787
|
agendex sync One-shot scan + sync to cloud (skips unchanged plans)
|