skydive-cli 0.6.0-beta.114 → 0.6.0-beta.116

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,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import { c as version, s as name, t as createRestClient } from "./rest-DOBahsht.mjs";
3
- import { A as getPreference, B as resolveChatAuth, C as DEFAULT_API_URL, D as getConfigPath, E as deleteConfig, F as getStoredApiKeyId, G as saveConfig, H as resolveManagementAuth, I as getStoredApiKeyWorkspaceName, J as setLastSeenVersion, K as saveSession, L as getUpdateCheckDisabled, O as getDefaultAgent, P as getShareMachineDefault, S as API_KEY_PREFIX, T as PREFERENCES, U as resolveSession$1, V as resolveConfig, b as API_KEYS_URL, i as resolveAgent$1, j as getPromptHistoryPath, k as getLastSeenVersion, x as API_KEY_FAMILY_PREFIX, z as resolveAppUrl } from "./print-DxSdcppI.mjs";
4
- import { A as aliasActivationHint, B as getSessionIdentity, E as themes, F as SUPPORTED_SHELLS, H as resolveWorkspaceId, I as defaultInstallEnv, L as detectShell, M as installAgentAlias, N as slugifyAliasName, O as buildImportSeedPrompt, P as takenAliasNames, R as ensureActiveOrganization, U as setActiveWorkspace, V as listWorkspaces, c as brandHelpArt, d as maybeStartProfiling, f as profileDir, j as dedupeAliasName, k as machineOsFromPlatform, t as installCrashHandler, u as getAutomaticLogsDir, z as getActiveWorkspaceId } from "./install-CBH7cP3w.mjs";
2
+ import { c as version, s as name, t as createRestClient } from "./rest-BW0kOOf5.mjs";
3
+ import { A as getPreference, B as resolveChatAuth, C as DEFAULT_API_URL, D as getConfigPath, E as deleteConfig, F as getStoredApiKeyId, G as saveConfig, H as resolveManagementAuth, I as getStoredApiKeyWorkspaceName, J as setLastSeenVersion, K as saveSession, L as getUpdateCheckDisabled, O as getDefaultAgent, P as getShareMachineDefault, S as API_KEY_PREFIX, T as PREFERENCES, U as resolveSession$1, V as resolveConfig, b as API_KEYS_URL, i as resolveAgent$1, j as getPromptHistoryPath, k as getLastSeenVersion, x as API_KEY_FAMILY_PREFIX, z as resolveAppUrl } from "./print-Chf1MyJK.mjs";
4
+ import { A as aliasActivationHint, B as getSessionIdentity, E as themes, F as SUPPORTED_SHELLS, H as resolveWorkspaceId, I as defaultInstallEnv, L as detectShell, M as installAgentAlias, N as slugifyAliasName, O as buildImportSeedPrompt, P as takenAliasNames, R as ensureActiveOrganization, U as setActiveWorkspace, V as listWorkspaces, c as brandHelpArt, d as maybeStartProfiling, f as profileDir, j as dedupeAliasName, k as machineOsFromPlatform, t as installCrashHandler, u as getAutomaticLogsDir, z as getActiveWorkspaceId } from "./install-C71mocIJ.mjs";
5
5
  import { n as printError, r as printTable, t as output } from "./output-C9mb3sUB.mjs";
6
6
  import { t as HttpError } from "./http-error-BF2NZZE3.mjs";
7
7
  import "./billing-blocked-D3l5kJlX.mjs";
8
- import { s as resolveMachineIdentity } from "./client-DFizfTrs.mjs";
8
+ import { s as resolveMachineIdentity } from "./client-6HkECaQY.mjs";
9
9
  import "./tls-cert-Rua2oV7n.mjs";
10
10
  import { i as grantPortalAccess, n as fetchPortalDevices, o as registerPortalDevice, r as findThisDevice, s as revokePortalAccess } from "./api-BFQ4PQDA.mjs";
11
- import { d as daemonPaths, i as queryDaemonStatus, n as ensureDaemonRunning, s as stopDaemon, u as PORTAL_DAEMON_FLAG } from "./daemon-YluL9ulI.mjs";
11
+ import { d as daemonPaths, i as queryDaemonStatus, n as ensureDaemonRunning, s as stopDaemon, u as PORTAL_DAEMON_FLAG } from "./daemon-Ds1su2WI.mjs";
12
12
  import { a as FS_MAX_BLOB_BYTES, i as streamSpecToQuery, n as DEFAULT_EXEC_TIMEOUT_MS, o as decodeFsResponse, r as SANDBOX_STREAM_PATH, s as encodeFsRequest, t as SandboxStream } from "./client-Cxk3khQu.mjs";
13
13
  import { hideBin } from "yargs/helpers";
14
14
  import yargs from "yargs";
@@ -1176,7 +1176,7 @@ async function resolveTargetAgentId(client, selector) {
1176
1176
  printError("Missing --agent <id or name>. Run `skydive agents list` for candidates.");
1177
1177
  process.exit(1);
1178
1178
  }
1179
- const { resolveAgent } = await import("./print-BoNswI3_.mjs");
1179
+ const { resolveAgent } = await import("./print-DsSX6iCt.mjs");
1180
1180
  const result = await client.listAgents({
1181
1181
  scope: "org",
1182
1182
  limit: 100
@@ -1985,7 +1985,7 @@ const importCommand = {
1985
1985
  process.exit(1);
1986
1986
  }
1987
1987
  }
1988
- const { runChat } = await import("./boot-Cv4aKjh5.mjs");
1988
+ const { runChat } = await import("./boot-NCNfcUPM.mjs");
1989
1989
  await runChat({
1990
1990
  appUrl,
1991
1991
  sessionToken: session.value.sessionToken,
@@ -2015,7 +2015,7 @@ async function runImportPrintMode({ argv, appUrl }) {
2015
2015
  printError(`${session.error.message} For non-interactive use, run \`skydive auth login --web\` first, or set SKYDIVE_SESSION_TOKEN.`);
2016
2016
  process.exit(1);
2017
2017
  }
2018
- const { connectMachineShare } = await import("./print-share-CSJURV8z.mjs");
2018
+ const { connectMachineShare } = await import("./print-share-CJVL4i4K.mjs");
2019
2019
  const machineShare = await connectMachineShare({
2020
2020
  appUrl,
2021
2021
  sessionToken: session.value.sessionToken,
@@ -2023,7 +2023,7 @@ async function runImportPrintMode({ argv, appUrl }) {
2023
2023
  });
2024
2024
  const extra = (argv.print ?? "").trim();
2025
2025
  const prompt = buildImportSeedPrompt(process.cwd(), machineOsFromPlatform(process.platform)) + (extra ? `\n\nAdditional instructions: ${extra}` : "");
2026
- const { runPrint } = await import("./print-BoNswI3_.mjs");
2026
+ const { runPrint } = await import("./print-DsSX6iCt.mjs");
2027
2027
  try {
2028
2028
  const result = await runPrint({
2029
2029
  appUrl,
@@ -2446,7 +2446,7 @@ const chatCommand = {
2446
2446
  sessionToken: auth.value.token,
2447
2447
  agentSelector: argv.agent ?? null
2448
2448
  });
2449
- const { runChat } = await import("./boot-Cv4aKjh5.mjs");
2449
+ const { runChat } = await import("./boot-NCNfcUPM.mjs");
2450
2450
  await runChat({
2451
2451
  appUrl: auth.value.appUrl,
2452
2452
  sessionToken: auth.value.token,
@@ -2530,7 +2530,7 @@ async function runPrintMode({ argv, appUrl }) {
2530
2530
  printError(`${auth.error.message} For non-interactive use, run \`skydive auth login\` first, or set SKYDIVE_API_KEY / SKYDIVE_SESSION_TOKEN.`);
2531
2531
  process.exit(1);
2532
2532
  }
2533
- const { runPrint, readStdin } = await import("./print-BoNswI3_.mjs");
2533
+ const { runPrint, readStdin } = await import("./print-DsSX6iCt.mjs");
2534
2534
  const workspaceId = await resolveWorkspaceFlag({
2535
2535
  appUrl,
2536
2536
  sessionToken: auth.value.token,
@@ -2560,7 +2560,7 @@ async function runPrintMode({ argv, appUrl }) {
2560
2560
  process.exit(1);
2561
2561
  }
2562
2562
  } else {
2563
- const { connectMachineShare } = await import("./print-share-CSJURV8z.mjs");
2563
+ const { connectMachineShare } = await import("./print-share-CJVL4i4K.mjs");
2564
2564
  machineShare = await connectMachineShare({
2565
2565
  appUrl: auth.value.appUrl,
2566
2566
  sessionToken: auth.value.token,
@@ -2625,7 +2625,7 @@ const getCommand$1 = {
2625
2625
  printError(`${auth.error.message} Run \`skydive auth login\` first, or set SKYDIVE_API_KEY / SKYDIVE_SESSION_TOKEN.`);
2626
2626
  process.exit(1);
2627
2627
  }
2628
- const { messageGet } = await import("./print-BoNswI3_.mjs");
2628
+ const { messageGet } = await import("./print-DsSX6iCt.mjs");
2629
2629
  try {
2630
2630
  const result = await messageGet({
2631
2631
  appUrl: auth.value.appUrl,
@@ -2828,7 +2828,7 @@ const switchCommand = {
2828
2828
  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.");
2829
2829
  process.exit(1);
2830
2830
  }
2831
- const { runWorkspacePicker } = await import("./boot-Cv4aKjh5.mjs");
2831
+ const { runWorkspacePicker } = await import("./boot-NCNfcUPM.mjs");
2832
2832
  await runWorkspacePicker(session);
2833
2833
  return;
2834
2834
  }
@@ -2907,7 +2907,7 @@ const openCommand = {
2907
2907
  const agent = argv.agent ? resolveAgent$1((await fetchPortalDevices(session)).agents, argv.agent) : null;
2908
2908
  const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
2909
2909
  const { machineName } = await resolveMachineIdentity(null);
2910
- const { PortalDaemonClient } = await import("./daemon-client-DM4HMwwf.mjs");
2910
+ const { PortalDaemonClient } = await import("./daemon-client-CQS9DT1k.mjs");
2911
2911
  let lastLine = "";
2912
2912
  let signalConnected;
2913
2913
  const connected = new Promise((resolve) => {
@@ -3267,8 +3267,8 @@ const sandboxCommand = {
3267
3267
  }).example("skydive sandbox --agent grace", "Live terminal (Ctrl-] detaches)").example("skydive sandbox --agent grace -- tail -n 50 /tmp/harness.log", "One-shot command (use `--` so its flags reach the sandbox)").example("skydive sandbox --agent grace -- sh -c 'ls /tmp | wc -l'", "Shell features go through an explicit `sh -c`"),
3268
3268
  handler: async (argv) => {
3269
3269
  const session = requireSession(argv);
3270
- const { createRestClient } = await import("./rest-w-EM3e41.mjs");
3271
- const { resolveAgent } = await import("./print-BoNswI3_.mjs");
3270
+ const { createRestClient } = await import("./rest-DTxe6wdI.mjs");
3271
+ const { resolveAgent } = await import("./print-DsSX6iCt.mjs");
3272
3272
  const client = createRestClient({
3273
3273
  appUrl: session.appUrl,
3274
3274
  sessionToken: session.sessionToken
@@ -3560,8 +3560,8 @@ function resolveEditor(override, env, platform = process.platform) {
3560
3560
  * `sandbox-fs-enabled` kill switch) exits here before any file work.
3561
3561
  */
3562
3562
  async function openAgentFs(session, agentSelector) {
3563
- const { createRestClient } = await import("./rest-w-EM3e41.mjs");
3564
- const { resolveAgent } = await import("./print-BoNswI3_.mjs");
3563
+ const { createRestClient } = await import("./rest-DTxe6wdI.mjs");
3564
+ const { resolveAgent } = await import("./print-DsSX6iCt.mjs");
3565
3565
  let agent;
3566
3566
  try {
3567
3567
  agent = resolveAgent(await createRestClient({
@@ -5351,7 +5351,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
5351
5351
  process.exit(0);
5352
5352
  }
5353
5353
  if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
5354
- const { runPortalDaemon } = await import("./daemon-3M_Ea1QX.mjs");
5354
+ const { runPortalDaemon } = await import("./daemon-CSr9E4cY.mjs");
5355
5355
  runPortalDaemon(process.argv);
5356
5356
  } else runCli();
5357
5357
  function runCli() {
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, i as sendErrorMessage, n as errorDetail, o as isRecord, t as createRestClient } from "./rest-DOBahsht.mjs";
3
- import { C as DEFAULT_API_URL, D as getConfigPath, M as getReviewStateDir, N as getSavedTheme, R as recordDefaultAgent, W as resolveWebUrl, _ as computeSettledLabel, c as actionableCardVerb, d as parseOauthConnectParams, f as prioritizeActionableCards, g as composeQuestionAnswerEntries, h as composeQuestionAnswer, i as resolveAgent, l as cardActionErrorMessage, m as resolveConnectUrl, p as reconcileMaskedInput, q as saveTheme, s as MASK_CHAR, u as parseExternalOauthConnectParams, v as parseConnectCard, w as DEFAULT_APP_URL, y as specKeyFor } from "./print-DxSdcppI.mjs";
4
- import { A as aliasActivationHint, C as themeMode, D as themesForMode, L as detectShell, M as installAgentAlias, N as slugifyAliasName, P as takenAliasNames, S as themeForMode, T as themeVersion, U as setActiveWorkspace, V as listWorkspaces, _ as applyTheme, a as writeCrashReport, b as noColorRequested, g as DEFAULT_THEME_ID, h as writeArtifact, i as buildCrashReport, j as dedupeAliasName, k as machineOsFromPlatform, l as splashFitsWidth, m as record, n as disableTerminalAutowrap, o as MARK_CELLS, p as profilingEnabled, r as restoreTerminalAutowrap, s as WORDMARK, t as installCrashHandler, v as findTheme, w as themeModeFromColorFgBg, x as theme, y as monoTheme, z as getActiveWorkspaceId } from "./install-CBH7cP3w.mjs";
2
+ import { a as errorMessage, i as sendErrorMessage, n as errorDetail, o as isRecord, t as createRestClient } from "./rest-BW0kOOf5.mjs";
3
+ import { C as DEFAULT_API_URL, D as getConfigPath, M as getReviewStateDir, N as getSavedTheme, R as recordDefaultAgent, W as resolveWebUrl, _ as computeSettledLabel, c as actionableCardVerb, d as parseOauthConnectParams, f as prioritizeActionableCards, g as composeQuestionAnswerEntries, h as composeQuestionAnswer, i as resolveAgent, l as cardActionErrorMessage, m as resolveConnectUrl, p as reconcileMaskedInput, q as saveTheme, s as MASK_CHAR, u as parseExternalOauthConnectParams, v as parseConnectCard, w as DEFAULT_APP_URL, y as specKeyFor } from "./print-Chf1MyJK.mjs";
4
+ import { A as aliasActivationHint, C as themeMode, D as themesForMode, L as detectShell, M as installAgentAlias, N as slugifyAliasName, P as takenAliasNames, S as themeForMode, T as themeVersion, U as setActiveWorkspace, V as listWorkspaces, _ as applyTheme, a as writeCrashReport, b as noColorRequested, g as DEFAULT_THEME_ID, h as writeArtifact, i as buildCrashReport, j as dedupeAliasName, k as machineOsFromPlatform, l as splashFitsWidth, m as record, n as disableTerminalAutowrap, o as MARK_CELLS, p as profilingEnabled, r as restoreTerminalAutowrap, s as WORDMARK, t as installCrashHandler, v as findTheme, w as themeModeFromColorFgBg, x as theme, y as monoTheme, z as getActiveWorkspaceId } from "./install-C71mocIJ.mjs";
5
5
  import { t as HttpError } from "./http-error-BF2NZZE3.mjs";
6
6
  import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-D3l5kJlX.mjs";
7
- import { n as PortalClient } from "./client-DFizfTrs.mjs";
7
+ import { n as PortalClient } from "./client-6HkECaQY.mjs";
8
8
  import { t as defaultTlsCertSource } from "./tls-cert-Rua2oV7n.mjs";
9
9
  import "./api-BFQ4PQDA.mjs";
10
- import "./daemon-YluL9ulI.mjs";
10
+ import "./daemon-Ds1su2WI.mjs";
11
11
  import { t as SandboxStream } from "./client-Cxk3khQu.mjs";
12
- import { t as PortalDaemonClient } from "./daemon-client-DOxEtaXg.mjs";
12
+ import { t as PortalDaemonClient } from "./daemon-client-DJ7xcv1x.mjs";
13
13
  import { t as runRawPtyPassthrough } from "./raw-pty-B-WKaaE3.mjs";
14
14
  import * as os$1 from "node:os";
15
15
  import { homedir, platform, release, tmpdir } from "node:os";
@@ -3100,48 +3100,39 @@ function WelcomeFrame({ contentWidth, children }) {
3100
3100
  flexDirection: "column",
3101
3101
  flexGrow: 1
3102
3102
  } });
3103
- return /* @__PURE__ */ jsxs("box", {
3103
+ return /* @__PURE__ */ jsx("box", {
3104
3104
  style: {
3105
3105
  flexDirection: "column",
3106
- flexGrow: 1,
3107
- alignItems: "center"
3106
+ height: "100%",
3107
+ alignItems: "center",
3108
+ justifyContent: "center"
3108
3109
  },
3109
- children: [
3110
- /* @__PURE__ */ jsx("box", { style: {
3111
- flexGrow: 1,
3112
- flexShrink: 1
3113
- } }),
3114
- /* @__PURE__ */ jsxs("box", {
3110
+ children: /* @__PURE__ */ jsxs("box", {
3111
+ style: {
3112
+ flexDirection: "column",
3113
+ width: contentWidth
3114
+ },
3115
+ children: [/* @__PURE__ */ jsxs("box", {
3115
3116
  style: {
3116
3117
  flexDirection: "column",
3117
- width: contentWidth
3118
+ alignItems: "center"
3118
3119
  },
3119
- children: [/* @__PURE__ */ jsxs("box", {
3120
+ children: [/* @__PURE__ */ jsx(BrandHeader, {
3121
+ height,
3122
+ width
3123
+ }), height >= 24 ? /* @__PURE__ */ jsxs("box", {
3120
3124
  style: {
3121
3125
  flexDirection: "column",
3122
3126
  alignItems: "center"
3123
3127
  },
3124
- children: [/* @__PURE__ */ jsx(BrandHeader, {
3125
- height,
3126
- width
3127
- }), height >= 24 ? /* @__PURE__ */ jsxs("box", {
3128
- style: {
3129
- flexDirection: "column",
3130
- alignItems: "center"
3131
- },
3132
- children: [/* @__PURE__ */ jsx("text", {
3133
- fg: theme.accent,
3134
- attributes: 1,
3135
- children: "Welcome to Skydive"
3136
- }), /* @__PURE__ */ jsx("box", { style: { height: 1 } })]
3137
- }) : null]
3138
- }), children]
3139
- }),
3140
- /* @__PURE__ */ jsx("box", { style: {
3141
- flexGrow: 1,
3142
- flexShrink: 1
3143
- } })
3144
- ]
3128
+ children: [/* @__PURE__ */ jsx("text", {
3129
+ fg: theme.accent,
3130
+ attributes: 1,
3131
+ children: "Welcome to Skydive"
3132
+ }), /* @__PURE__ */ jsx("box", { style: { height: 1 } })]
3133
+ }) : null]
3134
+ }), children]
3135
+ })
3145
3136
  });
3146
3137
  }
3147
3138
  function AgentListMode({ state, scope, onToggleScope, onCreate, onSwitchWorkspace, onPick, onSwitchModel, modelPickerOpen }) {
@@ -3188,6 +3179,7 @@ function FilterableAgentList({ agents, scope, contentWidth, onToggleScope, onCre
3188
3179
  const visibleRows = Math.max(3, height - 8 - brandHeaderRows(height, width) - identityRows);
3189
3180
  const listRows = Math.min(visibleRows, Math.max(3, Math.floor(height * MAX_LIST_FRACTION)));
3190
3181
  const start = windowStart(clamped, filtered.length, listRows);
3182
+ const paintedRows = Math.min(listRows, agents.length);
3191
3183
  const windowed = hits.slice(start, start + listRows);
3192
3184
  const openAgent = () => {
3193
3185
  const agent = filtered[clamped];
@@ -3279,7 +3271,7 @@ function FilterableAgentList({ agents, scope, contentWidth, onToggleScope, onCre
3279
3271
  style: {
3280
3272
  flexDirection: "column",
3281
3273
  flexShrink: 0,
3282
- height: listRows
3274
+ height: paintedRows
3283
3275
  },
3284
3276
  children: empty ? /* @__PURE__ */ jsx("text", {
3285
3277
  fg: theme.muted,
@@ -4177,10 +4169,16 @@ function useComposerAttachments(input) {
4177
4169
  stageFiles(files);
4178
4170
  return;
4179
4171
  }
4180
- onPasteText(route.text);
4172
+ onPasteText(stripControlChars(route.text));
4181
4173
  });
4182
4174
  return;
4183
- case "text": return;
4175
+ case "text": {
4176
+ const sanitized = stripControlChars(text);
4177
+ if (sanitized === text) return;
4178
+ event.preventDefault();
4179
+ onPasteText(sanitized);
4180
+ return;
4181
+ }
4184
4182
  }
4185
4183
  });
4186
4184
  return {
@@ -4198,6 +4196,16 @@ function useComposerAttachments(input) {
4198
4196
  }
4199
4197
  /** Name for clipboard image bytes, which arrive with no filename of their
4200
4198
  * own: `pasted-image-<timestamp>.<ext>` from the paste's own media type. */
4199
+ /**
4200
+ * Control characters (C0 except tab/newline/carriage-return, DEL, C1) crash
4201
+ * opentui 0.6 EditBuffer/Textarea with a NativeError on insert.
4202
+ */
4203
+ function isControlChar(code) {
4204
+ return code < 32 && code !== 9 && code !== 10 && code !== 13 || code === 127 || code >= 128 && code <= 159;
4205
+ }
4206
+ function stripControlChars(text) {
4207
+ return [...text].filter((char) => !isControlChar(char.codePointAt(0) ?? 0)).join("");
4208
+ }
4201
4209
  function pastedImageName(mediaType) {
4202
4210
  const ext = mediaType.split("/")[1]?.split("+")[0] ?? "png";
4203
4211
  return `pasted-image-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.${ext}`;
@@ -4590,38 +4598,29 @@ function HomeFrame({ children }) {
4590
4598
  flexDirection: "column",
4591
4599
  flexGrow: 1
4592
4600
  } });
4593
- return /* @__PURE__ */ jsxs("box", {
4601
+ return /* @__PURE__ */ jsx("box", {
4594
4602
  style: {
4595
4603
  flexDirection: "column",
4596
- flexGrow: 1,
4597
- alignItems: "center"
4604
+ height: "100%",
4605
+ alignItems: "center",
4606
+ justifyContent: "center"
4598
4607
  },
4599
- children: [
4600
- /* @__PURE__ */ jsx("box", { style: {
4601
- flexGrow: 1,
4602
- flexShrink: 1
4603
- } }),
4604
- /* @__PURE__ */ jsxs("box", {
4608
+ children: /* @__PURE__ */ jsxs("box", {
4609
+ style: {
4610
+ flexDirection: "column",
4611
+ width: contentWidth
4612
+ },
4613
+ children: [/* @__PURE__ */ jsx("box", {
4605
4614
  style: {
4606
4615
  flexDirection: "column",
4607
- width: contentWidth
4616
+ alignItems: "center"
4608
4617
  },
4609
- children: [/* @__PURE__ */ jsx("box", {
4610
- style: {
4611
- flexDirection: "column",
4612
- alignItems: "center"
4613
- },
4614
- children: /* @__PURE__ */ jsx(BrandHeader, {
4615
- height,
4616
- width
4617
- })
4618
- }), children]
4619
- }),
4620
- /* @__PURE__ */ jsx("box", { style: {
4621
- flexGrow: 1,
4622
- flexShrink: 1
4623
- } })
4624
- ]
4618
+ children: /* @__PURE__ */ jsx(BrandHeader, {
4619
+ height,
4620
+ width
4621
+ })
4622
+ }), children]
4623
+ })
4625
4624
  });
4626
4625
  }
4627
4626
  /**
@@ -5030,6 +5029,7 @@ function ConversationHome({ agent, initialQuery, conversations, showAutomated, o
5030
5029
  return /* @__PURE__ */ jsxs("box", {
5031
5030
  style: {
5032
5031
  flexDirection: "column",
5032
+ height: "100%",
5033
5033
  flexGrow: 1,
5034
5034
  alignItems: "center"
5035
5035
  },
@@ -5349,10 +5349,51 @@ async function exportTranscript(options) {
5349
5349
  return filePath;
5350
5350
  }
5351
5351
 
5352
+ //#endregion
5353
+ //#region src/chat/tui/chunks/markdown-chunks.ts
5354
+ const MARKDOWN_CHUNK_TARGET_BYTES = 32 * 1024;
5355
+ const CODE_FENCE = /^(`{3,}|~{3,})/;
5356
+ function byteLength(lines) {
5357
+ return lines.reduce((sum, line) => sum + Buffer.byteLength(line) + 1, 0);
5358
+ }
5359
+ function splitMarkdownIntoChunks(markdown, targetBytes = MARKDOWN_CHUNK_TARGET_BYTES) {
5360
+ if (Buffer.byteLength(markdown) <= targetBytes) return [markdown];
5361
+ const lines = markdown.split("\n");
5362
+ const chunks = [];
5363
+ let current = [];
5364
+ let inFence = false;
5365
+ let fenceMarker = "";
5366
+ const flush = () => {
5367
+ if (current.length > 0) chunks.push(current.join("\n"));
5368
+ current = [];
5369
+ };
5370
+ for (const line of lines) {
5371
+ const fenceMatch = CODE_FENCE.exec(line);
5372
+ const fenceChar = fenceMatch?.[1]?.[0];
5373
+ if (fenceMatch && (!inFence || fenceChar === fenceMarker)) {
5374
+ if (!inFence) {
5375
+ inFence = true;
5376
+ fenceMarker = fenceChar ?? "";
5377
+ } else {
5378
+ inFence = false;
5379
+ fenceMarker = "";
5380
+ }
5381
+ current.push(line);
5382
+ continue;
5383
+ }
5384
+ current.push(line);
5385
+ if (!inFence && line === "" && byteLength(current) >= targetBytes) flush();
5386
+ }
5387
+ flush();
5388
+ if (chunks.length === 0) chunks.push(markdown);
5389
+ return chunks;
5390
+ }
5391
+
5352
5392
  //#endregion
5353
5393
  //#region src/chat/tui/chunks/syntax.ts
5354
5394
  let cached = null;
5355
5395
  let cachedVersion = -1;
5396
+ let cachedOwner = null;
5356
5397
  let retiring = null;
5357
5398
  /**
5358
5399
  * Scope lookup falls back to the FIRST dot segment only (`markup.heading.1`
@@ -5419,6 +5460,10 @@ function syntaxStyleTable() {
5419
5460
  fg: theme.syntaxCyan,
5420
5461
  underline: true
5421
5462
  },
5463
+ "markup.underline": {
5464
+ fg: theme.fg,
5465
+ underline: true
5466
+ },
5422
5467
  "markup.link.bracket.close": { fg: theme.syntaxCyan },
5423
5468
  "markup.link.label": { fg: theme.syntaxCyan },
5424
5469
  "markup.link.url": {
@@ -5473,12 +5518,14 @@ function syntaxStyleTable() {
5473
5518
  embedded: { fg: theme.fg }
5474
5519
  };
5475
5520
  }
5476
- function syntaxStyle() {
5477
- if (cached && cachedVersion === themeVersion()) return cached;
5521
+ function syntaxStyle(renderer) {
5522
+ const owner = renderer.nativeScene.resourceContext;
5523
+ if (cached && cachedVersion === themeVersion() && cachedOwner === owner) return cached;
5478
5524
  retiring?.destroy();
5479
5525
  retiring = cached;
5480
5526
  cachedVersion = themeVersion();
5481
- cached = SyntaxStyle.fromStyles(syntaxStyleTable());
5527
+ cachedOwner = owner;
5528
+ cached = SyntaxStyle.fromStyles(syntaxStyleTable(), owner);
5482
5529
  return cached;
5483
5530
  }
5484
5531
 
@@ -5513,6 +5560,7 @@ function splitStableMarkdown(text) {
5513
5560
  //#region src/chat/tui/chunks/card.tsx
5514
5561
  function CardItem({ item }) {
5515
5562
  const { card, status, detail } = item;
5563
+ const renderer = useRenderer();
5516
5564
  return /* @__PURE__ */ jsxs("box", {
5517
5565
  style: {
5518
5566
  border: true,
@@ -5558,7 +5606,7 @@ function CardItem({ item }) {
5558
5606
  }, qi)),
5559
5607
  card.description ? /* @__PURE__ */ jsx("markdown", {
5560
5608
  content: card.description,
5561
- syntaxStyle: syntaxStyle(),
5609
+ syntaxStyle: syntaxStyle(renderer),
5562
5610
  fg: theme.assistant
5563
5611
  }) : null,
5564
5612
  /* @__PURE__ */ jsx(StatusLine, { item }),
@@ -6196,9 +6244,10 @@ function buildDiffs(filePath, pairs, maxLinesOverride) {
6196
6244
  return diffs;
6197
6245
  }
6198
6246
  function DiffBlock({ diff, filePath }) {
6247
+ const renderer = useRenderer();
6199
6248
  const palette = diffPalette();
6200
6249
  const ft = filetypeForPath(filePath);
6201
- const ss = syntaxStyle();
6250
+ const ss = syntaxStyle(renderer);
6202
6251
  const segments = segmentRows(diff.rows);
6203
6252
  const numWidth = Math.max(...diff.rows.map((r) => String(r.lineNo).length), 2);
6204
6253
  return /* @__PURE__ */ jsxs("box", {
@@ -6940,6 +6989,7 @@ function Row({ barColor, children }) {
6940
6989
  });
6941
6990
  }
6942
6991
  function RenderItem({ item, onSaveFile }) {
6992
+ const renderer = useRenderer();
6943
6993
  switch (item.kind) {
6944
6994
  case "user": return /* @__PURE__ */ jsxs(Row, {
6945
6995
  barColor: theme.accent,
@@ -6967,12 +7017,12 @@ function RenderItem({ item, onSaveFile }) {
6967
7017
  case "assistant-text":
6968
7018
  if (item.done) return /* @__PURE__ */ jsx(Row, {
6969
7019
  barColor: null,
6970
- children: /* @__PURE__ */ jsx("markdown", {
6971
- content: item.text,
6972
- syntaxStyle: syntaxStyle(),
7020
+ children: splitMarkdownIntoChunks(item.text).map((chunk, index) => /* @__PURE__ */ jsx("markdown", {
7021
+ content: chunk,
7022
+ syntaxStyle: syntaxStyle(renderer),
6973
7023
  fg: theme.assistant,
6974
7024
  conceal: true
6975
- })
7025
+ }, index))
6976
7026
  });
6977
7027
  return /* @__PURE__ */ jsx(StreamingAssistantText, { text: item.text });
6978
7028
  case "reasoning": return /* @__PURE__ */ jsx(Row, {
@@ -7075,15 +7125,16 @@ function formatFileSize(bytes) {
7075
7125
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
7076
7126
  }
7077
7127
  function StreamingAssistantText({ text }) {
7128
+ const renderer = useRenderer();
7078
7129
  const { stable, tail } = splitStableMarkdown(text);
7079
7130
  return /* @__PURE__ */ jsxs(Row, {
7080
7131
  barColor: null,
7081
- children: [stable ? /* @__PURE__ */ jsx("markdown", {
7082
- content: stable,
7083
- syntaxStyle: syntaxStyle(),
7132
+ children: [(stable ? splitMarkdownIntoChunks(stable) : []).map((chunk, index) => /* @__PURE__ */ jsx("markdown", {
7133
+ content: chunk,
7134
+ syntaxStyle: syntaxStyle(renderer),
7084
7135
  fg: theme.assistant,
7085
7136
  conceal: true
7086
- }) : null, /* @__PURE__ */ jsxs("text", {
7137
+ }, index)), /* @__PURE__ */ jsxs("text", {
7087
7138
  fg: theme.assistant,
7088
7139
  children: [tail || (stable ? "" : " "), /* @__PURE__ */ jsx("span", {
7089
7140
  fg: theme.dim,
@@ -10209,16 +10260,19 @@ function filterSlashCommands(query) {
10209
10260
  * Leaving the chat has to work even when the renderer cannot finish its own
10210
10261
  * teardown.
10211
10262
  *
10212
- * `destroy()` restores the terminal from inside the render loop: when a frame
10213
- * is in flight it defers the restore to the loop's `finally` and returns
10214
- * immediately. That is fine while the loop is turning. When the loop has
10215
- * stopped producing frames, the deferred half never runs — the process keeps
10216
- * running with the alternate screen up, the cursor hidden and stdin in raw
10217
- * mode, so the pane looks frozen and quitting appears to do nothing.
10263
+ * Since opentui 0.6 `destroy()` only kicks off teardown: it suspends the
10264
+ * renderer (which flushes the exit from the alternate screen) and finishes
10265
+ * asynchronously. Its completion signal is the `closed` promise, which the
10266
+ * release notes say to await before closing stdout or calling process.exit().
10267
+ * `closed` rejects on abnormal termination; a rejection still counts as
10268
+ * settled, and the final state is read from `isDestroyed`.
10218
10269
  *
10219
- * So teardown checks whether the renderer actually finished. If it did not,
10220
- * we emit the same terminal reset ourselves and end the process rather than
10221
- * waiting on an event loop that is no longer draining.
10270
+ * The old failure mode still exists: when the render loop has stopped
10271
+ * producing frames, the deferred half of teardown never runs, the process
10272
+ * keeps running with the alternate screen up, the cursor hidden and stdin in
10273
+ * raw mode, and quitting appears to do nothing. A renderer that never settles
10274
+ * (or finishes without being destroyed) therefore takes the manual path after
10275
+ * a bounded wait.
10222
10276
  */
10223
10277
  /**
10224
10278
  * The reset the renderer writes when it completes teardown: show the cursor,
@@ -10246,13 +10300,28 @@ const TERMINAL_RESTORE = [
10246
10300
  * ends once the event loop drains, so nothing in flight is cut short. Only an
10247
10301
  * unfinished teardown takes the forced path.
10248
10302
  */
10249
- function exitChat({ renderer, afterTeardown, write = (text) => void process.stdout.write(text), setRawMode = (raw) => process.stdin.setRawMode?.(raw), exit = (code) => process.exit(code) }) {
10303
+ const exitingRenderers = /* @__PURE__ */ new WeakSet();
10304
+ async function exitChat({ renderer, afterTeardown, write = (text) => void process.stdout.write(text), setRawMode = (raw) => process.stdin.setRawMode?.(raw), exit = (code) => process.exit(code), teardownTimeoutMs = 500 }) {
10305
+ if (exitingRenderers.has(renderer)) return;
10306
+ exitingRenderers.add(renderer);
10250
10307
  let destroyThrew = false;
10251
10308
  try {
10252
10309
  renderer.destroy();
10253
10310
  } catch (_error) {
10254
10311
  destroyThrew = true;
10255
10312
  }
10313
+ if (!destroyThrew) {
10314
+ let timeoutHandle;
10315
+ try {
10316
+ const timeout = new Promise((resolve) => {
10317
+ timeoutHandle = setTimeout(() => resolve("timeout"), teardownTimeoutMs);
10318
+ timeoutHandle.unref?.();
10319
+ });
10320
+ await Promise.race([renderer.closed.then(() => "closed", () => "rejected"), timeout]);
10321
+ } finally {
10322
+ if (timeoutHandle) clearTimeout(timeoutHandle);
10323
+ }
10324
+ }
10256
10325
  const finished = !destroyThrew && renderer.isDestroyed;
10257
10326
  if (!finished) {
10258
10327
  try {
@@ -10741,6 +10810,7 @@ function repoLabel(key) {
10741
10810
  * repaints with each picker preview swap for free — no props, no state.
10742
10811
  */
10743
10812
  function ThemePreview() {
10813
+ const renderer = useRenderer();
10744
10814
  return /* @__PURE__ */ jsxs("box", {
10745
10815
  style: {
10746
10816
  flexDirection: "column",
@@ -10789,7 +10859,7 @@ function ThemePreview() {
10789
10859
  "}",
10790
10860
  "```"
10791
10861
  ].join("\n"),
10792
- syntaxStyle: syntaxStyle(),
10862
+ syntaxStyle: syntaxStyle(renderer),
10793
10863
  fg: theme.assistant,
10794
10864
  conceal: true
10795
10865
  }),
@@ -11510,6 +11580,7 @@ function reviewSourceContentWidth(width) {
11510
11580
  }
11511
11581
  /** Shared source row for Changes diffs and Files full-content previews. */
11512
11582
  function ReviewSourceRow({ file, row, cursor, selected, commented, width }) {
11583
+ const renderer = useRenderer();
11513
11584
  const palette = diffPalette();
11514
11585
  const semanticBg = row.kind === "add" ? palette?.addedLineBg : row.kind === "del" ? palette?.removedLineBg : void 0;
11515
11586
  const bg = cursor ? blendHex(theme.fg, theme.surface, .22) : selected ? blendHex(theme.fg, theme.surface, .12) : semanticBg;
@@ -11557,7 +11628,7 @@ function ReviewSourceRow({ file, row, cursor, selected, commented, width }) {
11557
11628
  children: filetype ? /* @__PURE__ */ jsx("code", {
11558
11629
  content: row.text.length > 0 ? row.text : " ",
11559
11630
  filetype,
11560
- syntaxStyle: syntaxStyle(),
11631
+ syntaxStyle: syntaxStyle(renderer),
11561
11632
  fg: theme.fg,
11562
11633
  bg,
11563
11634
  width: contentWidth,
@@ -161,7 +161,7 @@ function errorMessage(err) {
161
161
  * the commit time of the built tree is one monotonic clock they share.
162
162
  */
163
163
  function portalDaemonBuild() {
164
- return "1792186901";
164
+ return "1792193118";
165
165
  }
166
166
  /**
167
167
  * Whether a client carrying `mine` should replace a running daemon carrying
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as PortalClient, r as RATE_LIMIT_STAND_DOWN_MS, t as AUTH_STAND_DOWN_MS } from "./client-DFizfTrs.mjs";
2
+ import { n as PortalClient, r as RATE_LIMIT_STAND_DOWN_MS, t as AUTH_STAND_DOWN_MS } from "./client-6HkECaQY.mjs";
3
3
  import "./api-BFQ4PQDA.mjs";
4
4
 
5
5
  export { PortalClient };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import "./client-DFizfTrs.mjs";
2
+ import "./client-6HkECaQY.mjs";
3
3
  import "./tls-cert-Rua2oV7n.mjs";
4
4
  import "./api-BFQ4PQDA.mjs";
5
- import { a as runPortalDaemon, c as stopDaemonForHandoff, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-YluL9ulI.mjs";
5
+ import { a as runPortalDaemon, c as stopDaemonForHandoff, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-Ds1su2WI.mjs";
6
6
 
7
7
  export { runPortalDaemon };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as portalDaemonBuild, i as isNewerBuild, n as PortalClient, o as isRecord } from "./client-DFizfTrs.mjs";
2
+ import { a as portalDaemonBuild, i as isNewerBuild, n as PortalClient, o as isRecord } from "./client-6HkECaQY.mjs";
3
3
  import { t as defaultTlsCertSource } from "./tls-cert-Rua2oV7n.mjs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import "./client-6HkECaQY.mjs";
3
+ import "./tls-cert-Rua2oV7n.mjs";
4
+ import "./api-BFQ4PQDA.mjs";
5
+ import "./daemon-Ds1su2WI.mjs";
6
+ import { t as PortalDaemonClient } from "./daemon-client-DJ7xcv1x.mjs";
7
+
8
+ export { PortalDaemonClient };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as daemonPaths, f as encodeLine, l as LOCAL_PROTOCOL_VERSION, m as parseDaemonMessage, n as ensureDaemonRunning, p as makeLineParser } from "./daemon-YluL9ulI.mjs";
2
+ import { d as daemonPaths, f as encodeLine, l as LOCAL_PROTOCOL_VERSION, m as parseDaemonMessage, n as ensureDaemonRunning, p as makeLineParser } from "./daemon-Ds1su2WI.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { connect } from "node:net";
5
5
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { c as version$1 } from "./rest-DOBahsht.mjs";
3
- import { D as getConfigPath } from "./print-DxSdcppI.mjs";
2
+ import { c as version$1 } from "./rest-BW0kOOf5.mjs";
3
+ import { D as getConfigPath } from "./print-Chf1MyJK.mjs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { err, ok } from "neverthrow";
@@ -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-DOBahsht.mjs";
2
+ import { a as errorMessage, i as sendErrorMessage, o as isRecord, t as createRestClient } from "./rest-BW0kOOf5.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";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./rest-DOBahsht.mjs";
3
- import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-DxSdcppI.mjs";
2
+ import "./rest-BW0kOOf5.mjs";
3
+ import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-Chf1MyJK.mjs";
4
4
  import "./billing-blocked-D3l5kJlX.mjs";
5
5
 
6
6
  export { messageGet, readStdin, resolveAgent, runPrint };
@@ -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-Ck07qFBr.mjs");
17
+ const { PortalClient } = await import("./client-C8rBz7ct.mjs");
18
18
  const { defaultTlsCertSource } = await import("./tls-cert-BpCaD5AT.mjs");
19
19
  let signalConnected;
20
20
  const connected = new Promise((resolve) => {
@@ -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.114";
9
+ var version = "0.6.0-beta.116";
10
10
 
11
11
  //#endregion
12
12
  //#region src/chat/util.ts
@@ -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-DOBahsht.mjs";
2
+ import { i as sendErrorMessage, n as errorDetail, r as filenameFromContentDisposition, t as createRestClient } from "./rest-BW0kOOf5.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.114",
3
+ "version": "0.6.0-beta.116",
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.10",
34
+ "@opentui/react": "0.6.6",
35
35
  "conf": "^13.0.1",
36
36
  "diff": "9.0.0",
37
37
  "eventsource-parser": "^3.0.8",
@@ -72,9 +72,9 @@
72
72
  },
73
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.",
74
74
  "optionalDependencies": {
75
- "skydive-cli-darwin-arm64": "0.6.0-beta.114",
76
- "skydive-cli-darwin-x64": "0.6.0-beta.114",
77
- "skydive-cli-linux-x64": "0.6.0-beta.114",
78
- "skydive-cli-linux-arm64": "0.6.0-beta.114"
75
+ "skydive-cli-darwin-arm64": "0.6.0-beta.116",
76
+ "skydive-cli-darwin-x64": "0.6.0-beta.116",
77
+ "skydive-cli-linux-x64": "0.6.0-beta.116",
78
+ "skydive-cli-linux-arm64": "0.6.0-beta.116"
79
79
  }
80
80
  }
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./client-DFizfTrs.mjs";
3
- import "./tls-cert-Rua2oV7n.mjs";
4
- import "./api-BFQ4PQDA.mjs";
5
- import "./daemon-YluL9ulI.mjs";
6
- import { t as PortalDaemonClient } from "./daemon-client-DOxEtaXg.mjs";
7
-
8
- export { PortalDaemonClient };