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.
Files changed (3) hide show
  1. package/README.md +10 -2
  2. package/dist/cli.js +42 -4
  3. 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 * 3;
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.9.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
- writeStdout(`- hostname: ${hostnameStr}
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)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agendex-cli",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Agendex CLI for login, sync, and daemon workflows",
5
5
  "homepage": "https://github.com/Tyru5/Agendex#readme",
6
6
  "repository": {