skydive-cli 0.5.0-beta.3 → 0.5.0-beta.4

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/js/bin.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-DtuXkIkR.mjs";
2
+ import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-RmWjKIHD.mjs";
3
3
  import { A as getStoredApiKeyWorkspaceName, C as getLastSeenVersion, F as resolveManagementAuth, I as resolveSession, M as resolveAppUrl, N as resolveChatAuth, O as getShareMachineDefault, P as resolveConfig, R as saveConfig, S as getConfigPath, T as getPromptHistoryPath, V as setLastSeenVersion, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getUpdateCheckDisabled, k as getStoredApiKeyId, v as DEFAULT_API_URL, w as getPreference, x as deleteConfig, z as saveSession } from "./print-CbayCa87.mjs";
4
4
  import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
5
5
  import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
6
6
  import { t as createRestClient } from "./rest-BY2nADw5.mjs";
7
7
  import "./billing-blocked-2wju4gC_.mjs";
8
8
  import { a as registerPortalDevice, c as resolveMachineIdentity, i as grantPortalAccess, n as fetchPortalDevices, o as revokePortalAccess, r as findThisDevice } from "./client-Dd5sMXPv.mjs";
9
- import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-Bq93vOIk.mjs";
9
+ import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-BYlIJN6x.mjs";
10
10
  import { t as SandboxStream } from "./client-Cn2af31H.mjs";
11
11
  import { hideBin } from "yargs/helpers";
12
12
  import yargs from "yargs";
@@ -1516,7 +1516,7 @@ const importCommand = {
1516
1516
  process.exit(1);
1517
1517
  }
1518
1518
  }
1519
- const { runChat } = await import("./boot-BVVbrf2k.mjs");
1519
+ const { runChat } = await import("./boot-B_93T51X.mjs");
1520
1520
  await runChat({
1521
1521
  appUrl,
1522
1522
  sessionToken: session.value.sessionToken,
@@ -1543,7 +1543,7 @@ async function runImportPrintMode({ argv, appUrl }) {
1543
1543
  printError(`${session.error.message} For non-interactive use, run \`skydive auth login --web\` first, or set SKYDIVE_SESSION_TOKEN.`);
1544
1544
  process.exit(1);
1545
1545
  }
1546
- const { connectMachineShare } = await import("./print-share-C1LPsgTP.mjs");
1546
+ const { connectMachineShare } = await import("./print-share-uwUG16Ov.mjs");
1547
1547
  const machineShare = await connectMachineShare({
1548
1548
  appUrl,
1549
1549
  sessionToken: session.value.sessionToken,
@@ -1928,7 +1928,7 @@ const chatCommand = {
1928
1928
  sessionToken: auth.value.token,
1929
1929
  agentSelector: argv.agent ?? null
1930
1930
  });
1931
- const { runChat } = await import("./boot-BVVbrf2k.mjs");
1931
+ const { runChat } = await import("./boot-B_93T51X.mjs");
1932
1932
  await runChat({
1933
1933
  appUrl: auth.value.appUrl,
1934
1934
  sessionToken: auth.value.token,
@@ -2020,7 +2020,7 @@ async function runPrintMode({ argv, appUrl }) {
2020
2020
  process.exit(1);
2021
2021
  }
2022
2022
  } else {
2023
- const { connectMachineShare } = await import("./print-share-C1LPsgTP.mjs");
2023
+ const { connectMachineShare } = await import("./print-share-uwUG16Ov.mjs");
2024
2024
  machineShare = await connectMachineShare({
2025
2025
  appUrl: auth.value.appUrl,
2026
2026
  sessionToken: auth.value.token,
@@ -2287,7 +2287,7 @@ const switchCommand = {
2287
2287
  printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
2288
2288
  process.exit(1);
2289
2289
  }
2290
- const { runWorkspacePicker } = await import("./boot-BVVbrf2k.mjs");
2290
+ const { runWorkspacePicker } = await import("./boot-B_93T51X.mjs");
2291
2291
  await runWorkspacePicker(session);
2292
2292
  return;
2293
2293
  }
@@ -2366,7 +2366,7 @@ const openCommand = {
2366
2366
  const agent = argv.agent ? resolveAgent((await fetchPortalDevices(session)).agents, argv.agent) : null;
2367
2367
  const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
2368
2368
  const { machineName } = await resolveMachineIdentity();
2369
- const { PortalDaemonClient } = await import("./daemon-client-srAit8Fz.mjs");
2369
+ const { PortalDaemonClient } = await import("./daemon-client-Z4Ce4zf-.mjs");
2370
2370
  let lastLine = "";
2371
2371
  let signalConnected;
2372
2372
  const connected = new Promise((resolve) => {
@@ -4169,7 +4169,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
4169
4169
  process.exit(0);
4170
4170
  }
4171
4171
  if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
4172
- const { runPortalDaemon } = await import("./daemon-DDBIumf1.mjs");
4172
+ const { runPortalDaemon } = await import("./daemon-CBvFKDpy.mjs");
4173
4173
  runPortalDaemon(process.argv);
4174
4174
  } else runCli();
4175
4175
  function runCli() {
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-DtuXkIkR.mjs";
2
+ import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-RmWjKIHD.mjs";
3
3
  import { B as saveTheme, D as getSavedTheme, E as getReviewStateDir, L as resolveWebUrl, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL } from "./print-CbayCa87.mjs";
4
4
  import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
5
5
  import { a as isRecord, i as errorMessage, n as errorDetail, r as sendErrorMessage, t as createRestClient } from "./rest-BY2nADw5.mjs";
6
6
  import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-2wju4gC_.mjs";
7
7
  import { t as PortalClient } from "./client-Dd5sMXPv.mjs";
8
- import "./daemon-Bq93vOIk.mjs";
8
+ import "./daemon-BYlIJN6x.mjs";
9
9
  import { t as SandboxStream } from "./client-Cn2af31H.mjs";
10
- import { t as PortalDaemonClient } from "./daemon-client-Bewt98dE.mjs";
10
+ import { t as PortalDaemonClient } from "./daemon-client-DPjmvIDE.mjs";
11
11
  import { t as runRawPtyPassthrough } from "./raw-pty-B6mAroiI.mjs";
12
12
  import * as os$1 from "node:os";
13
13
  import { homedir, platform, release, tmpdir } from "node:os";
@@ -8,6 +8,43 @@ import { createHash } from "node:crypto";
8
8
  import { connect, createServer } from "node:net";
9
9
  import { access, appendFile, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
10
10
 
11
+ //#region ../portal-daemon/src/build-stamp.ts
12
+ /**
13
+ * This build's stamp: the unix commit time (seconds) of the source it was
14
+ * compiled from. Empty string when unstamped (a dev source run without the
15
+ * env override).
16
+ *
17
+ * Why a commit time and not a package version: the daemon ships inside two
18
+ * independently-versioned installers (the skydive CLI and the desktop app),
19
+ * so their semvers are not comparable — but both build from this repo, so
20
+ * the commit time of the built tree is one monotonic clock they share.
21
+ */
22
+ function portalDaemonBuild() {
23
+ return "1786574791";
24
+ }
25
+ /**
26
+ * Whether a client carrying `mine` should replace a running daemon carrying
27
+ * `theirs` (newest build wins):
28
+ *
29
+ * - an unstamped client never takes over — it can't prove it's newer;
30
+ * - a stamped client replaces an unstamped daemon — every stamped build
31
+ * postdates stamping, so the unstamped daemon is older by construction;
32
+ * - otherwise strictly greater wins; equal keeps the incumbent, so two
33
+ * identical builds never bounce the daemon between them.
34
+ */
35
+ function isNewerBuild(mine, theirs) {
36
+ const mineAt = parseStamp(mine);
37
+ if (mineAt === null) return false;
38
+ const theirsAt = parseStamp(theirs);
39
+ if (theirsAt === null) return true;
40
+ return mineAt > theirsAt;
41
+ }
42
+ function parseStamp(stamp) {
43
+ if (!/^[0-9]+$/.test(stamp)) return null;
44
+ return Number(stamp);
45
+ }
46
+
47
+ //#endregion
11
48
  //#region ../portal-daemon/src/local-protocol.ts
12
49
  /**
13
50
  * Local IPC between the portal DAEMON and the `skydive` CLI processes attached
@@ -220,6 +257,7 @@ const daemonStatusResultSchema = z.object({
220
257
  v: z.number(),
221
258
  pid: z.number(),
222
259
  appUrl: z.string(),
260
+ build: z.string().default(""),
223
261
  portal: z.object({
224
262
  status: z.enum([
225
263
  "off",
@@ -516,6 +554,7 @@ var PortalDaemon = class {
516
554
  v: LOCAL_PROTOCOL_VERSION,
517
555
  pid: process.pid,
518
556
  appUrl: this.appUrl,
557
+ build: portalDaemonBuild(),
519
558
  portal: {
520
559
  status: portal?.status ?? "off",
521
560
  machineName: portal?.machineName ?? "",
@@ -573,10 +612,23 @@ var PortalDaemon = class {
573
612
  * before dispatching a normal command — the same pattern the update-check
574
613
  * worker uses, so it survives bundling (import.meta.url points at the bundle,
575
614
  * not a standalone daemon module).
615
+ *
616
+ * Newest build wins: the daemon is embedded in two independently-updated
617
+ * installers (the skydive CLI and the desktop app), and whoever spawned first
618
+ * would otherwise hold the socket forever — a stale desktop daemon serving a
619
+ * newer CLI indefinitely. So when a daemon is already listening, compare its
620
+ * build stamp to ours: if ours is strictly newer, ask it to shut down (it
621
+ * drains attached clients, who reconnect within ~500ms) and spawn from this
622
+ * binary. Both spawners apply the same rule, so a host converges on the
623
+ * newest installed build with at most one bounce.
576
624
  */
577
625
  async function ensureDaemonRunning(appUrl) {
578
626
  const { socketPath } = daemonPaths(appUrl);
579
- if (await isDaemonListening(socketPath)) return;
627
+ if (await isDaemonListening(socketPath)) {
628
+ const status = await queryDaemonStatus(appUrl);
629
+ if (!status || !isNewerBuild(portalDaemonBuild(), status.build)) return;
630
+ if (await stopDaemon(appUrl) === "failed") return;
631
+ }
580
632
  const entry = process.argv[1];
581
633
  const args = entry ? [
582
634
  entry,
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import "./client-Dd5sMXPv.mjs";
3
- import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-Bq93vOIk.mjs";
3
+ import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-BYlIJN6x.mjs";
4
4
 
5
5
  export { runPortalDaemon };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-Bq93vOIk.mjs";
2
+ import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-BYlIJN6x.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { connect } from "node:net";
5
5
 
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import "./client-Dd5sMXPv.mjs";
3
+ import "./daemon-BYlIJN6x.mjs";
4
+ import { t as PortalDaemonClient } from "./daemon-client-DPjmvIDE.mjs";
5
+
6
+ export { PortalDaemonClient };
@@ -14,7 +14,7 @@ import { n as printError } from "./output-DYzzdXYV.mjs";
14
14
  * the reply (and to --json).
15
15
  */
16
16
  async function connectMachineShare({ appUrl, sessionToken, timeoutHint }) {
17
- const { PortalClient } = await import("./client-CKBQ8pft.mjs");
17
+ const { PortalClient } = await import("./client-DZstLQ_1.mjs");
18
18
  let signalConnected;
19
19
  const connected = new Promise((resolve) => {
20
20
  signalConnected = resolve;
@@ -8,7 +8,7 @@ import fs from "node:fs";
8
8
 
9
9
  //#region package.json
10
10
  var name = "skydive-cli";
11
- var version$1 = "0.5.0-beta.3";
11
+ var version$1 = "0.5.0-beta.4";
12
12
 
13
13
  //#endregion
14
14
  //#region src/auth/organization.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skydive-cli",
3
- "version": "0.5.0-beta.3",
3
+ "version": "0.5.0-beta.4",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./client-Dd5sMXPv.mjs";
3
- import "./daemon-Bq93vOIk.mjs";
4
- import { t as PortalDaemonClient } from "./daemon-client-Bewt98dE.mjs";
5
-
6
- export { PortalDaemonClient };