skydive-cli 0.5.0-beta.18 → 0.5.0-beta.19

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 { A as version, D as listWorkspaces, E as getSessionIdentity, O as setActiveWorkspace, S as themes, T as getActiveWorkspaceId, a as installCrashHandler, k as name, t as maybeStartProfiling, u as brandHelpArt, w as ensureActiveOrganization } from "./profiler-Cdb37vOS.mjs";
2
+ import { A as version, D as listWorkspaces, E as getSessionIdentity, O as setActiveWorkspace, S as themes, T as getActiveWorkspaceId, a as installCrashHandler, k as name, t as maybeStartProfiling, u as brandHelpArt, w as ensureActiveOrganization } from "./profiler-DlxtXXGp.mjs";
3
3
  import { A as getStoredApiKeyId, B as saveConfig, C as getDefaultAgent, E as getPromptHistoryPath, F as resolveChatAuth, I as resolveConfig, L as resolveManagementAuth, M as getUpdateCheckDisabled, P as resolveAppUrl, R as resolveSession, S as getConfigPath, T as getPreference, U as setLastSeenVersion, V as saveSession, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getStoredApiKeyWorkspaceName, k as getShareMachineDefault, v as DEFAULT_API_URL, w as getLastSeenVersion, x as deleteConfig } from "./print-CPRgbo2N.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-CLrHVkxh.mjs";
7
7
  import "./billing-blocked-2wju4gC_.mjs";
8
8
  import { r as resolveMachineIdentity } from "./client-DbqRBquD.mjs";
9
- import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-Bh5-Zcmm.mjs";
9
+ import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-DWw9AjB4.mjs";
10
10
  import { i as grantPortalAccess, n as fetchPortalDevices, o as registerPortalDevice, r as findThisDevice, s as revokePortalAccess } from "./api-DG5W6iwx.mjs";
11
11
  import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
12
12
  import { hideBin } from "yargs/helpers";
@@ -1517,7 +1517,7 @@ const importCommand = {
1517
1517
  process.exit(1);
1518
1518
  }
1519
1519
  }
1520
- const { runChat } = await import("./boot-B5s4OFD1.mjs");
1520
+ const { runChat } = await import("./boot-C831RDoa.mjs");
1521
1521
  await runChat({
1522
1522
  appUrl,
1523
1523
  sessionToken: session.value.sessionToken,
@@ -1930,7 +1930,7 @@ const chatCommand = {
1930
1930
  sessionToken: auth.value.token,
1931
1931
  agentSelector: argv.agent ?? null
1932
1932
  });
1933
- const { runChat } = await import("./boot-B5s4OFD1.mjs");
1933
+ const { runChat } = await import("./boot-C831RDoa.mjs");
1934
1934
  await runChat({
1935
1935
  appUrl: auth.value.appUrl,
1936
1936
  sessionToken: auth.value.token,
@@ -2290,7 +2290,7 @@ const switchCommand = {
2290
2290
  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.");
2291
2291
  process.exit(1);
2292
2292
  }
2293
- const { runWorkspacePicker } = await import("./boot-B5s4OFD1.mjs");
2293
+ const { runWorkspacePicker } = await import("./boot-C831RDoa.mjs");
2294
2294
  await runWorkspacePicker(session);
2295
2295
  return;
2296
2296
  }
@@ -2369,7 +2369,7 @@ const openCommand = {
2369
2369
  const agent = argv.agent ? resolveAgent((await fetchPortalDevices(session)).agents, argv.agent) : null;
2370
2370
  const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
2371
2371
  const { machineName } = await resolveMachineIdentity(null);
2372
- const { PortalDaemonClient } = await import("./daemon-client-DohoNVOP.mjs");
2372
+ const { PortalDaemonClient } = await import("./daemon-client-CMsS0Ayk.mjs");
2373
2373
  let lastLine = "";
2374
2374
  let signalConnected;
2375
2375
  const connected = new Promise((resolve) => {
@@ -4215,7 +4215,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
4215
4215
  process.exit(0);
4216
4216
  }
4217
4217
  if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
4218
- const { runPortalDaemon } = await import("./daemon-ET09u2qs.mjs");
4218
+ const { runPortalDaemon } = await import("./daemon-BX8OBLBs.mjs");
4219
4219
  runPortalDaemon(process.argv);
4220
4220
  } else runCli();
4221
4221
  function runCli() {
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import { C as themesForMode, D as listWorkspaces, O as setActiveWorkspace, T as getActiveWorkspaceId, _ as theme, a as installCrashHandler, b as themeModeFromColorFgBg, c as MARK_CELLS, d as splashFitsWidth, f as DEFAULT_THEME_ID, g as noColorRequested, h as monoTheme, i as writeArtifact, l as WORDMARK, m as findTheme, n as profilingEnabled, o as buildCrashReport, p as applyTheme, r as record, s as writeCrashReport, v as themeForMode, x as themeVersion, y as themeMode } from "./profiler-Cdb37vOS.mjs";
2
+ import { C as themesForMode, D as listWorkspaces, O as setActiveWorkspace, T as getActiveWorkspaceId, _ as theme, a as installCrashHandler, b as themeModeFromColorFgBg, c as MARK_CELLS, d as splashFitsWidth, f as DEFAULT_THEME_ID, g as noColorRequested, h as monoTheme, i as writeArtifact, l as WORDMARK, m as findTheme, n as profilingEnabled, o as buildCrashReport, p as applyTheme, r as record, s as writeCrashReport, v as themeForMode, x as themeVersion, y as themeMode } from "./profiler-DlxtXXGp.mjs";
3
3
  import { D as getReviewStateDir, H as saveTheme, N as recordDefaultAgent, O as getSavedTheme, 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, z as resolveWebUrl } from "./print-CPRgbo2N.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-CLrHVkxh.mjs";
6
6
  import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-2wju4gC_.mjs";
7
7
  import { t as PortalClient } from "./client-DbqRBquD.mjs";
8
- import "./daemon-Bh5-Zcmm.mjs";
8
+ import "./daemon-DWw9AjB4.mjs";
9
9
  import "./api-DG5W6iwx.mjs";
10
10
  import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
11
- import { t as PortalDaemonClient } from "./daemon-client-D20UhJJa.mjs";
11
+ import { t as PortalDaemonClient } from "./daemon-client-C_lgQr4E.mjs";
12
12
  import { t as runRawPtyPassthrough } from "./raw-pty-DY4KelZW.mjs";
13
13
  import * as os$1 from "node:os";
14
14
  import { homedir, platform, release, tmpdir } from "node:os";
@@ -2597,15 +2597,80 @@ function useDebouncedValue(value, delayMs) {
2597
2597
  }
2598
2598
 
2599
2599
  //#endregion
2600
- //#region src/chat/tui/screens/conversation-picker.tsx
2601
- const SEARCH_DEBOUNCE_MS = 250;
2602
- const SEARCH_QUERY_MAX_LENGTH = 200;
2600
+ //#region src/chat/tui/screens/conversation-channel.ts
2601
+ function isNewConversation(c) {
2602
+ return "kind" in c && c.kind === "new";
2603
+ }
2604
+ /**
2605
+ * The channels a human can start a conversation on. Enumerated, not derived,
2606
+ * to keep `@createinc/anyone-db` out of the CLI build (see rest.ts). A newly
2607
+ * added human channel needs adding here too. The picker filters its default
2608
+ * view to these; `isAgentRunConversation` is their complement.
2609
+ */
2603
2610
  const humanChannels = [
2604
2611
  "web",
2605
2612
  "slack",
2606
2613
  "email",
2607
2614
  "imessage"
2608
2615
  ];
2616
+ /**
2617
+ * Whether a conversation is an agent run — a thread the agent opened for
2618
+ * itself (cron firing, inbound webhook wake) rather than one a person
2619
+ * started. These have no human participant row, so per-user archive can
2620
+ * never apply to them (there is nothing to mark); delete is their only
2621
+ * cleanup affordance, and the UI should not offer archive on them.
2622
+ *
2623
+ * Best-effort: an a2a/subagent thread carries a `web` channel binding, so it
2624
+ * reads as `'web'` here and is NOT detected. Archive on one of those still
2625
+ * fails server-side with the existing error notice — this predicate only
2626
+ * removes the affordance where the client can know it's dead.
2627
+ */
2628
+ function isAgentRunConversation(c) {
2629
+ if (isNewConversation(c)) return false;
2630
+ if (c.channel === null) return false;
2631
+ const { channel } = c;
2632
+ return !humanChannels.some((human) => human === channel);
2633
+ }
2634
+ /**
2635
+ * The channel a conversation belongs to when it isn't the web channel, else
2636
+ * null. A brand-new conversation is always web, and the list route reports the
2637
+ * web channel as either `'web'` or (legacy) null — both mean "post from here".
2638
+ * Anything else (slack, email, imessage, webhook, cron) is owned by that
2639
+ * channel: the message has to go through it, so the TUI can't send here.
2640
+ * Mirrors the web app's `channel !== null && channel !== 'web'` gate.
2641
+ */
2642
+ function nonWebChannelLabel(c) {
2643
+ if (isNewConversation(c)) return null;
2644
+ if (c.channel === null || c.channel === "web") return null;
2645
+ return c.channelLabel ?? c.channel;
2646
+ }
2647
+ /**
2648
+ * The list-row shape for a conversation the TUI just forked, so the chat
2649
+ * screen can reopen on the copy without waiting for a list refetch. A fork
2650
+ * carries none of the source's channel binding — that's what makes it
2651
+ * sendable from here — so it is always a web conversation.
2652
+ */
2653
+ function forkedConversationRef({ agent, forked }) {
2654
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2655
+ return {
2656
+ id: forked.id,
2657
+ title: forked.title,
2658
+ createdAt: now,
2659
+ updatedAt: now,
2660
+ preview: null,
2661
+ channel: "web",
2662
+ channelLabel: null,
2663
+ agent: {
2664
+ id: agent.id,
2665
+ name: agent.name
2666
+ }
2667
+ };
2668
+ }
2669
+
2670
+ //#endregion
2671
+ //#region src/chat/tui/screens/conversation-picker.tsx
2672
+ const SEARCH_DEBOUNCE_MS = 250;
2673
+ const SEARCH_QUERY_MAX_LENGTH = 200;
2609
2674
  function ConversationPickerScreen({ agent }) {
2610
2675
  const rest = useStore((s) => s.rest);
2611
2676
  const goTo = useStore((s) => s.goTo);
@@ -2799,6 +2864,7 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
2799
2864
  const clamped = Math.min(highlight, Math.max(0, rows.length - 1));
2800
2865
  const highlightRow = rows[clamped];
2801
2866
  const highlightArchived = highlightRow?.kind === "conv" && isArchived(highlightRow.hit.item);
2867
+ const highlightAgentRun = highlightRow?.kind === "conv" && isAgentRunConversation(highlightRow.hit.item);
2802
2868
  const confirmConv = confirmId !== null ? list.find((c) => c.id === confirmId) : void 0;
2803
2869
  const searchState = isSearching ? search?.state : void 0;
2804
2870
  const countSegment = isSearching && (searchState?.kind === "loading" || search === null) ? "searching…" : isSearching && searchState?.kind === "error" ? `search failed: ${searchState.message}` : `${hits.length}/${list.length}${complete || isSearching ? "" : " (loading…)"}`;
@@ -2812,7 +2878,7 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
2812
2878
  fg: theme.dim,
2813
2879
  text: fitHintLine([
2814
2880
  countSegment,
2815
- `ctrl+a ${highlightArchived ? "unarchive" : "archive"}`,
2881
+ ...highlightAgentRun ? [] : [`ctrl+a ${highlightArchived ? "unarchive" : "archive"}`],
2816
2882
  "ctrl+d delete",
2817
2883
  `tab ${showAutomated ? "hide" : "show"} agent runs`,
2818
2884
  `shift+tab ${showArchived ? "hide" : "show"} archived`,
@@ -2906,6 +2972,10 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
2906
2972
  } else if (key.name === "a" && key.ctrl) {
2907
2973
  const row = rows[clamped];
2908
2974
  if (row?.kind === "conv") {
2975
+ if (isAgentRunConversation(row.hit.item)) {
2976
+ setError("agent runs can't be archived — ctrl+d deletes");
2977
+ return;
2978
+ }
2909
2979
  setError(null);
2910
2980
  toggleArchived(row.hit.item);
2911
2981
  }
@@ -10679,47 +10749,6 @@ async function runPtySession(opts) {
10679
10749
  }
10680
10750
  }
10681
10751
 
10682
- //#endregion
10683
- //#region src/chat/tui/screens/conversation-channel.ts
10684
- function isNewConversation(c) {
10685
- return "kind" in c && c.kind === "new";
10686
- }
10687
- /**
10688
- * The channel a conversation belongs to when it isn't the web channel, else
10689
- * null. A brand-new conversation is always web, and the list route reports the
10690
- * web channel as either `'web'` or (legacy) null — both mean "post from here".
10691
- * Anything else (slack, email, imessage, webhook, cron) is owned by that
10692
- * channel: the message has to go through it, so the TUI can't send here.
10693
- * Mirrors the web app's `channel !== null && channel !== 'web'` gate.
10694
- */
10695
- function nonWebChannelLabel(c) {
10696
- if (isNewConversation(c)) return null;
10697
- if (c.channel === null || c.channel === "web") return null;
10698
- return c.channelLabel ?? c.channel;
10699
- }
10700
- /**
10701
- * The list-row shape for a conversation the TUI just forked, so the chat
10702
- * screen can reopen on the copy without waiting for a list refetch. A fork
10703
- * carries none of the source's channel binding — that's what makes it
10704
- * sendable from here — so it is always a web conversation.
10705
- */
10706
- function forkedConversationRef({ agent, forked }) {
10707
- const now = (/* @__PURE__ */ new Date()).toISOString();
10708
- return {
10709
- id: forked.id,
10710
- title: forked.title,
10711
- createdAt: now,
10712
- updatedAt: now,
10713
- preview: null,
10714
- channel: "web",
10715
- channelLabel: null,
10716
- agent: {
10717
- id: agent.id,
10718
- name: agent.name
10719
- }
10720
- };
10721
- }
10722
-
10723
10752
  //#endregion
10724
10753
  //#region src/chat/tui/screens/chat.tsx
10725
10754
  /**
@@ -10810,6 +10839,7 @@ function ChatScreen({ agent, conversation }) {
10810
10839
  const initialConversationId = isNewConversation(conversation) ? null : conversation.id;
10811
10840
  const agentHost = useAgentHost();
10812
10841
  const nonWebChannel = nonWebChannelLabel(conversation);
10842
+ const agentRunConversation = isAgentRunConversation(conversation);
10813
10843
  const [conversationId, setConversationId] = useState(initialConversationId);
10814
10844
  const { compacting, compactConversation, onCompactionEvent } = useCompaction({
10815
10845
  rest,
@@ -11821,6 +11851,10 @@ function ChatScreen({ agent, conversation }) {
11821
11851
  ]);
11822
11852
  const archiveConversation = useCallback(() => {
11823
11853
  if (grantPrompt || credPrompt) return;
11854
+ if (agentRunConversation) {
11855
+ useStore.getState().showToast({ message: "agent runs can't be archived — ctrl+d in the picker deletes" });
11856
+ return;
11857
+ }
11824
11858
  if (runRef.current.kind !== "idle") {
11825
11859
  useStore.getState().showToast({ message: "finish or cancel the run first (ctrl+c)" });
11826
11860
  return;
@@ -11849,6 +11883,7 @@ function ChatScreen({ agent, conversation }) {
11849
11883
  }, [
11850
11884
  grantPrompt,
11851
11885
  credPrompt,
11886
+ agentRunConversation,
11852
11887
  conversationId,
11853
11888
  rest,
11854
11889
  goTo,
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import "./client-DbqRBquD.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-Bh5-Zcmm.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-DWw9AjB4.mjs";
4
4
  import "./api-DG5W6iwx.mjs";
5
5
 
6
6
  export { runPortalDaemon };
@@ -20,7 +20,7 @@ import { access, appendFile, mkdir, readFile, unlink, writeFile } from "node:fs/
20
20
  * the commit time of the built tree is one monotonic clock they share.
21
21
  */
22
22
  function portalDaemonBuild() {
23
- return "1786643266";
23
+ return "1786649704";
24
24
  }
25
25
  /**
26
26
  * Whether a client carrying `mine` should replace a running daemon carrying
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import "./client-DbqRBquD.mjs";
3
+ import "./daemon-DWw9AjB4.mjs";
4
+ import "./api-DG5W6iwx.mjs";
5
+ import { t as PortalDaemonClient } from "./daemon-client-C_lgQr4E.mjs";
6
+
7
+ export { PortalDaemonClient };
@@ -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-Bh5-Zcmm.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-DWw9AjB4.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { connect } from "node:net";
5
5
 
@@ -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.18";
11
+ var version$1 = "0.5.0-beta.19";
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.18",
3
+ "version": "0.5.0-beta.19",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./client-DbqRBquD.mjs";
3
- import "./daemon-Bh5-Zcmm.mjs";
4
- import "./api-DG5W6iwx.mjs";
5
- import { t as PortalDaemonClient } from "./daemon-client-D20UhJJa.mjs";
6
-
7
- export { PortalDaemonClient };