skydive-cli 0.6.0-beta.8 → 0.6.0-beta.81

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { c as version$1 } from "./rest-Dspsplnl.mjs";
3
- import { w as getConfigPath } from "./print-BRfIIT7U.mjs";
2
+ import { c as version$1 } from "./rest-BkyLLyCo.mjs";
3
+ import { D as getConfigPath } from "./print-BoYBDMOF.mjs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { err, ok } from "neverthrow";
@@ -1547,6 +1547,51 @@ function formatMb(bytes) {
1547
1547
  return `${(bytes / MB).toFixed(1)} MB`;
1548
1548
  }
1549
1549
 
1550
+ //#endregion
1551
+ //#region src/chat/tui/autowrap.ts
1552
+ /**
1553
+ * Why the TUI turns the terminal's autowrap off for its lifetime.
1554
+ *
1555
+ * OpenTUI's incremental cell-diff emitter positions every run with an
1556
+ * absolute cursor move — it never relies on the terminal to advance the
1557
+ * cursor — but it leaves the terminal's autowrap (DECAWM) enabled. When a
1558
+ * run reaches the last column, the host terminal wraps its cursor to column
1559
+ * 1 of the next row and paints the run's tail there, into cells owned by a
1560
+ * different element. The diff buffer then records the *intended* cells, so
1561
+ * those stray bytes are never repainted and unrelated text smears together
1562
+ * until a full repaint (a resize). Filed upstream with a repro and root
1563
+ * cause: https://github.com/anomalyco/opentui/issues/1187 — unfixed there,
1564
+ * the consumer-side fix (verified in numux#115) is to disable DECAWM while
1565
+ * the renderer runs. Pane content still wraps, inside OpenTUI's own grid.
1566
+ */
1567
+ const AUTOWRAP_OFF = "\x1B[?7l";
1568
+ const AUTOWRAP_ON = "\x1B[?7h";
1569
+ /** Escape hatch: if any surface turns out to depend on host autowrap. */
1570
+ const keepAutowrap = () => Boolean(process.env["SKYDIVE_TUI_AUTOWRAP"]);
1571
+ let disabledBy = false;
1572
+ /**
1573
+ * Disable host autowrap so the diff emitter's runs can never wrap onto the
1574
+ * next row. No-op when stdout is not a terminal (piped output, tests) and
1575
+ * under `SKYDIVE_TUI_AUTOWRAP`.
1576
+ */
1577
+ function disableTerminalAutowrap(stdout = process.stdout) {
1578
+ if (!stdout.isTTY || keepAutowrap() || disabledBy) return;
1579
+ disabledBy = true;
1580
+ stdout.write(AUTOWRAP_OFF);
1581
+ }
1582
+ /**
1583
+ * Restore host autowrap. The terminal mode is a property of the host, so
1584
+ * every teardown path must run this even when the renderer cannot finish
1585
+ * its own teardown: the renderer's `onDestroy` hook covers renderer-driven
1586
+ * exits, and the forced-fallback reset in `hard-exit.ts` carries the
1587
+ * restore for a teardown that never got there. Idempotent.
1588
+ */
1589
+ function restoreTerminalAutowrap(stdout = process.stdout) {
1590
+ if (!disabledBy) return;
1591
+ disabledBy = false;
1592
+ stdout.write(AUTOWRAP_ON);
1593
+ }
1594
+
1550
1595
  //#endregion
1551
1596
  //#region src/crash/install.ts
1552
1597
  let installed = false;
@@ -1566,6 +1611,7 @@ function installCrashHandler(opts = {}) {
1566
1611
  if (installed) return;
1567
1612
  installed = true;
1568
1613
  process.on("uncaughtException", (error) => {
1614
+ restoreTerminalAutowrap();
1569
1615
  const memory = safeMemory();
1570
1616
  printFatalNotice(writeCrashReport(buildCrashReport({
1571
1617
  reason: "uncaughtException",
@@ -1594,4 +1640,4 @@ function printFatalNotice(file, memory) {
1594
1640
  }
1595
1641
 
1596
1642
  //#endregion
1597
- export { installAgentAlias as A, resolveWorkspaceId as B, themeVersion as C, machineOsFromPlatform as D, buildImportSeedPrompt as E, detectShell as F, ensureActiveOrganization as I, getActiveWorkspaceId as L, takenAliasNames as M, SUPPORTED_SHELLS as N, aliasActivationHint as O, defaultInstallEnv as P, getSessionIdentity as R, themeModeFromColorFgBg as S, themesForMode as T, setActiveWorkspace as V, monoTheme as _, WORDMARK as a, themeForMode as b, getAutomaticLogsDir as c, profilingEnabled as d, record as f, findTheme as g, applyTheme as h, MARK_CELLS as i, slugifyAliasName as j, dedupeAliasName as k, maybeStartProfiling as l, DEFAULT_THEME_ID as m, buildCrashReport as n, brandHelpArt as o, writeArtifact as p, writeCrashReport as r, splashFitsWidth as s, installCrashHandler as t, profileDir as u, noColorRequested as v, themes as w, themeMode as x, theme as y, listWorkspaces as z };
1643
+ export { aliasActivationHint as A, getSessionIdentity as B, themeMode as C, themesForMode as D, themes as E, SUPPORTED_SHELLS as F, resolveWorkspaceId as H, defaultInstallEnv as I, detectShell as L, installAgentAlias as M, slugifyAliasName as N, buildImportSeedPrompt as O, takenAliasNames as P, ensureActiveOrganization as R, themeForMode as S, themeVersion as T, setActiveWorkspace as U, listWorkspaces as V, applyTheme as _, writeCrashReport as a, noColorRequested as b, brandHelpArt as c, maybeStartProfiling as d, profileDir as f, DEFAULT_THEME_ID as g, writeArtifact as h, buildCrashReport as i, dedupeAliasName as j, machineOsFromPlatform as k, splashFitsWidth as l, record as m, disableTerminalAutowrap as n, MARK_CELLS as o, profilingEnabled as p, restoreTerminalAutowrap as r, WORDMARK as s, installCrashHandler as t, getAutomaticLogsDir as u, findTheme as v, themeModeFromColorFgBg as w, theme as x, monoTheme as y, getActiveWorkspaceId as z };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, i as sendErrorMessage, o as isRecord, t as createRestClient } from "./rest-Dspsplnl.mjs";
2
+ import { a as errorMessage, i as sendErrorMessage, o as isRecord, t as createRestClient } from "./rest-BkyLLyCo.mjs";
3
3
  import { t as HttpError } from "./http-error-BF2NZZE3.mjs";
4
4
  import { i as billingBlockedOutcomeFromSendResponse, n as BillingBlockedError } from "./billing-blocked-D3l5kJlX.mjs";
5
5
  import path from "node:path";
@@ -512,18 +512,18 @@ function readQuestionEntries(raw) {
512
512
  }];
513
513
  });
514
514
  }
515
- /**
516
- * The `platform ask` form. The web renders it as an interactive picker; here
517
- * it maps onto an answer_question button so ctrl+r (and letter shortcuts)
518
- * open an in-TUI picker. The composed answer is sent as a normal user
519
- * message — same non-blocking model as the web card. Without this the spec
520
- * is not a Card, parses to null, and the question is silently dropped.
521
- */
522
515
  /** Compose the user-message body the web card also sends. */
523
516
  function composeQuestionAnswer(questions, answers) {
524
517
  if (questions.length === 1) return (answers[0] ?? []).join(", ");
525
518
  return questions.map((q, i) => `${q.question} → ${(answers[i] ?? []).join(", ")}`).join("\n");
526
519
  }
520
+ /** Build the typed durable payload that settles this exact question card. */
521
+ function composeQuestionAnswerEntries(questions, answers) {
522
+ return questions.map((question, index) => ({
523
+ question: question.question,
524
+ answer: (answers[index] ?? []).join(", ")
525
+ }));
526
+ }
527
527
  function parseQuestionCard(rootEl) {
528
528
  const props = isRecord(rootEl.props) ? rootEl.props : {};
529
529
  const cardId = optionalString(props.cardId);
@@ -691,6 +691,66 @@ function reconcileMaskedInput(previousValue, displayed) {
691
691
  while (kept < displayed.length && kept < previousValue.length && displayed[kept] === MASK_CHAR) kept++;
692
692
  return previousValue.slice(0, kept) + displayed.slice(kept);
693
693
  }
694
+ /**
695
+ * Whether a card is one an agent RUN is actively blocked on until the user
696
+ * decides here: a portal-share consent (`platform portal request`), a compute
697
+ * upgrade decision (`platform compute request`), or a connect/credential card
698
+ * the run is waiting to be fulfilled. The lone non-blocking actionable card is
699
+ * `answer_question` — a `platform ask` form, whose answer is a normal user
700
+ * message (the run keeps going regardless), so it must never shadow a decision
701
+ * the agent is stalled on.
702
+ */
703
+ function isBlockingCardAction(action) {
704
+ return action.kind !== "answer_question";
705
+ }
706
+ /**
707
+ * Narrow a set of actionable cards to the ones ctrl+r (and the card picker)
708
+ * should target, prioritizing blocking cards over `platform ask` forms. When
709
+ * both a blocking card and a stale `answer_question` are waiting, ctrl+r must
710
+ * approve the thing the agent is stalled on, not re-answer an earlier ask that
711
+ * can remain actionable when ignored or answered as plain composer text.
712
+ * Falls through to the
713
+ * ask forms only when they are the only actionable cards left. Preserves input
714
+ * order within a tier, so a single card and genuine multi-card cases behave
715
+ * exactly as before.
716
+ */
717
+ function prioritizeActionableCards(cards) {
718
+ const blocking = cards.filter((c) => c.card.button !== null && isBlockingCardAction(c.card.button.action));
719
+ return blocking.length > 0 ? blocking : [...cards];
720
+ }
721
+ /**
722
+ * The footer verb for a single card action. Derived from the action's own
723
+ * `kind`, not from `isBlockingCardAction` (which answers a different question —
724
+ * "is the run stalled on this" — and is right for prioritization but wrong as a
725
+ * label: it would read a portal-share or compute-approval card as "connect").
726
+ * Each blocking kind gets the verb that matches what the chord actually does:
727
+ * an OAuth/credential card connects, a portal-share card grants, a compute
728
+ * request is decided, a `platform ask` form is answered.
729
+ */
730
+ function verbForAction(action) {
731
+ switch (action.kind) {
732
+ case "open_oauth":
733
+ case "open_external_oauth":
734
+ case "open_github_app":
735
+ case "submit_credential": return "connect";
736
+ case "grant_portal": return "grant";
737
+ case "decide_compute": return "decide";
738
+ case "answer_question": return "answer";
739
+ }
740
+ }
741
+ /**
742
+ * The footer verb for the actionable cards ctrl+r would target. Reflects the
743
+ * first card's actual action so a stale ask never mislabels the footer as
744
+ * "connect", and a portal/compute card reads as "grant"/"decide" rather than
745
+ * being lumped under "connect". Pass the ALREADY-prioritized set (see
746
+ * prioritizeActionableCards) so the label matches what ctrl+r acts on; null
747
+ * when nothing is waiting.
748
+ */
749
+ function actionableCardVerb(cards) {
750
+ const [first] = cards;
751
+ if (!first || first.card.button === null) return null;
752
+ return verbForAction(first.card.button.action);
753
+ }
694
754
 
695
755
  //#endregion
696
756
  //#region src/chat/connect-cards.ts
@@ -763,7 +823,7 @@ function summarizeConnectCard(card, appUrl) {
763
823
  }
764
824
  /**
765
825
  * Parse a `data-anyone-render-spec` stream chunk into a connect-card summary,
766
- * or null if the chunk isn't a connect card (other render specs — training,
826
+ * or null if the chunk isn't a connect card (other render specs — e.g.
767
827
  * deep-learn — parse to null, same as the TUI). A card that arrives already
768
828
  * settled (a compute request's decided re-emission) is an FYI, not an action,
769
829
  * so it stays out of the "[action needed]" stream too.
@@ -840,6 +900,7 @@ async function runPrint({ appUrl, sessionToken, workspaceId, prompt, agentSelect
840
900
  conversationId,
841
901
  content: prompt,
842
902
  attachmentIds: [],
903
+ questionAnswer: null,
843
904
  clientSurface: "cli"
844
905
  });
845
906
  } catch (err) {
@@ -1017,4 +1078,4 @@ async function readStdin() {
1017
1078
  }
1018
1079
 
1019
1080
  //#endregion
1020
- export { getSavedTheme as A, resolveSession as B, deleteConfig as C, getPreference as D, getLastSeenVersion as E, recordDefaultAgent as F, setLastSeenVersion as G, saveConfig as H, resolveAppUrl as I, resolveChatAuth as L, getStoredApiKeyId as M, getStoredApiKeyWorkspaceName as N, getPromptHistoryPath as O, getUpdateCheckDisabled as P, resolveConfig as R, PREFERENCES as S, getDefaultAgent as T, saveSession as U, resolveWebUrl as V, saveTheme as W, API_KEYS_URL as _, runPrint as a, DEFAULT_API_URL as b, cardActionErrorMessage as c, reconcileMaskedInput as d, resolveConnectUrl as f, specKeyFor as g, parseConnectCard as h, resolveAgent as i, getShareMachineDefault as j, getReviewStateDir as k, parseExternalOauthConnectParams as l, computeSettledLabel as m, messageGet as n, toPrintError as o, composeQuestionAnswer as p, readStdin as r, MASK_CHAR as s, collectRunText as t, parseOauthConnectParams as u, API_KEY_FAMILY_PREFIX as v, getConfigPath as w, DEFAULT_APP_URL as x, API_KEY_PREFIX as y, resolveManagementAuth as z };
1081
+ export { getPreference as A, resolveChatAuth as B, DEFAULT_API_URL as C, getConfigPath as D, deleteConfig as E, getStoredApiKeyId as F, saveConfig as G, resolveManagementAuth as H, getStoredApiKeyWorkspaceName as I, setLastSeenVersion as J, saveSession as K, getUpdateCheckDisabled as L, getReviewStateDir as M, getSavedTheme as N, getDefaultAgent as O, getShareMachineDefault as P, recordDefaultAgent as R, API_KEY_PREFIX as S, PREFERENCES as T, resolveSession as U, resolveConfig as V, resolveWebUrl as W, computeSettledLabel as _, runPrint as a, API_KEYS_URL as b, actionableCardVerb as c, parseOauthConnectParams as d, prioritizeActionableCards as f, composeQuestionAnswerEntries as g, composeQuestionAnswer as h, resolveAgent as i, getPromptHistoryPath as j, getLastSeenVersion as k, cardActionErrorMessage as l, resolveConnectUrl as m, messageGet as n, toPrintError as o, reconcileMaskedInput as p, saveTheme as q, readStdin as r, MASK_CHAR as s, collectRunText as t, parseExternalOauthConnectParams as u, parseConnectCard as v, DEFAULT_APP_URL as w, API_KEY_FAMILY_PREFIX as x, specKeyFor as y, resolveAppUrl as z };
@@ -14,7 +14,7 @@ import { n as printError } from "./output-C9mb3sUB.mjs";
14
14
  * the reply (and to --json).
15
15
  */
16
16
  async function connectMachineShare({ appUrl, sessionToken, timeoutHint }) {
17
- const { PortalClient } = await import("./client-WZ78eOZx.mjs");
17
+ const { PortalClient } = await import("./client-CyHxHvde.mjs");
18
18
  const { defaultTlsCertSource } = await import("./tls-cert-BpCaD5AT.mjs");
19
19
  let signalConnected;
20
20
  const connected = new Promise((resolve) => {
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./rest-Dspsplnl.mjs";
3
- import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-BRfIIT7U.mjs";
2
+ import "./rest-BkyLLyCo.mjs";
3
+ import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-BoYBDMOF.mjs";
4
4
  import "./billing-blocked-D3l5kJlX.mjs";
5
5
 
6
6
  export { messageGet, readStdin, resolveAgent, runPrint };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as SandboxStream } from "./client-Btq6bMzX.mjs";
2
+ import { t as SandboxStream } from "./client-Cxk3khQu.mjs";
3
3
 
4
4
  //#region src/chat/sandbox/raw-pty.ts
5
5
  /**
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import "./client-Cxk3khQu.mjs";
3
+ import { t as runRawPtyPassthrough } from "./raw-pty-B-WKaaE3.mjs";
4
+
5
+ export { runRawPtyPassthrough };
@@ -6,7 +6,7 @@ import { createParser } from "eventsource-parser";
6
6
 
7
7
  //#region package.json
8
8
  var name = "skydive-cli";
9
- var version = "0.6.0-beta.8";
9
+ var version = "0.6.0-beta.81";
10
10
 
11
11
  //#endregion
12
12
  //#region src/chat/util.ts
@@ -270,8 +270,11 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
270
270
  return conversation;
271
271
  },
272
272
  listModels: async () => {
273
- const { models } = await get("/api/v1/models", listModelsResponseSchema);
274
- return models;
273
+ const { models, trainingOptedOut } = await get("/api/v1/models", listModelsResponseSchema);
274
+ return {
275
+ models,
276
+ trainingOptedOut: trainingOptedOut ?? false
277
+ };
275
278
  },
276
279
  listModelEfforts: async () => {
277
280
  const { modelConfigOverrides } = await get("/api/v1/models/preferred", modelEffortPreferencesResponseSchema);
@@ -279,6 +282,14 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
279
282
  for (const [modelId, config] of Object.entries(modelConfigOverrides ?? {})) if (config.thinkingLevel) efforts[modelId] = config.thinkingLevel;
280
283
  return efforts;
281
284
  },
285
+ getBillingSummary: async () => {
286
+ const { result } = await get("/api/v1/trpc/v2.billing.getBillingOrgSummary", billingSummaryResponseSchema);
287
+ return result.data;
288
+ },
289
+ getFreeFloorState: async () => {
290
+ const { result } = await get("/api/v1/trpc/v2.billing.freeFloorState", freeFloorStateResponseSchema);
291
+ return result.data;
292
+ },
282
293
  setModelEffort: async ({ modelId, thinkingLevel }) => {
283
294
  await post("/api/v1/models/config", {
284
295
  modelId,
@@ -295,11 +306,17 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
295
306
  thinkingLevel: agent.thinkingLevel ?? null
296
307
  };
297
308
  },
298
- setConversationModel: async ({ conversationId, agentId, model, thinkingLevel }) => post(`/api/v1/conversations/${conversationId}/model`, {
299
- agentId,
300
- model,
301
- thinkingLevel
302
- }, conversationModelResponseSchema),
309
+ setConversationModel: async ({ conversationId, agentId, model, thinkingLevel }) => {
310
+ const settled = await post(`/api/v1/conversations/${conversationId}/model`, {
311
+ agentId,
312
+ model,
313
+ thinkingLevel
314
+ }, conversationModelResponseSchema);
315
+ return {
316
+ ...settled,
317
+ scope: settled.scope ?? null
318
+ };
319
+ },
303
320
  updateAgentEffort: async ({ agentId, thinkingLevel }) => {
304
321
  const { agent } = await patchAgent(agentId, { thinkingLevel });
305
322
  return { thinkingLevel: agent.thinkingLevel ?? null };
@@ -360,6 +377,10 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
360
377
  const { recap } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/recap`, recapResponseSchema);
361
378
  return recap?.text ?? null;
362
379
  },
380
+ getConversationUsage: async ({ conversationId }) => {
381
+ const { usage } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/usage`, conversationUsageResponseSchema);
382
+ return usage;
383
+ },
363
384
  listSubagentTasks: async ({ conversationId }) => {
364
385
  const { result } = await get(`/api/v1/trpc/v2.subagentTasks.list?input=${encodeURIComponent(JSON.stringify({ conversationId }))}`, subagentTasksResponseSchema);
365
386
  return new Map(result.data.subagentTasks.map((task) => [task.id, task]));
@@ -422,9 +443,13 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
422
443
  setConversationArchived: async ({ conversationId, archived }) => {
423
444
  await post(`/api/v1/conversations/${encodeURIComponent(conversationId)}/archive`, { archived }, z.object({ archived: z.boolean() }));
424
445
  },
446
+ setConversationPinned: async ({ conversationId, pinned }) => {
447
+ await post(`/api/v1/conversations/${encodeURIComponent(conversationId)}/pin`, { pinned }, z.object({ pinned: z.boolean() }));
448
+ },
425
449
  markConversationRead: async ({ conversationId }) => {
426
450
  await post(`/api/v1/conversations/${encodeURIComponent(conversationId)}/read`, {}, z.object({ read: z.boolean() }));
427
451
  },
452
+ trackAnalyticsEvent: async (input) => post("/api/v1/cli-analytics/track", input, z.object({ ok: z.boolean() })),
428
453
  renameConversation: async ({ conversationId, title }) => {
429
454
  await post(`/api/v1/conversations/${encodeURIComponent(conversationId)}`, { title }, z.object({ conversation: z.object({ id: z.string() }) }), "PATCH");
430
455
  },
@@ -541,14 +566,34 @@ const platformModelSchema = z.object({
541
566
  providerDisplay: z.string().optional(),
542
567
  reasoning: z.boolean().optional(),
543
568
  compliant: z.boolean().optional(),
569
+ noTraining: z.boolean().optional(),
544
570
  thinkingLevels: z.array(z.string()).optional(),
545
- thinkingLevelLabels: z.record(z.string(), z.string()).optional()
571
+ thinkingLevelLabels: z.record(z.string(), z.string()).optional(),
572
+ signals: z.object({
573
+ intelligence: z.number().int().min(1).max(6).nullable(),
574
+ speed: z.number().int().min(1).max(6).nullable(),
575
+ cost: z.number().int().min(1).max(6).nullable()
576
+ }).optional()
546
577
  }).passthrough();
547
- const listModelsResponseSchema = z.object({ models: z.array(platformModelSchema) });
578
+ const listModelsResponseSchema = z.object({
579
+ models: z.array(platformModelSchema),
580
+ trainingOptedOut: z.boolean().optional()
581
+ });
548
582
  const modelEffortPreferencesResponseSchema = z.object({ modelConfigOverrides: z.record(z.string(), z.object({ thinkingLevel: z.string().optional() })).optional() });
583
+ const billingSummaryResponseSchema = z.object({ result: z.object({ data: z.object({
584
+ planKey: z.string().nullable(),
585
+ blockReason: z.string().nullable(),
586
+ billingEnforcementEnabled: z.boolean()
587
+ }) }) });
588
+ const freeFloorStateResponseSchema = z.object({ result: z.object({ data: z.object({
589
+ available: z.boolean(),
590
+ models: z.array(z.string()),
591
+ resetsAt: z.string().nullable()
592
+ }).nullable() }) });
549
593
  const conversationModelResponseSchema = z.object({
550
594
  model: z.string().nullable(),
551
- thinkingLevel: z.string().nullable()
595
+ thinkingLevel: z.string().nullable(),
596
+ scope: z.enum(["agent", "conversation"]).nullish()
552
597
  });
553
598
  const updateAgentResponseSchema = z.object({ agent: z.object({
554
599
  model: z.string().nullable().optional(),
@@ -582,7 +627,10 @@ const conversationSummarySchema = z.object({
582
627
  channel: z.string().nullable(),
583
628
  channelLabel: z.string().nullable(),
584
629
  viewerArchivedAt: z.string().nullable().optional(),
630
+ viewerPinnedAt: z.string().nullable().optional(),
631
+ viewerParticipates: z.boolean().optional(),
585
632
  unread: z.boolean().optional(),
633
+ activeRun: z.boolean().optional(),
586
634
  agent: conversationAgentSchema,
587
635
  agents: z.array(conversationAgentSchema).optional()
588
636
  });
@@ -636,6 +684,31 @@ const uiMessageSchema = z.object({
636
684
  agentName: z.string().nullish()
637
685
  }).passthrough().optional() }).passthrough().optional()
638
686
  });
687
+ const conversationUsageModelSchema = z.object({
688
+ model: z.string().nullable(),
689
+ promptTokens: z.number(),
690
+ completionTokens: z.number(),
691
+ cacheCreationTokens: z.number(),
692
+ cacheReadTokens: z.number(),
693
+ cents: z.number()
694
+ });
695
+ const conversationUsageSchema = z.object({
696
+ own: z.object({
697
+ inferenceCents: z.number(),
698
+ byModel: z.array(conversationUsageModelSchema)
699
+ }),
700
+ children: z.object({
701
+ inferenceCents: z.number(),
702
+ conversationCount: z.number()
703
+ }),
704
+ compute: z.object({
705
+ cents: z.number(),
706
+ vcpuSeconds: z.number()
707
+ }),
708
+ unpriced: z.array(z.string()),
709
+ totalCents: z.number()
710
+ });
711
+ const conversationUsageResponseSchema = z.object({ usage: conversationUsageSchema.nullable() });
639
712
  const recapResponseSchema = z.object({ recap: z.object({ text: z.string() }).nullable() });
640
713
  const subagentTaskSnapshotSchema = z.object({
641
714
  id: z.string(),
@@ -718,7 +791,8 @@ const conversationStreamEventSchema = z.discriminatedUnion("kind", [
718
791
  id: z.string(),
719
792
  model: z.string().nullable(),
720
793
  modelLocked: z.boolean(),
721
- thinkingLevel: z.string().nullish()
794
+ thinkingLevel: z.string().nullish(),
795
+ agentModel: z.string().nullish()
722
796
  }),
723
797
  z.object({
724
798
  kind: z.literal("run"),
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as sendErrorMessage, n as errorDetail, r as filenameFromContentDisposition, t as createRestClient } from "./rest-Dspsplnl.mjs";
2
+ import { i as sendErrorMessage, n as errorDetail, r as filenameFromContentDisposition, t as createRestClient } from "./rest-BkyLLyCo.mjs";
3
3
  import { t as HttpError } from "./http-error-BF2NZZE3.mjs";
4
4
  import "./billing-blocked-D3l5kJlX.mjs";
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skydive-cli",
3
- "version": "0.6.0-beta.8",
3
+ "version": "0.6.0-beta.81",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "typecheck": "tsgo --noEmit"
32
32
  },
33
33
  "dependencies": {
34
- "@opentui/react": "0.5.8",
34
+ "@opentui/react": "0.5.10",
35
35
  "conf": "^13.0.1",
36
36
  "diff": "9.0.0",
37
37
  "eventsource-parser": "^3.0.8",
@@ -39,7 +39,7 @@
39
39
  "fuzzysort": "^3.1.0",
40
40
  "neverthrow": "^8.2.0",
41
41
  "open": "^10.1.0",
42
- "react": "^19.2.0",
42
+ "react": "^19.0.0",
43
43
  "react-devtools-core": "^7.0.1",
44
44
  "safe-stable-stringify": "^2.3.1",
45
45
  "semver": "^7.7.4",
@@ -51,6 +51,7 @@
51
51
  "zustand": "^5.0.2"
52
52
  },
53
53
  "devDependencies": {
54
+ "@createinc/anyone-agents": "^0.0.0",
54
55
  "@createinc/anyone-portal-daemon": "0.0.0",
55
56
  "@createinc/anyone-sandbox-stream-protocol": "0.0.0",
56
57
  "@createinc/tsconfig": "0.0.0",
@@ -60,10 +61,10 @@
60
61
  "@types/semver": "^7.7.1",
61
62
  "@types/yargs": "^17.0.33",
62
63
  "@typescript/native-preview": "^7.0.0-dev.20260113.1",
63
- "@vitest/coverage-v8": "^2.1.8",
64
+ "@vitest/coverage-v8": "^3.2.4",
64
65
  "tsdown": "^0.20.3",
65
66
  "typescript": "^5.9.3",
66
- "vitest": "^2.1.8"
67
+ "vitest": "^3.2.4"
67
68
  },
68
69
  "engines": {
69
70
  "bun": ">=1.3.14",
@@ -71,9 +72,9 @@
71
72
  },
72
73
  "//optionalDependencies": "The per-platform binary packages (skydive-cli-<os>-<arch>) are INTENTIONALLY not committed here. They are published by release-skydive-cli-binaries.yml and injected — pinned to the exact version being published — into the published launcher's optionalDependencies at release time (scripts/prepare-platform-packages.mjs --pin-version, run in release-skydive-cli.yml). Committing them would make `yarn install` try to resolve versions that only exist post-publish, breaking local dev and CI. npm installs of a published skydive-cli still get them (os/cpu-gated); the launcher (src/launcher.ts) resolves and execs the matching one. Local dev never needs them: it runs the JS bundle or `build:binary` directly.",
73
74
  "optionalDependencies": {
74
- "skydive-cli-darwin-arm64": "0.6.0-beta.8",
75
- "skydive-cli-darwin-x64": "0.6.0-beta.8",
76
- "skydive-cli-linux-x64": "0.6.0-beta.8",
77
- "skydive-cli-linux-arm64": "0.6.0-beta.8"
75
+ "skydive-cli-darwin-arm64": "0.6.0-beta.81",
76
+ "skydive-cli-darwin-x64": "0.6.0-beta.81",
77
+ "skydive-cli-linux-x64": "0.6.0-beta.81",
78
+ "skydive-cli-linux-arm64": "0.6.0-beta.81"
78
79
  }
79
80
  }
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- import { t as PortalClient } from "./client-rEnnRv0U.mjs";
3
- import "./api-BFQ4PQDA.mjs";
4
-
5
- export { PortalClient };
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./client-rEnnRv0U.mjs";
3
- import "./tls-cert-Rua2oV7n.mjs";
4
- import "./api-BFQ4PQDA.mjs";
5
- import "./daemon-C6C2LWDy.mjs";
6
- import { t as PortalDaemonClient } from "./daemon-client-JI3fEdpn.mjs";
7
-
8
- export { PortalDaemonClient };
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./client-Btq6bMzX.mjs";
3
- import { t as runRawPtyPassthrough } from "./raw-pty-D5PhKZSl.mjs";
4
-
5
- export { runRawPtyPassthrough };