skydive-cli 0.4.0-beta.1141 → 0.4.0-beta.1174

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,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-C-hbIwXv.mjs";
3
- import { A as getStoredApiKeyWorkspaceName, C as getLastSeenVersion, F as resolveManagementAuth, I as resolveSession, M as resolveAppUrl, N as resolveChatAuth, O as getShareMachineDefault, P as resolveConfig, R as saveConfig, S as getConfigPath, T as getPromptHistoryPath, V as setLastSeenVersion, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getUpdateCheckDisabled, k as getStoredApiKeyId, v as DEFAULT_API_URL, w as getPreference, x as deleteConfig, z as saveSession } from "./print-CswnhVUN.mjs";
2
+ import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-TWHjJUji.mjs";
3
+ import { A as getStoredApiKeyWorkspaceName, C as getLastSeenVersion, F as resolveManagementAuth, I as resolveSession, M as resolveAppUrl, N as resolveChatAuth, O as getShareMachineDefault, P as resolveConfig, R as saveConfig, S as getConfigPath, T as getPromptHistoryPath, V as setLastSeenVersion, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getUpdateCheckDisabled, k as getStoredApiKeyId, v as DEFAULT_API_URL, w as getPreference, x as deleteConfig, z as saveSession } from "./print-DA8WzgzH.mjs";
4
4
  import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
5
- import { n as createRestClient, t as HttpError } from "./rest-CG7VpQ56.mjs";
5
+ import { n as createRestClient, t as HttpError } from "./rest-CtEF_ZDf.mjs";
6
6
  import "./billing-blocked-CwfG1BTR.mjs";
7
- import { a as registerPortalDevice, i as grantPortalAccess, n as fetchPortalDevices, o as revokePortalAccess, r as findThisDevice, s as machineIdentity } from "./client-DiaJZQG6.mjs";
8
- import { c as PORTAL_DAEMON_FLAG, i as queryDaemonStatus, l as daemonPaths, n as ensureDaemonRunning, o as stopDaemon } from "./daemon-BSSZpzto.mjs";
7
+ import { a as registerPortalDevice, i as grantPortalAccess, n as fetchPortalDevices, o as revokePortalAccess, r as findThisDevice, s as machineIdentity } from "./client-C5O0ZhxP.mjs";
8
+ import { c as PORTAL_DAEMON_FLAG, i as queryDaemonStatus, l as daemonPaths, n as ensureDaemonRunning, o as stopDaemon } from "./daemon-CgLbaJ9_.mjs";
9
9
  import { t as SandboxStream } from "./client-D8s9vY4p.mjs";
10
10
  import { hideBin } from "yargs/helpers";
11
11
  import yargs from "yargs";
@@ -1514,7 +1514,7 @@ const importCommand = {
1514
1514
  process.exit(1);
1515
1515
  }
1516
1516
  }
1517
- const { runChat } = await import("./boot-D1iX9oW1.mjs");
1517
+ const { runChat } = await import("./boot-DFFwwXGr.mjs");
1518
1518
  await runChat({
1519
1519
  appUrl,
1520
1520
  sessionToken: session.value.sessionToken,
@@ -1541,7 +1541,7 @@ async function runImportPrintMode({ argv, appUrl }) {
1541
1541
  printError(`${session.error.message} For non-interactive use, run \`skydive auth login --web\` first, or set SKYDIVE_SESSION_TOKEN.`);
1542
1542
  process.exit(1);
1543
1543
  }
1544
- const { connectMachineShare } = await import("./print-share-DCmeJC5e.mjs");
1544
+ const { connectMachineShare } = await import("./print-share-FHUrtd8x.mjs");
1545
1545
  const machineShare = await connectMachineShare({
1546
1546
  appUrl,
1547
1547
  sessionToken: session.value.sessionToken,
@@ -1549,7 +1549,7 @@ async function runImportPrintMode({ argv, appUrl }) {
1549
1549
  });
1550
1550
  const extra = (argv.print ?? "").trim();
1551
1551
  const prompt = buildImportSeedPrompt(process.cwd()) + (extra ? `\n\nAdditional instructions: ${extra}` : "");
1552
- const { runPrint } = await import("./print-LoJjA8FM.mjs");
1552
+ const { runPrint } = await import("./print-DwQoTays.mjs");
1553
1553
  try {
1554
1554
  const result = await runPrint({
1555
1555
  appUrl,
@@ -1926,7 +1926,7 @@ const chatCommand = {
1926
1926
  sessionToken: auth.value.token,
1927
1927
  agentSelector: argv.agent ?? null
1928
1928
  });
1929
- const { runChat } = await import("./boot-D1iX9oW1.mjs");
1929
+ const { runChat } = await import("./boot-DFFwwXGr.mjs");
1930
1930
  await runChat({
1931
1931
  appUrl: auth.value.appUrl,
1932
1932
  sessionToken: auth.value.token,
@@ -1993,7 +1993,7 @@ async function runPrintMode({ argv, appUrl }) {
1993
1993
  printError(`${auth.error.message} For non-interactive use, run \`skydive auth login\` first, or set SKYDIVE_API_KEY / SKYDIVE_SESSION_TOKEN.`);
1994
1994
  process.exit(1);
1995
1995
  }
1996
- const { runPrint, readStdin } = await import("./print-LoJjA8FM.mjs");
1996
+ const { runPrint, readStdin } = await import("./print-DwQoTays.mjs");
1997
1997
  await ensureAgentWorkspace({
1998
1998
  appUrl,
1999
1999
  sessionToken: auth.value.token,
@@ -2018,7 +2018,7 @@ async function runPrintMode({ argv, appUrl }) {
2018
2018
  process.exit(1);
2019
2019
  }
2020
2020
  } else {
2021
- const { connectMachineShare } = await import("./print-share-DCmeJC5e.mjs");
2021
+ const { connectMachineShare } = await import("./print-share-FHUrtd8x.mjs");
2022
2022
  machineShare = await connectMachineShare({
2023
2023
  appUrl: auth.value.appUrl,
2024
2024
  sessionToken: auth.value.token,
@@ -2082,7 +2082,7 @@ const getCommand$1 = {
2082
2082
  printError(`${auth.error.message} Run \`skydive auth login\` first, or set SKYDIVE_API_KEY / SKYDIVE_SESSION_TOKEN.`);
2083
2083
  process.exit(1);
2084
2084
  }
2085
- const { messageGet } = await import("./print-LoJjA8FM.mjs");
2085
+ const { messageGet } = await import("./print-DwQoTays.mjs");
2086
2086
  try {
2087
2087
  const result = await messageGet({
2088
2088
  appUrl: auth.value.appUrl,
@@ -2285,7 +2285,7 @@ const switchCommand = {
2285
2285
  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.");
2286
2286
  process.exit(1);
2287
2287
  }
2288
- const { runWorkspacePicker } = await import("./boot-D1iX9oW1.mjs");
2288
+ const { runWorkspacePicker } = await import("./boot-DFFwwXGr.mjs");
2289
2289
  await runWorkspacePicker(session);
2290
2290
  return;
2291
2291
  }
@@ -2363,7 +2363,7 @@ const openCommand = {
2363
2363
  const agent = argv.agent ? resolveAgent((await fetchPortalDevices(session)).agents, argv.agent) : null;
2364
2364
  const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
2365
2365
  const { machineName } = machineIdentity();
2366
- const { PortalClient } = await import("./client-BpAnESuq.mjs");
2366
+ const { PortalClient } = await import("./client-BhdMLYEe.mjs");
2367
2367
  let lastLine = "";
2368
2368
  let signalConnected;
2369
2369
  const connected = new Promise((resolve) => {
@@ -2636,8 +2636,8 @@ const sandboxCommand = {
2636
2636
  }).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`"),
2637
2637
  handler: async (argv) => {
2638
2638
  const session = requireSession(argv);
2639
- const { createRestClient } = await import("./rest-DfpoRJ_Q.mjs");
2640
- const { resolveAgent } = await import("./print-LoJjA8FM.mjs");
2639
+ const { createRestClient } = await import("./rest-aXwyxWX0.mjs");
2640
+ const { resolveAgent } = await import("./print-DwQoTays.mjs");
2641
2641
  const client = createRestClient({
2642
2642
  appUrl: session.appUrl,
2643
2643
  sessionToken: session.sessionToken
@@ -3896,7 +3896,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
3896
3896
  process.exit(0);
3897
3897
  }
3898
3898
  if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
3899
- const { runPortalDaemon } = await import("./daemon-ybnlDUgi.mjs");
3899
+ const { runPortalDaemon } = await import("./daemon-qBD3Zd-l.mjs");
3900
3900
  runPortalDaemon(process.argv);
3901
3901
  } else runCli();
3902
3902
  function runCli() {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-C-hbIwXv.mjs";
3
- import { B as saveTheme, D as getSavedTheme, E as getReviewStateDir, L as resolveWebUrl, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL } from "./print-CswnhVUN.mjs";
4
- import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-CG7VpQ56.mjs";
2
+ import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-TWHjJUji.mjs";
3
+ import { B as saveTheme, D as getSavedTheme, E as getReviewStateDir, L as resolveWebUrl, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL } from "./print-DA8WzgzH.mjs";
4
+ import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-CtEF_ZDf.mjs";
5
5
  import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-CwfG1BTR.mjs";
6
- import { t as PortalClient } from "./client-DiaJZQG6.mjs";
7
- import { d as makeLineParser, f as parseDaemonMessage, l as daemonPaths, n as ensureDaemonRunning, s as LOCAL_PROTOCOL_VERSION, u as encodeLine } from "./daemon-BSSZpzto.mjs";
6
+ import { t as PortalClient } from "./client-C5O0ZhxP.mjs";
7
+ import { d as makeLineParser, f as parseDaemonMessage, l as daemonPaths, n as ensureDaemonRunning, s as LOCAL_PROTOCOL_VERSION, u as encodeLine } from "./daemon-CgLbaJ9_.mjs";
8
8
  import { t as SandboxStream } from "./client-D8s9vY4p.mjs";
9
9
  import { t as runRawPtyPassthrough } from "./raw-pty-DAmb8uqt.mjs";
10
10
  import * as os$1 from "node:os";
@@ -4223,6 +4223,292 @@ function parseMatches(output) {
4223
4223
  return null;
4224
4224
  }
4225
4225
 
4226
+ //#endregion
4227
+ //#region src/chat/tui/chat/conversation-context.tsx
4228
+ const ConversationContext = createContext({
4229
+ rest: null,
4230
+ conversationId: null
4231
+ });
4232
+ function useConversationContext() {
4233
+ return useContext(ConversationContext);
4234
+ }
4235
+
4236
+ //#endregion
4237
+ //#region src/chat/tui/spinner-frames.ts
4238
+ /** Braille dot-cycle frames — the classic smooth terminal spinner. */
4239
+ const SPINNER_FRAMES = [
4240
+ "⠋",
4241
+ "⠙",
4242
+ "⠹",
4243
+ "⠸",
4244
+ "⠼",
4245
+ "⠴",
4246
+ "⠦",
4247
+ "⠧",
4248
+ "⠇",
4249
+ "⠏"
4250
+ ];
4251
+ /** Milliseconds between frames. ~12.5fps reads as smooth without thrashing. */
4252
+ const SPINNER_INTERVAL_MS = 80;
4253
+ /** Frame for a given tick count. Wraps at the end of the cycle; negative-safe. */
4254
+ function spinnerFrame(tick) {
4255
+ const n = SPINNER_FRAMES.length;
4256
+ return SPINNER_FRAMES[(Math.trunc(tick) % n + n) % n] ?? SPINNER_FRAMES[0];
4257
+ }
4258
+
4259
+ //#endregion
4260
+ //#region src/chat/tui/spinner.tsx
4261
+ /**
4262
+ * An animated spinner glyph. Advances one frame every SPINNER_INTERVAL_MS via
4263
+ * a self-owned interval that's cleared on unmount, so the animation runs only
4264
+ * while the component is mounted. Returns a <span>, so render it inside a
4265
+ * <text> (matching how the rest of the TUI composes inline glyphs).
4266
+ */
4267
+ function Spinner({ color }) {
4268
+ const [tick, setTick] = useState(0);
4269
+ useEffect(() => {
4270
+ const id = setInterval(() => setTick((t) => t + 1), SPINNER_INTERVAL_MS);
4271
+ return () => clearInterval(id);
4272
+ }, []);
4273
+ return /* @__PURE__ */ jsx("span", {
4274
+ fg: color,
4275
+ children: spinnerFrame(tick)
4276
+ });
4277
+ }
4278
+
4279
+ //#endregion
4280
+ //#region src/chat/tui/chat/subagents.ts
4281
+ /** A run the platform hasn't settled yet — still queued or mid-run. */
4282
+ function isLiveStatus(status) {
4283
+ return status === "queued" || status === "running";
4284
+ }
4285
+ function toTaskStatus(raw) {
4286
+ switch (raw) {
4287
+ case "queued":
4288
+ case "running":
4289
+ case "completed":
4290
+ case "failed":
4291
+ case "canceled": return raw;
4292
+ default: return "queued";
4293
+ }
4294
+ }
4295
+ const FALLBACK_TITLE = "Subagent task";
4296
+ /**
4297
+ * Each delegated task's display title from the `subagent` call's input, in
4298
+ * call order — the short name the tool requires per task. A malformed entry
4299
+ * yields a fallback label rather than being dropped, so the row count always
4300
+ * matches the fan-out width. Mirrors the web client's `subagentTaskTitles`.
4301
+ */
4302
+ function subagentTaskTitles(input) {
4303
+ if (!isRecord(input)) return [];
4304
+ const tasks = input["tasks"];
4305
+ if (!Array.isArray(tasks)) return [];
4306
+ return tasks.map((task) => {
4307
+ if (!isRecord(task)) return FALLBACK_TITLE;
4308
+ const title = task["title"];
4309
+ return typeof title === "string" && title.trim() ? title.trim() : FALLBACK_TITLE;
4310
+ });
4311
+ }
4312
+ const QUEUED_TASK_ID_LINE = /^\s*-\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}):\s/i;
4313
+ /**
4314
+ * The ids of the runs a `subagent` call queued, read back out of its own
4315
+ * output. The call returns the moment the runs exist, so the ids are there
4316
+ * long before any child finishes — they are what ties this card to the task
4317
+ * rows the status poll returns, and their order is the tasks' call order.
4318
+ */
4319
+ function queuedSubagentTaskIds(output) {
4320
+ const text = flattenOutputText(output);
4321
+ if (!text) return [];
4322
+ return text.split("\n").map((line) => line.match(QUEUED_TASK_ID_LINE)?.[1] ?? null).filter((id) => id !== null);
4323
+ }
4324
+ /**
4325
+ * Tool output reaches the TUI as `unknown`: the raw string live, possibly
4326
+ * wrapped in content parts or arrays when loaded from history. Walk it for
4327
+ * string leaves, newline-joined — the PR scanner's `stringifyToolOutput`
4328
+ * shape, bounded small because the id list sits at the top of the output.
4329
+ */
4330
+ function flattenOutputText(value) {
4331
+ const MAX_LEN = 2e4;
4332
+ const parts = [];
4333
+ let total = 0;
4334
+ const visit = (v, depth) => {
4335
+ if (total >= MAX_LEN || depth > 4) return;
4336
+ if (typeof v === "string") {
4337
+ parts.push(v);
4338
+ total += v.length;
4339
+ return;
4340
+ }
4341
+ if (Array.isArray(v)) {
4342
+ for (const item of v) visit(item, depth + 1);
4343
+ return;
4344
+ }
4345
+ if (isRecord(v)) for (const item of Object.values(v)) visit(item, depth + 1);
4346
+ };
4347
+ visit(value, 0);
4348
+ return parts.join("\n");
4349
+ }
4350
+ /**
4351
+ * The card's rows: one per queued run id (call order), each carrying the
4352
+ * freshest known state. A task the status fetch hasn't returned yet falls
4353
+ * back to the input's title and reads as queued; a fetched row's own title
4354
+ * wins over the input's (the server's copy is the one the child actually
4355
+ * ran under). Before the ids exist — the call is still streaming — rows come
4356
+ * from the input titles alone, so the card never renders empty mid-turn.
4357
+ */
4358
+ function subagentRows({ titles, ids, fetched }) {
4359
+ if (ids.length === 0) return titles.map((title, index) => ({
4360
+ id: `queued:${index}`,
4361
+ title,
4362
+ status: "queued",
4363
+ createdAt: null,
4364
+ completedAt: null
4365
+ }));
4366
+ return ids.map((id, index) => {
4367
+ const row = fetched?.get(id) ?? null;
4368
+ return {
4369
+ id,
4370
+ title: row?.title ?? titles[index] ?? FALLBACK_TITLE,
4371
+ status: row ? toTaskStatus(row.status) : "queued",
4372
+ createdAt: row?.createdAt ?? null,
4373
+ completedAt: row?.completedAt ?? null
4374
+ };
4375
+ });
4376
+ }
4377
+
4378
+ //#endregion
4379
+ //#region src/chat/tui/chunks/tool-subagent.tsx
4380
+ /** How often a live batch re-reads its tasks' status. */
4381
+ const POLL_INTERVAL_MS = 3e3;
4382
+ function rowGlyph(status) {
4383
+ switch (status) {
4384
+ case "completed": return {
4385
+ ch: "✔",
4386
+ fg: theme.success
4387
+ };
4388
+ case "failed":
4389
+ case "canceled": return {
4390
+ ch: "✗",
4391
+ fg: theme.error
4392
+ };
4393
+ case "running": return {
4394
+ ch: "▶",
4395
+ fg: theme.accent
4396
+ };
4397
+ case "queued": return {
4398
+ ch: "○",
4399
+ fg: theme.dim
4400
+ };
4401
+ }
4402
+ }
4403
+ function rowColor$1(status) {
4404
+ switch (status) {
4405
+ case "running": return theme.fg;
4406
+ case "completed": return theme.dim;
4407
+ default: return theme.muted;
4408
+ }
4409
+ }
4410
+ function headerLabel(rows) {
4411
+ const subject = rows.length === 1 ? "Subagent" : `${rows.length} subagents`;
4412
+ return rows.some((row) => isLiveStatus(row.status)) ? `${subject} running` : subject;
4413
+ }
4414
+ /**
4415
+ * The transcript block for a `subagent` tool call — the TUI analog of the web
4416
+ * chat's fan-out card. One row per delegated run: status glyph, the short
4417
+ * title the delegating agent wrote, ticking over live as children settle.
4418
+ *
4419
+ * Rows are seeded from the call itself (titles from its input, task ids from
4420
+ * its own output), so the card renders the moment the call does. Status then
4421
+ * comes from the server's task rows, polled while any run is live — the
4422
+ * delegated runs outlive the call that spawned them, so the transcript stream
4423
+ * carries nothing more about them. The poll stops the moment the batch
4424
+ * settles; reopening an old conversation does one fetch and stops there. A
4425
+ * failed poll is skipped silently (the next tick retries; stale rows beat an
4426
+ * error row in the scrollback).
4427
+ */
4428
+ function ToolSubagent({ item }) {
4429
+ const { rest, conversationId } = useConversationContext();
4430
+ const titles = subagentTaskTitles(item.input);
4431
+ const ids = item.output?.kind === "ok" ? queuedSubagentTaskIds(item.output.value) : [];
4432
+ const idsKey = ids.join(",");
4433
+ const [fetched, setFetched] = useState(null);
4434
+ const rows = subagentRows({
4435
+ titles,
4436
+ ids,
4437
+ fetched
4438
+ });
4439
+ const live = rows.length === 0 || rows.some((row) => isLiveStatus(row.status));
4440
+ useEffect(() => {
4441
+ if (!rest || !conversationId || idsKey.length === 0 || !live) return;
4442
+ let cancelled = false;
4443
+ let timer = null;
4444
+ const tick = async () => {
4445
+ try {
4446
+ const tasks = await rest.listSubagentTasks({ conversationId });
4447
+ if (cancelled) return;
4448
+ setFetched(tasks);
4449
+ } catch (_error) {}
4450
+ if (!cancelled) timer = setTimeout(tick, POLL_INTERVAL_MS);
4451
+ };
4452
+ tick();
4453
+ return () => {
4454
+ cancelled = true;
4455
+ if (timer !== null) clearTimeout(timer);
4456
+ };
4457
+ }, [
4458
+ rest,
4459
+ conversationId,
4460
+ idsKey,
4461
+ live
4462
+ ]);
4463
+ if (rows.length === 0) return /* @__PURE__ */ jsxs("text", { children: [/* @__PURE__ */ jsx("span", {
4464
+ fg: theme.warning,
4465
+ children: "◐ "
4466
+ }), /* @__PURE__ */ jsx("span", {
4467
+ fg: theme.tool,
4468
+ children: "Delegating to subagents…"
4469
+ })] });
4470
+ return /* @__PURE__ */ jsxs("box", {
4471
+ style: { flexDirection: "column" },
4472
+ children: [/* @__PURE__ */ jsxs("text", { children: [
4473
+ live ? /* @__PURE__ */ jsx(Spinner, { color: theme.accent }) : /* @__PURE__ */ jsx("span", {
4474
+ fg: theme.success,
4475
+ children: "✓"
4476
+ }),
4477
+ /* @__PURE__ */ jsxs("span", {
4478
+ fg: theme.tool,
4479
+ children: [" ", /* @__PURE__ */ jsx("b", { children: headerLabel(rows) })]
4480
+ }),
4481
+ /* @__PURE__ */ jsxs("span", {
4482
+ fg: theme.dim,
4483
+ children: [
4484
+ " ",
4485
+ rows.filter((row) => row.status === "completed").length,
4486
+ "/",
4487
+ rows.length
4488
+ ]
4489
+ })
4490
+ ] }), /* @__PURE__ */ jsx("box", {
4491
+ style: {
4492
+ flexDirection: "column",
4493
+ paddingLeft: 2
4494
+ },
4495
+ children: rows.map((row) => {
4496
+ const glyph = rowGlyph(row.status);
4497
+ return /* @__PURE__ */ jsxs("box", {
4498
+ style: { flexDirection: "row" },
4499
+ children: [/* @__PURE__ */ jsxs("text", {
4500
+ fg: glyph.fg,
4501
+ children: [glyph.ch, " "]
4502
+ }), /* @__PURE__ */ jsx("text", {
4503
+ fg: rowColor$1(row.status),
4504
+ children: row.title
4505
+ })]
4506
+ }, row.id);
4507
+ })
4508
+ })]
4509
+ });
4510
+ }
4511
+
4226
4512
  //#endregion
4227
4513
  //#region src/chat/tui/chunks/shell-local.tsx
4228
4514
  /**
@@ -4446,6 +4732,7 @@ function ToolItem({ item }) {
4446
4732
  case "read": return /* @__PURE__ */ jsx(ToolRead, { item });
4447
4733
  case "grep":
4448
4734
  case "glob": return /* @__PURE__ */ jsx(ToolGrep, { item });
4735
+ case "subagent": return /* @__PURE__ */ jsx(ToolSubagent, { item });
4449
4736
  default: return /* @__PURE__ */ jsx(ToolGeneric, { item });
4450
4737
  }
4451
4738
  }
@@ -4615,6 +4902,270 @@ function clampItem(item) {
4615
4902
  }
4616
4903
  }
4617
4904
 
4905
+ //#endregion
4906
+ //#region src/chat/tui/chat/fix-json.ts
4907
+ /**
4908
+ * Implemented as a scanner with additional fixing
4909
+ * that performs a single linear time scan pass over the partial JSON.
4910
+ *
4911
+ * The states should ideally match relevant states from the JSON spec:
4912
+ * https://www.json.org/json-en.html
4913
+ *
4914
+ * Please note that invalid JSON is not considered/covered, because it
4915
+ * is assumed that the resulting JSON will be processed by a standard
4916
+ * JSON parser that will detect any invalid JSON.
4917
+ */
4918
+ function fixJson(input) {
4919
+ const stack = ["ROOT"];
4920
+ let lastValidIndex = -1;
4921
+ let literalStart = null;
4922
+ function processValueStart(char, i, swapState) {
4923
+ switch (char) {
4924
+ case "\"":
4925
+ lastValidIndex = i;
4926
+ stack.pop();
4927
+ stack.push(swapState);
4928
+ stack.push("INSIDE_STRING");
4929
+ break;
4930
+ case "f":
4931
+ case "t":
4932
+ case "n":
4933
+ lastValidIndex = i;
4934
+ literalStart = i;
4935
+ stack.pop();
4936
+ stack.push(swapState);
4937
+ stack.push("INSIDE_LITERAL");
4938
+ break;
4939
+ case "-":
4940
+ stack.pop();
4941
+ stack.push(swapState);
4942
+ stack.push("INSIDE_NUMBER");
4943
+ break;
4944
+ case "0":
4945
+ case "1":
4946
+ case "2":
4947
+ case "3":
4948
+ case "4":
4949
+ case "5":
4950
+ case "6":
4951
+ case "7":
4952
+ case "8":
4953
+ case "9":
4954
+ lastValidIndex = i;
4955
+ stack.pop();
4956
+ stack.push(swapState);
4957
+ stack.push("INSIDE_NUMBER");
4958
+ break;
4959
+ case "{":
4960
+ lastValidIndex = i;
4961
+ stack.pop();
4962
+ stack.push(swapState);
4963
+ stack.push("INSIDE_OBJECT_START");
4964
+ break;
4965
+ case "[":
4966
+ lastValidIndex = i;
4967
+ stack.pop();
4968
+ stack.push(swapState);
4969
+ stack.push("INSIDE_ARRAY_START");
4970
+ break;
4971
+ }
4972
+ }
4973
+ function processAfterObjectValue(char, i) {
4974
+ switch (char) {
4975
+ case ",":
4976
+ stack.pop();
4977
+ stack.push("INSIDE_OBJECT_AFTER_COMMA");
4978
+ break;
4979
+ case "}":
4980
+ lastValidIndex = i;
4981
+ stack.pop();
4982
+ break;
4983
+ }
4984
+ }
4985
+ function processAfterArrayValue(char, i) {
4986
+ switch (char) {
4987
+ case ",":
4988
+ stack.pop();
4989
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
4990
+ break;
4991
+ case "]":
4992
+ lastValidIndex = i;
4993
+ stack.pop();
4994
+ break;
4995
+ }
4996
+ }
4997
+ for (let i = 0; i < input.length; i++) {
4998
+ const char = input[i];
4999
+ if (!char) continue;
5000
+ switch (stack[stack.length - 1]) {
5001
+ case "ROOT":
5002
+ processValueStart(char, i, "FINISH");
5003
+ break;
5004
+ case "INSIDE_OBJECT_START":
5005
+ switch (char) {
5006
+ case "\"":
5007
+ stack.pop();
5008
+ stack.push("INSIDE_OBJECT_KEY");
5009
+ break;
5010
+ case "}":
5011
+ lastValidIndex = i;
5012
+ stack.pop();
5013
+ break;
5014
+ }
5015
+ break;
5016
+ case "INSIDE_OBJECT_AFTER_COMMA":
5017
+ switch (char) {
5018
+ case "\"":
5019
+ stack.pop();
5020
+ stack.push("INSIDE_OBJECT_KEY");
5021
+ break;
5022
+ }
5023
+ break;
5024
+ case "INSIDE_OBJECT_KEY":
5025
+ switch (char) {
5026
+ case "\"":
5027
+ stack.pop();
5028
+ stack.push("INSIDE_OBJECT_AFTER_KEY");
5029
+ break;
5030
+ }
5031
+ break;
5032
+ case "INSIDE_OBJECT_AFTER_KEY":
5033
+ switch (char) {
5034
+ case ":":
5035
+ stack.pop();
5036
+ stack.push("INSIDE_OBJECT_BEFORE_VALUE");
5037
+ break;
5038
+ }
5039
+ break;
5040
+ case "INSIDE_OBJECT_BEFORE_VALUE":
5041
+ processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
5042
+ break;
5043
+ case "INSIDE_OBJECT_AFTER_VALUE":
5044
+ processAfterObjectValue(char, i);
5045
+ break;
5046
+ case "INSIDE_STRING":
5047
+ switch (char) {
5048
+ case "\"":
5049
+ stack.pop();
5050
+ lastValidIndex = i;
5051
+ break;
5052
+ case "\\":
5053
+ stack.push("INSIDE_STRING_ESCAPE");
5054
+ break;
5055
+ default: lastValidIndex = i;
5056
+ }
5057
+ break;
5058
+ case "INSIDE_ARRAY_START":
5059
+ switch (char) {
5060
+ case "]":
5061
+ lastValidIndex = i;
5062
+ stack.pop();
5063
+ break;
5064
+ default:
5065
+ lastValidIndex = i;
5066
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
5067
+ break;
5068
+ }
5069
+ break;
5070
+ case "INSIDE_ARRAY_AFTER_VALUE":
5071
+ switch (char) {
5072
+ case ",":
5073
+ stack.pop();
5074
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
5075
+ break;
5076
+ case "]":
5077
+ lastValidIndex = i;
5078
+ stack.pop();
5079
+ break;
5080
+ default:
5081
+ lastValidIndex = i;
5082
+ break;
5083
+ }
5084
+ break;
5085
+ case "INSIDE_ARRAY_AFTER_COMMA":
5086
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
5087
+ break;
5088
+ case "INSIDE_STRING_ESCAPE":
5089
+ stack.pop();
5090
+ lastValidIndex = i;
5091
+ break;
5092
+ case "INSIDE_NUMBER":
5093
+ switch (char) {
5094
+ case "0":
5095
+ case "1":
5096
+ case "2":
5097
+ case "3":
5098
+ case "4":
5099
+ case "5":
5100
+ case "6":
5101
+ case "7":
5102
+ case "8":
5103
+ case "9":
5104
+ lastValidIndex = i;
5105
+ break;
5106
+ case "e":
5107
+ case "E":
5108
+ case "-":
5109
+ case ".": break;
5110
+ case ",":
5111
+ stack.pop();
5112
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
5113
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
5114
+ break;
5115
+ case "}":
5116
+ stack.pop();
5117
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
5118
+ break;
5119
+ case "]":
5120
+ stack.pop();
5121
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
5122
+ break;
5123
+ default:
5124
+ stack.pop();
5125
+ break;
5126
+ }
5127
+ break;
5128
+ case "INSIDE_LITERAL": {
5129
+ if (!literalStart) continue;
5130
+ const partialLiteral = input.substring(literalStart, i + 1);
5131
+ if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
5132
+ stack.pop();
5133
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i);
5134
+ else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
5135
+ } else lastValidIndex = i;
5136
+ break;
5137
+ }
5138
+ }
5139
+ }
5140
+ let result = input.slice(0, lastValidIndex + 1);
5141
+ for (let i = stack.length - 1; i >= 0; i--) switch (stack[i]) {
5142
+ case "INSIDE_STRING":
5143
+ result += "\"";
5144
+ break;
5145
+ case "INSIDE_OBJECT_KEY":
5146
+ case "INSIDE_OBJECT_AFTER_KEY":
5147
+ case "INSIDE_OBJECT_AFTER_COMMA":
5148
+ case "INSIDE_OBJECT_START":
5149
+ case "INSIDE_OBJECT_BEFORE_VALUE":
5150
+ case "INSIDE_OBJECT_AFTER_VALUE":
5151
+ result += "}";
5152
+ break;
5153
+ case "INSIDE_ARRAY_START":
5154
+ case "INSIDE_ARRAY_AFTER_COMMA":
5155
+ case "INSIDE_ARRAY_AFTER_VALUE":
5156
+ result += "]";
5157
+ break;
5158
+ case "INSIDE_LITERAL": {
5159
+ if (!literalStart) continue;
5160
+ const partialLiteral = input.substring(literalStart, input.length);
5161
+ if ("true".startsWith(partialLiteral)) result += "true".slice(partialLiteral.length);
5162
+ else if ("false".startsWith(partialLiteral)) result += "false".slice(partialLiteral.length);
5163
+ else if ("null".startsWith(partialLiteral)) result += "null".slice(partialLiteral.length);
5164
+ }
5165
+ }
5166
+ return result;
5167
+ }
5168
+
4618
5169
  //#endregion
4619
5170
  //#region src/chat/tui/chat/reducer.ts
4620
5171
  function str(chunk, key) {
@@ -4622,6 +5173,24 @@ function str(chunk, key) {
4622
5173
  return typeof value === "string" ? value : null;
4623
5174
  }
4624
5175
  /**
5176
+ * Best-effort parse of a tool call's partial arguments while they stream.
5177
+ * `fixJson` (the vercel/ai scanner) closes off the truncated JSON so a
5178
+ * half-arrived `{"command":"npm ins` parses to `{ command: 'npm ins' }`,
5179
+ * letting the renderers show the structured input filling in live rather
5180
+ * than a raw JSON fragment. Returns null until enough has arrived to parse
5181
+ * (or when the text isn't an object/array), so callers keep their raw
5182
+ * `inputText` fallback for the first few characters.
5183
+ */
5184
+ function parsePartialInput(text) {
5185
+ const trimmed = text.trimStart();
5186
+ if (trimmed[0] !== "{" && trimmed[0] !== "[") return null;
5187
+ try {
5188
+ return JSON.parse(fixJson(text));
5189
+ } catch (_error) {
5190
+ return null;
5191
+ }
5192
+ }
5193
+ /**
4625
5194
  * `agentName` is the display name of the agent producing this run's stream.
4626
5195
  * It's stamped onto each assistant-origin item so a multi-agent conversation
4627
5196
  * can attribute live turns; pass null in a solo thread to leave items
@@ -4689,10 +5258,17 @@ function applyChunk(items, chunk, agentName = null) {
4689
5258
  const toolCallId = str(chunk, "toolCallId");
4690
5259
  const delta = str(chunk, "inputTextDelta") ?? str(chunk, "delta") ?? "";
4691
5260
  if (!toolCallId) return [...items];
4692
- return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
4693
- ...m,
4694
- inputText: m.inputText + delta
4695
- } : m);
5261
+ return items.map((m) => {
5262
+ if (m.kind !== "tool" || m.id !== toolCallId) return m;
5263
+ const inputText = m.inputText + delta;
5264
+ const parsed = parsePartialInput(inputText);
5265
+ const input = parsed == null ? null : clampPayload(parsed);
5266
+ return {
5267
+ ...m,
5268
+ inputText,
5269
+ input
5270
+ };
5271
+ });
4696
5272
  }
4697
5273
  case "tool-input-available": {
4698
5274
  const toolCallId = str(chunk, "toolCallId");
@@ -5497,49 +6073,6 @@ function createResponsePreview() {
5497
6073
  };
5498
6074
  }
5499
6075
 
5500
- //#endregion
5501
- //#region src/chat/tui/spinner-frames.ts
5502
- /** Braille dot-cycle frames — the classic smooth terminal spinner. */
5503
- const SPINNER_FRAMES = [
5504
- "⠋",
5505
- "⠙",
5506
- "⠹",
5507
- "⠸",
5508
- "⠼",
5509
- "⠴",
5510
- "⠦",
5511
- "⠧",
5512
- "⠇",
5513
- "⠏"
5514
- ];
5515
- /** Milliseconds between frames. ~12.5fps reads as smooth without thrashing. */
5516
- const SPINNER_INTERVAL_MS = 80;
5517
- /** Frame for a given tick count. Wraps at the end of the cycle; negative-safe. */
5518
- function spinnerFrame(tick) {
5519
- const n = SPINNER_FRAMES.length;
5520
- return SPINNER_FRAMES[(Math.trunc(tick) % n + n) % n] ?? SPINNER_FRAMES[0];
5521
- }
5522
-
5523
- //#endregion
5524
- //#region src/chat/tui/spinner.tsx
5525
- /**
5526
- * An animated spinner glyph. Advances one frame every SPINNER_INTERVAL_MS via
5527
- * a self-owned interval that's cleared on unmount, so the animation runs only
5528
- * while the component is mounted. Returns a <span>, so render it inside a
5529
- * <text> (matching how the rest of the TUI composes inline glyphs).
5530
- */
5531
- function Spinner({ color }) {
5532
- const [tick, setTick] = useState(0);
5533
- useEffect(() => {
5534
- const id = setInterval(() => setTick((t) => t + 1), SPINNER_INTERVAL_MS);
5535
- return () => clearInterval(id);
5536
- }, []);
5537
- return /* @__PURE__ */ jsx("span", {
5538
- fg: color,
5539
- children: spinnerFrame(tick)
5540
- });
5541
- }
5542
-
5543
6076
  //#endregion
5544
6077
  //#region src/chat/tui/prompt-history.ts
5545
6078
  /**
@@ -11188,6 +11721,10 @@ function ChatScreen({ agent, conversation }) {
11188
11721
  }
11189
11722
  });
11190
11723
  const hasPendingSteer = items.some((m) => m.kind === "pending-steer");
11724
+ const conversationContext = useMemo(() => ({
11725
+ rest,
11726
+ conversationId
11727
+ }), [rest, conversationId]);
11191
11728
  const actionableCards = useMemo(() => items.filter(isActionableCard), [items]);
11192
11729
  const statusText = useMemo(() => formatChatFooterStatus({
11193
11730
  runKind: run.kind,
@@ -11270,7 +11807,7 @@ function ChatScreen({ agent, conversation }) {
11270
11807
  setReviewFocused(false);
11271
11808
  }
11272
11809
  }) : null;
11273
- const chatView = /* @__PURE__ */ jsxs("box", {
11810
+ const chatViewBody = /* @__PURE__ */ jsxs("box", {
11274
11811
  onMouseDown: (event) => {
11275
11812
  const paneBox = reviewBelowBoxRef.current;
11276
11813
  if (reviewOpen && reviewPlacement === "below" && paneBox && event.y === paneBox.screenY + paneBox.height - 1) {
@@ -11560,6 +12097,10 @@ function ChatScreen({ agent, conversation }) {
11560
12097
  })
11561
12098
  ]
11562
12099
  });
12100
+ const chatView = /* @__PURE__ */ jsx(ConversationContext.Provider, {
12101
+ value: conversationContext,
12102
+ children: chatViewBody
12103
+ });
11563
12104
  if (!reviewView || reviewPlacement === "below") return chatView;
11564
12105
  const fullscreen = reviewPlacement === "fullscreen";
11565
12106
  return /* @__PURE__ */ jsxs("box", {
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import "./rest-CtEF_ZDf.mjs";
3
+ import "./billing-blocked-CwfG1BTR.mjs";
4
+ import { t as PortalClient } from "./client-C5O0ZhxP.mjs";
5
+
6
+ export { PortalClient };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, t as HttpError } from "./rest-CG7VpQ56.mjs";
2
+ import { a as errorMessage, t as HttpError } from "./rest-CtEF_ZDf.mjs";
3
3
  import os from "node:os";
4
4
  import { z } from "zod";
5
5
  import { spawn } from "node:child_process";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { o as isRecord } from "./rest-CG7VpQ56.mjs";
3
- import { t as PortalClient } from "./client-DiaJZQG6.mjs";
2
+ import { o as isRecord } from "./rest-CtEF_ZDf.mjs";
3
+ import { t as PortalClient } from "./client-C5O0ZhxP.mjs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { z } from "zod";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import "./rest-CG7VpQ56.mjs";
2
+ import "./rest-CtEF_ZDf.mjs";
3
3
  import "./billing-blocked-CwfG1BTR.mjs";
4
- import "./client-DiaJZQG6.mjs";
5
- import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as stopDaemon, r as isDaemonListening, t as PortalDaemon } from "./daemon-BSSZpzto.mjs";
4
+ import "./client-C5O0ZhxP.mjs";
5
+ import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as stopDaemon, r as isDaemonListening, t as PortalDaemon } from "./daemon-CgLbaJ9_.mjs";
6
6
 
7
7
  export { runPortalDaemon };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, t as HttpError } from "./rest-CG7VpQ56.mjs";
2
+ import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, t as HttpError } from "./rest-CtEF_ZDf.mjs";
3
3
  import { i as billingBlockedOutcomeFromSendResponse, n as BillingBlockedError } from "./billing-blocked-CwfG1BTR.mjs";
4
4
  import path from "node:path";
5
5
  import Conf from "conf";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-CswnhVUN.mjs";
3
- import "./rest-CG7VpQ56.mjs";
2
+ import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-DA8WzgzH.mjs";
3
+ import "./rest-CtEF_ZDf.mjs";
4
4
  import "./billing-blocked-CwfG1BTR.mjs";
5
5
 
6
6
  export { messageGet, readStdin, resolveAgent, runPrint };
@@ -14,7 +14,7 @@ import { n as printError } from "./output-DYzzdXYV.mjs";
14
14
  * the reply (and to --json).
15
15
  */
16
16
  async function connectMachineShare({ appUrl, sessionToken, timeoutHint }) {
17
- const { PortalClient } = await import("./client-BpAnESuq.mjs");
17
+ const { PortalClient } = await import("./client-BhdMLYEe.mjs");
18
18
  let signalConnected;
19
19
  const connected = new Promise((resolve) => {
20
20
  signalConnected = resolve;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { S as getConfigPath } from "./print-CswnhVUN.mjs";
2
+ import { S as getConfigPath } from "./print-DA8WzgzH.mjs";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { err, ok } from "neverthrow";
@@ -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.4.0-beta.1141";
11
+ var version$1 = "0.4.0-beta.1174";
12
12
 
13
13
  //#endregion
14
14
  //#region src/auth/organization.ts
@@ -294,6 +294,10 @@ function createRestClient({ appUrl, sessionToken, workspaceId }) {
294
294
  const { recap } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/recap`, recapResponseSchema);
295
295
  return recap?.text ?? null;
296
296
  },
297
+ listSubagentTasks: async ({ conversationId }) => {
298
+ const { result } = await get(`/api/v1/trpc/v2.subagentTasks.list?input=${encodeURIComponent(JSON.stringify({ conversationId }))}`, subagentTasksResponseSchema);
299
+ return new Map(result.data.subagentTasks.map((task) => [task.id, task]));
300
+ },
297
301
  uploadAttachment: async ({ agentId, fileName, mediaType, data }) => {
298
302
  const size = data.byteLength;
299
303
  const presign = await post("/api/v1/attachments/presign", {
@@ -530,6 +534,14 @@ const uiMessageSchema = z.object({
530
534
  }).passthrough().optional() }).passthrough().optional()
531
535
  });
532
536
  const recapResponseSchema = z.object({ recap: z.object({ text: z.string() }).nullable() });
537
+ const subagentTaskSnapshotSchema = z.object({
538
+ id: z.string(),
539
+ status: z.string(),
540
+ title: z.string().nullable(),
541
+ createdAt: z.string(),
542
+ completedAt: z.string().nullable()
543
+ });
544
+ const subagentTasksResponseSchema = z.object({ result: z.object({ data: z.object({ subagentTasks: z.array(subagentTaskSnapshotSchema) }) }) });
533
545
  const listMessagesResponseSchema = z.object({ messages: z.array(uiMessageSchema) });
534
546
  const workspaceFileSchema = z.object({
535
547
  id: z.string(),
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as sendErrorMessage, n as createRestClient, r as errorDetail, t as HttpError } from "./rest-CG7VpQ56.mjs";
2
+ import { i as sendErrorMessage, n as createRestClient, r as errorDetail, t as HttpError } from "./rest-CtEF_ZDf.mjs";
3
3
  import "./billing-blocked-CwfG1BTR.mjs";
4
4
 
5
5
  export { createRestClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skydive-cli",
3
- "version": "0.4.0-beta.1141",
3
+ "version": "0.4.0-beta.1174",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./rest-CG7VpQ56.mjs";
3
- import "./billing-blocked-CwfG1BTR.mjs";
4
- import { t as PortalClient } from "./client-DiaJZQG6.mjs";
5
-
6
- export { PortalClient };