skydive-cli 0.2.0-beta.630 → 0.2.0-beta.684

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 CHANGED
@@ -131,10 +131,45 @@ skydive portal open # open the portal to this machine, headless
131
131
  skydive portal grant --agent <id|name>
132
132
  skydive portal revoke --agent <id|name>
133
133
  skydive portal status
134
+
135
+ skydive completion install # set up TAB completion for your shell
134
136
  ```
135
137
 
136
138
  Global flags: `--json`, `--quiet`, `--api-url <url>`.
137
139
 
140
+ ## Shell completions
141
+
142
+ bash, zsh, and fish. One command sets them up for the shell you're in:
143
+
144
+ ```sh
145
+ skydive completion install
146
+ ```
147
+
148
+ It writes to `~/.bashrc` (or `~/.bash_profile` on macOS), `~/.zshrc`, or
149
+ `~/.config/fish/completions/skydive.fish`, respecting `ZDOTDIR` and
150
+ `XDG_CONFIG_HOME`, and picking whichever bash startup file you already have.
151
+ Open a new shell to pick them up. Re-running it — after an upgrade, say —
152
+ refreshes the block it wrote instead of appending a second copy, and leaves
153
+ the rest of the file alone. Pass a shell explicitly to set up one you're not
154
+ currently in: `skydive completion install fish`.
155
+
156
+ To see the script instead of installing it, or to source it from somewhere of
157
+ your own choosing:
158
+
159
+ ```sh
160
+ skydive completion zsh # print it
161
+ eval "$(skydive completion bash)" # this shell only
162
+ ```
163
+
164
+ The script doesn't contain the command list — it asks the CLI for candidates
165
+ on each TAB, so completions never drift from the installed version. That
166
+ covers commands, subcommands, flags, and the values of flags with a fixed set
167
+ (`skydive agents list --scope <TAB>` → `mine org`). One TAB costs one short
168
+ CLI invocation (~150 ms).
169
+
170
+ zsh and fish show each command's description alongside it; bash lists names
171
+ only.
172
+
138
173
  ## `skydive import`
139
174
 
140
175
  Migrating from Claude Code, Cursor, or OpenCode? `skydive import` opens a
package/dist/js/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as setActiveWorkspace, S as listWorkspaces, T as version, _ as themes, b as getActiveWorkspaceId, o as brandHelpArt, t as installCrashHandler, w as name, x as getSessionIdentity, y as ensureActiveOrganization } from "./install-ZNL9Ss_c.mjs";
2
+ import { C as setActiveWorkspace, S as listWorkspaces, T as version, _ as themes, b as getActiveWorkspaceId, o as brandHelpArt, t as installCrashHandler, w as name, x as getSessionIdentity, y as ensureActiveOrganization } from "./install-DgwIUN1J.mjs";
3
3
  import { A as resolveAppUrl, C as getPromptHistoryPath, D as getStoredApiKeyId, E as getShareMachineDefault, F as saveConfig, I as saveSession, M as resolveManagementAuth, N as resolveSession, O as getStoredApiKeyWorkspaceName, R as setLastSeenVersion, S as getLastSeenVersion, _ as API_KEY_PREFIX, b as deleteConfig, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as resolveConfig, k as getUpdateCheckDisabled, v as DEFAULT_API_URL, x as getConfigPath } from "./print-BUbxOvnm.mjs";
4
4
  import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
5
5
  import { n as createRestClient } from "./rest-CCyln7vx.mjs";
@@ -8,14 +8,14 @@ import { c as PORTAL_DAEMON_FLAG, i as queryDaemonStatus, l as daemonPaths, n as
8
8
  import { t as SandboxStream } from "./client-DfcJFEbh.mjs";
9
9
  import { hideBin } from "yargs/helpers";
10
10
  import yargs from "yargs";
11
- import { hostname } from "node:os";
11
+ import os, { hostname } from "node:os";
12
12
  import path from "node:path";
13
13
  import { err, ok } from "neverthrow";
14
14
  import { z } from "zod";
15
15
  import open from "open";
16
+ import fs from "node:fs";
16
17
  import { spawn, spawnSync } from "node:child_process";
17
18
  import { createHash } from "node:crypto";
18
- import fs from "node:fs";
19
19
  import zlib from "node:zlib";
20
20
  import fsp from "node:fs/promises";
21
21
  import semver from "semver";
@@ -713,6 +713,308 @@ const authCommand = {
713
713
  handler: () => {}
714
714
  };
715
715
 
716
+ //#endregion
717
+ //#region src/commands/completion.ts
718
+ /**
719
+ * The argv sentinel yargs answers with completion candidates for a partially
720
+ * typed command line. The scripts below are the only callers; `bin.ts` also
721
+ * matches on it to keep notices off the user's prompt (see isCompletionProbe).
722
+ */
723
+ const COMPLETION_PROBE_FLAG = "--get-yargs-completions";
724
+ const SUPPORTED_SHELLS = [
725
+ "bash",
726
+ "zsh",
727
+ "fish"
728
+ ];
729
+ /**
730
+ * True when this invocation is a shell asking for completion candidates
731
+ * rather than a user running a command. Such a run must print candidates and
732
+ * nothing else: stderr is still a TTY inside a completion function, so an
733
+ * update notice would be drawn onto the prompt line, and the what's-new
734
+ * notice is one-shot — a TAB press would consume it unread.
735
+ */
736
+ function isCompletionProbe(argv) {
737
+ return argv.includes(COMPLETION_PROBE_FLAG);
738
+ }
739
+ /**
740
+ * Blank the word the cursor is still on before yargs sees a probe.
741
+ *
742
+ * yargs' completion walk treats *every* token in the probe as a finished
743
+ * command, the word under the cursor included: it scans the args for one that
744
+ * names a command, descends into that command's builder, and answers from
745
+ * there. So a fully typed command name answers with nothing —
746
+ * `skydive conv<TAB>` descends into the `conv` alias of `conversations` and
747
+ * emits an empty list, which leaves an alias that can never be expanded and a
748
+ * `skydive agents<TAB>` that won't even add its trailing space. In bash it is
749
+ * worse than a no-op: `complete -o default` reads the empty list as "no
750
+ * candidates" and offers local *filenames* instead.
751
+ *
752
+ * The three scripts all send the partial word as the last token — that is
753
+ * yargs' wire format, not something we chose — so drop it here and let the
754
+ * shell filter the full candidate list by prefix. That is already what happens
755
+ * for any partial that doesn't happen to name a command (`skydive conve<TAB>`
756
+ * gets all 13 commands back today and bash/zsh/fish narrow them), so this only
757
+ * removes the special case, it doesn't change the contract.
758
+ *
759
+ * Two tokens are left alone:
760
+ * - one starting with `-`, because yargs uses exactly that to decide between
761
+ * offering options and offering subcommands, and
762
+ * - the command name itself, so a probe never degrades to an empty script name.
763
+ */
764
+ function normalizeProbeArgv(argv) {
765
+ const flag = argv.indexOf(COMPLETION_PROBE_FLAG);
766
+ if (flag === -1 || argv.length - flag < 3) return argv;
767
+ const last = argv[argv.length - 1] ?? "";
768
+ if (last === "" || last.startsWith("-")) return argv;
769
+ return [...argv.slice(0, -1), ""];
770
+ }
771
+ const blockStart = (name) => `###-begin-${name}-completions-###`;
772
+ const blockEnd = (name) => `###-end-${name}-completions-###`;
773
+ /**
774
+ * Emit a completion script that asks the CLI itself for candidates on every
775
+ * TAB, rather than baking today's command tree into the script. bash and zsh
776
+ * are adapted from yargs' own templates
777
+ * (node_modules/yargs/build/lib/completion-templates.js); fish is
778
+ * hand-written, as yargs ships no fish template. Differences from yargs:
779
+ *
780
+ * - The shell is an explicit argument, not inferred from `$SHELL` at generate
781
+ * time, so `skydive completion zsh` is meaningful from any shell.
782
+ * - The script calls `skydive` off PATH instead of the absolute path of the
783
+ * generating process, which would go stale on every version bump under a
784
+ * version manager.
785
+ * - The probe's wire format is pinned. yargs picks it from `SHELL`/`ZSH_NAME`
786
+ * — plain lines normally, `value:description` when either says "zsh" — so
787
+ * a bash user whose login shell is zsh would otherwise get descriptions
788
+ * stuffed into COMPREPLY. bash asks for plain lines; zsh and fish ask for
789
+ * the descriptive format and render the descriptions.
790
+ */
791
+ function renderCompletionScript(shell, commandName = "skydive") {
792
+ if (shell === "zsh") return zshScript(commandName);
793
+ if (shell === "fish") return fishScript(commandName);
794
+ return bashScript(commandName);
795
+ }
796
+ function bashScript(name) {
797
+ const fn = `_${name}_completions`;
798
+ return `${blockStart(name)}
799
+ #
800
+ # ${name} command completion script, generated by \`${name} completion bash\`.
801
+ # Installed by \`${name} completion install bash\`; edits inside this block
802
+ # are overwritten on the next install.
803
+ #
804
+ ${fn}()
805
+ {
806
+ local cur_word args candidates
807
+
808
+ cur_word="\${COMP_WORDS[COMP_CWORD]}"
809
+ args=("\${COMP_WORDS[@]}")
810
+
811
+ candidates=$(SHELL=bash ZSH_NAME= ${name} ${COMPLETION_PROBE_FLAG} "\${args[@]}" 2>/dev/null)
812
+
813
+ COMPREPLY=( $(compgen -W "\${candidates}" -- "\${cur_word}") )
814
+
815
+ return 0
816
+ }
817
+ complete -o bashdefault -o default -F ${fn} ${name}
818
+ ${blockEnd(name)}
819
+ `;
820
+ }
821
+ function zshScript(name) {
822
+ const fn = `_${name}_completions`;
823
+ return `${blockStart(name)}
824
+ #
825
+ # ${name} command completion script, generated by \`${name} completion zsh\`.
826
+ # Installed by \`${name} completion install zsh\`; edits inside this block
827
+ # are overwritten on the next install.
828
+ #
829
+ ${fn}()
830
+ {
831
+ local reply
832
+ local si=$IFS
833
+ IFS=$'\\n' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" SHELL=zsh ${name} ${COMPLETION_PROBE_FLAG} "\${words[@]}" 2>/dev/null))
834
+ IFS=$si
835
+ _describe 'values' reply
836
+ }
837
+ # compdef only exists once compinit has run. Sourcing this block from a .zshrc
838
+ # that never calls compinit (or calls it later) would otherwise fail with
839
+ # "command not found: compdef".
840
+ #
841
+ # -i is load-bearing: a bare compinit that finds an insecure directory on fpath
842
+ # stops to ask "Ignore insecure directories and continue?", and where it cannot
843
+ # open the terminal it prints "compinit: initialization aborted" and defines no
844
+ # compdef at all -- so the line below fails and the user gets no completions.
845
+ # An insecure fpath entry is ordinary, not exotic: Homebrew's
846
+ # share/zsh/site-functions is writable by the installing user. -i skips those
847
+ # directories and carries on, which beats prompting from someone's shell
848
+ # startup.
849
+ if ! type compdef >/dev/null 2>&1; then
850
+ autoload -Uz compinit && compinit -i
851
+ fi
852
+ compdef ${fn} ${name}
853
+ ${blockEnd(name)}
854
+ `;
855
+ }
856
+ function fishScript(name) {
857
+ const fn = `__${name}_completions`;
858
+ return `${blockStart(name)}
859
+ #
860
+ # ${name} command completion script, generated by \`${name} completion fish\`.
861
+ # Installed by \`${name} completion install fish\`; edits are overwritten on
862
+ # the next install.
863
+ #
864
+ function ${fn}
865
+ set -l tokens (commandline --current-process --tokenize --cut-at-cursor)
866
+ set -l current (commandline --current-token --cut-at-cursor)
867
+
868
+ for line in (ZSH_NAME=zsh ${name} ${COMPLETION_PROBE_FLAG} $tokens "$current" 2>/dev/null)
869
+ set -l masked (string replace --all -- '\\:' \\x01 $line)
870
+ set -l parts (string split --max 1 -- ':' $masked)
871
+ set -l value (string replace --all -- \\x01 ':' $parts[1])
872
+
873
+ # Filter by the partial token ourselves. fish 3.3 and older (Ubuntu
874
+ # 22.04 LTS ships 3.3.1) skip their own matching for any candidate that
875
+ # carries a description, so \`${name} ag<TAB>\` there offers every
876
+ # command instead of the one that matches -- and a description is the
877
+ # whole reason this script asks for the descriptive wire format. Newer
878
+ # fish filters, so this is a no-op on it. Compared by length rather
879
+ # than \`string match\` so a token holding a glob character stays
880
+ # literal. Prefix matching is also what bash's \`compgen -W\` and zsh's
881
+ # \`_describe\` do, so the three shells now agree.
882
+ if test (string sub --length (string length -- "$current") -- "$value") != "$current"
883
+ continue
884
+ end
885
+
886
+ if set -q parts[2]
887
+ printf '%s\\t%s\\n' $value (string replace --all -- \\x01 ':' $parts[2])
888
+ else
889
+ printf '%s\\n' $value
890
+ end
891
+ end
892
+ end
893
+
894
+ # -f: only our candidates, no filename fallback. -k: keep the CLI's own order
895
+ # instead of fish's alphabetical sort.
896
+ complete -c ${name} -f -k -a '(${fn})'
897
+ ${blockEnd(name)}
898
+ `;
899
+ }
900
+ const defaultInstallEnv = () => ({
901
+ home: os.homedir(),
902
+ platform: process.platform,
903
+ env: process.env,
904
+ exists: fs.existsSync
905
+ });
906
+ /**
907
+ * The shell to install for when the user didn't name one. `$SHELL` is the
908
+ * only signal available: a completion install runs as a child process, so the
909
+ * invoking shell's own variables (`$ZSH_VERSION`, `$FISH_VERSION`) aren't
910
+ * visible here.
911
+ */
912
+ function detectShell(env = process.env) {
913
+ const shell = env["SHELL"];
914
+ if (!shell) return null;
915
+ const name = path.basename(shell);
916
+ return SUPPORTED_SHELLS.find((candidate) => name === candidate) ?? null;
917
+ }
918
+ function completionTarget(shell, deps = defaultInstallEnv()) {
919
+ const { home, platform, env, exists } = deps;
920
+ if (shell === "fish") {
921
+ const configHome = env["XDG_CONFIG_HOME"] || path.join(home, ".config");
922
+ return {
923
+ path: path.join(configHome, "fish", "completions", "skydive.fish"),
924
+ mode: "file"
925
+ };
926
+ }
927
+ if (shell === "zsh") {
928
+ const zdotdir = env["ZDOTDIR"] || home;
929
+ return {
930
+ path: path.join(zdotdir, ".zshrc"),
931
+ mode: "block"
932
+ };
933
+ }
934
+ const rc = path.join(home, ".bashrc");
935
+ const profile = path.join(home, ".bash_profile");
936
+ const preferred = platform === "darwin" ? profile : rc;
937
+ const alternate = platform === "darwin" ? rc : profile;
938
+ if (!exists(preferred) && exists(alternate)) return {
939
+ path: alternate,
940
+ mode: "block"
941
+ };
942
+ return {
943
+ path: preferred,
944
+ mode: "block"
945
+ };
946
+ }
947
+ /**
948
+ * The startup file's contents with our block added or refreshed. Idempotent:
949
+ * a second install rewrites the block in place rather than appending a
950
+ * duplicate, which is also how an upgraded CLI ships a newer script.
951
+ */
952
+ function spliceCompletionBlock(existing, script, commandName = "skydive") {
953
+ const start = existing.indexOf(blockStart(commandName));
954
+ const endMarker = blockEnd(commandName);
955
+ const end = existing.indexOf(endMarker);
956
+ if (start !== -1 && end > start) {
957
+ const before = existing.slice(0, start);
958
+ const after = existing.slice(end + endMarker.length).replace(/^\n/, "");
959
+ return `${before}${script.trimEnd()}\n${after}`;
960
+ }
961
+ return `${existing}${existing === "" || existing.endsWith("\n\n") ? "" : "\n"}\n${script}`;
962
+ }
963
+ function installCompletionScript(shell, deps = defaultInstallEnv()) {
964
+ const target = completionTarget(shell, deps);
965
+ const script = renderCompletionScript(shell);
966
+ const existing = deps.exists(target.path) ? fs.readFileSync(target.path, "utf8") : "";
967
+ const contents = target.mode === "file" ? script : spliceCompletionBlock(existing, script);
968
+ fs.mkdirSync(path.dirname(target.path), { recursive: true });
969
+ fs.writeFileSync(target.path, contents, "utf8");
970
+ return {
971
+ shell,
972
+ path: target.path,
973
+ updated: existing.includes(blockStart("skydive"))
974
+ };
975
+ }
976
+ /** What the user has to do before completions work in the shell they're in. */
977
+ function activationHint(result) {
978
+ return result.shell === "fish" ? "Open a new fish shell to pick them up (fish autoloads completions)." : `Open a new shell, or run: source ${result.path}`;
979
+ }
980
+ const installCommand$1 = {
981
+ command: "install [shell]",
982
+ describe: "Install completions into your shell's startup file",
983
+ builder: (y) => y.positional("shell", {
984
+ type: "string",
985
+ describe: "Shell to install for (default: $SHELL)"
986
+ }).example("skydive completion install", "Install for the current shell").example("skydive completion install fish", "Install for a named shell"),
987
+ handler: async (argv) => {
988
+ const shell = argv.shell ? SUPPORTED_SHELLS.find((candidate) => candidate === argv.shell) : detectShell();
989
+ if (!shell) throw new Error(argv.shell ? `No completions for ${argv.shell}. Supported: ${SUPPORTED_SHELLS.join(", ")}.` : `Could not tell which shell to install for from $SHELL. Name one: ${SUPPORTED_SHELLS.join(", ")}.`);
990
+ let result;
991
+ try {
992
+ result = installCompletionScript(shell);
993
+ } catch (error) {
994
+ throw new Error(`Could not write ${shell} completions: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
995
+ }
996
+ if (argv.json) {
997
+ output(argv, result);
998
+ return;
999
+ }
1000
+ console.log(`${result.updated ? "Updated" : "Installed"} ${result.shell} completions in ${result.path}`);
1001
+ if (!argv.quiet) console.log(activationHint(result));
1002
+ }
1003
+ };
1004
+ const completionCommand = {
1005
+ command: "completion [shell]",
1006
+ describe: "Print the shell completion script for bash, zsh, or fish",
1007
+ builder: (y) => y.positional("shell", {
1008
+ type: "string",
1009
+ choices: SUPPORTED_SHELLS,
1010
+ describe: "Shell to generate completions for"
1011
+ }).command(installCommand$1).example("skydive completion install", "Set up completions for your shell").example("eval \"$(skydive completion zsh)\"", "Enable completions for this shell only"),
1012
+ handler: async (argv) => {
1013
+ if (!argv.shell) throw new Error(`Specify a shell (${SUPPORTED_SHELLS.join(", ")}), or run \`skydive completion install\` to set up $SHELL.`);
1014
+ process.stdout.write(renderCompletionScript(argv.shell));
1015
+ }
1016
+ };
1017
+
716
1018
  //#endregion
717
1019
  //#region src/commands/session.ts
718
1020
  /**
@@ -1198,7 +1500,7 @@ const importCommand = {
1198
1500
  process.exit(1);
1199
1501
  }
1200
1502
  }
1201
- const { runChat } = await import("./boot-DpgN_3SH.mjs");
1503
+ const { runChat } = await import("./boot-Buk9Rq0h.mjs");
1202
1504
  await runChat({
1203
1505
  appUrl,
1204
1506
  sessionToken: session.value.sessionToken,
@@ -1514,7 +1816,7 @@ const chatCommand = {
1514
1816
  printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
1515
1817
  process.exit(1);
1516
1818
  }
1517
- const { runChat } = await import("./boot-DpgN_3SH.mjs");
1819
+ const { runChat } = await import("./boot-Buk9Rq0h.mjs");
1518
1820
  await runChat({
1519
1821
  appUrl,
1520
1822
  sessionToken: session.value.sessionToken,
@@ -1822,7 +2124,7 @@ const switchCommand = {
1822
2124
  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.");
1823
2125
  process.exit(1);
1824
2126
  }
1825
- const { runWorkspacePicker } = await import("./boot-DpgN_3SH.mjs");
2127
+ const { runWorkspacePicker } = await import("./boot-Buk9Rq0h.mjs");
1826
2128
  await runWorkspacePicker(session);
1827
2129
  return;
1828
2130
  }
@@ -2882,7 +3184,7 @@ const updateCommand = {
2882
3184
  //#endregion
2883
3185
  //#region src/cli.ts
2884
3186
  function createCli(argv) {
2885
- return yargs(argv).scriptName("skydive").usage("$0 <command> [options]").parserConfiguration({ "populate--": true }).example("skydive auth login", "Store your API key").example("skydive chat", "Open the interactive chat TUI (prod)").example("skydive chat --api-url http://localhost:4500", "Chat against a local dev API").example("skydive agents list", "List your agents").example("skydive keys create \"my-key\"", "Create an API key").example("skydive secrets set OPENAI_API_KEY --agent-id <id>", "Set a secret (value from stdin)").example("skydive workspace list", "List workspaces on your account").example("skydive workspace switch acme-team", "Switch the workspace all `skydive` commands act on").example("skydive portal open --agent grace", "Open the portal to this machine for an agent, headless (no TUI)").option("json", {
3187
+ return yargs(argv).scriptName("skydive").usage("$0 <command> [options]").parserConfiguration({ "populate--": true }).example("skydive auth login", "Store your API key").example("skydive chat", "Open the interactive chat TUI (prod)").example("skydive chat --api-url http://localhost:4500", "Chat against a local dev API").example("skydive agents list", "List your agents").example("skydive completion install", "Set up TAB completion for your shell").example("skydive keys create \"my-key\"", "Create an API key").example("skydive secrets set OPENAI_API_KEY --agent-id <id>", "Set a secret (value from stdin)").example("skydive workspace list", "List workspaces on your account").example("skydive workspace switch acme-team", "Switch the workspace all `skydive` commands act on").example("skydive portal open --agent grace", "Open the portal to this machine for an agent, headless (no TUI)").option("json", {
2886
3188
  type: "boolean",
2887
3189
  default: false,
2888
3190
  global: true,
@@ -2896,7 +3198,7 @@ function createCli(argv) {
2896
3198
  type: "string",
2897
3199
  global: true,
2898
3200
  describe: "Override API base URL"
2899
- }).command(authCommand).command(chatCommand).command(messagesCommand).command(conversationsCommand).command(agentsCommand).command(importCommand).command(keysCommand).command(secretsCommand).command(workspaceCommand).command(portalCommand).command(sandboxCommand).command(updateCommand).demandCommand(1, "Specify a command. Run --help for usage.").strict().wrap(null).version(version).alias("v", "version").alias("h", "help").help().fail((msg, err) => {
3201
+ }).command(authCommand).command(chatCommand).command(messagesCommand).command(conversationsCommand).command(agentsCommand).command(importCommand).command(keysCommand).command(secretsCommand).command(workspaceCommand).command(portalCommand).command(sandboxCommand).command(updateCommand).command(completionCommand).demandCommand(1, "Specify a command. Run --help for usage.").strict().wrap(null).version(version).alias("v", "version").alias("h", "help").help().fail((msg, err) => {
2900
3202
  printError(err ? err instanceof Error ? err.message : String(err) : msg ?? "Unknown error");
2901
3203
  process.exit(1);
2902
3204
  });
@@ -3255,11 +3557,14 @@ if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
3255
3557
  runPortalDaemon(process.argv);
3256
3558
  } else runCli();
3257
3559
  function runCli() {
3258
- maybePrintWhatsNew();
3259
- setupUpdateCheck(hideBin(process.argv));
3260
- const resolved = resolveArgv(hideBin(process.argv));
3560
+ const completionProbe = isCompletionProbe(process.argv);
3561
+ if (!completionProbe) {
3562
+ maybePrintWhatsNew();
3563
+ setupUpdateCheck(hideBin(process.argv));
3564
+ }
3565
+ const resolved = resolveArgv(normalizeProbeArgv(hideBin(process.argv)));
3261
3566
  const raw = hideBin(process.argv);
3262
- if ((raw.includes("--help") || raw.includes("-h")) && !raw.some((a) => !a.startsWith("-")) && !raw.includes("--json") && !raw.includes("--quiet")) process.stdout.write(brandHelpArt());
3567
+ if (!completionProbe && (raw.includes("--help") || raw.includes("-h")) && !raw.some((a) => !a.startsWith("-")) && !raw.includes("--json") && !raw.includes("--quiet")) process.stdout.write(brandHelpArt());
3263
3568
  createCli(resolved).parse();
3264
3569
  }
3265
3570
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as setActiveWorkspace, S as listWorkspaces, a as WORDMARK, b as getActiveWorkspaceId, c as applyTheme, d as noColorRequested, f as theme, g as themeVersion, h as themeModeFromColorFgBg, i as MARK_CELLS, l as findTheme, m as themeMode, n as buildCrashReport, p as themeForMode, r as writeCrashReport, s as DEFAULT_THEME_ID, t as installCrashHandler, u as monoTheme, v as themesForMode } from "./install-ZNL9Ss_c.mjs";
2
+ import { C as setActiveWorkspace, S as listWorkspaces, a as WORDMARK, b as getActiveWorkspaceId, c as applyTheme, d as noColorRequested, f as theme, g as themeVersion, h as themeModeFromColorFgBg, i as MARK_CELLS, l as findTheme, m as themeMode, n as buildCrashReport, p as themeForMode, r as writeCrashReport, s as DEFAULT_THEME_ID, t as installCrashHandler, u as monoTheme, v as themesForMode } from "./install-DgwIUN1J.mjs";
3
3
  import { L as saveTheme, P as resolveWebUrl, T as getSavedTheme, 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, w as getReviewStateDir, x as getConfigPath, y as DEFAULT_APP_URL } from "./print-BUbxOvnm.mjs";
4
4
  import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-CCyln7vx.mjs";
5
5
  import { t as PortalClient } from "./client-O5KfzIaB.mjs";
@@ -11,9 +11,9 @@ import { homedir, platform, release, tmpdir } from "node:os";
11
11
  import path, { basename, extname, isAbsolute, join, win32 } from "node:path";
12
12
  import { z } from "zod";
13
13
  import open from "open";
14
+ import { constants } from "node:fs";
14
15
  import { execFile, spawn } from "node:child_process";
15
16
  import { createHash, randomUUID } from "node:crypto";
16
- import { constants } from "node:fs";
17
17
  import { connect, createConnection } from "node:net";
18
18
  import { access, appendFile, mkdir, mkdtemp, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
19
19
  import { MarkdownRenderable, RenderableEvents, StyledText, SyntaxStyle, createCliRenderer, decodePasteBytes, detectLinks, fg, link } from "@opentui/core";
@@ -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.2.0-beta.630";
11
+ var version$1 = "0.2.0-beta.684";
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.2.0-beta.630",
3
+ "version": "0.2.0-beta.684",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",