skydive-cli 0.1.0-beta.378 → 0.1.0-beta.382

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
@@ -16,7 +16,7 @@ import zlib from "node:zlib";
16
16
  import { WebSocket } from "ws";
17
17
 
18
18
  //#region package.json
19
- var version$1 = "0.1.0-beta.378";
19
+ var version$1 = "0.1.0-beta.382";
20
20
 
21
21
  //#endregion
22
22
  //#region src/types.ts
@@ -138,6 +138,14 @@ function getPromptHistoryPath() {
138
138
  return path.join(path.dirname(store.path), "prompt-history.jsonl");
139
139
  }
140
140
  /**
141
+ * Where the chat TUI persists pending review comments — one JSON file per
142
+ * conversation, so a pending comment survives conversation switches and
143
+ * process death. Kept beside the config file like prompt history.
144
+ */
145
+ function getReviewStateDir() {
146
+ return path.join(path.dirname(store.path), "review");
147
+ }
148
+ /**
141
149
  * Resolve the chat/auth origin. Precedence: `SKYDIVE_APP_URL` env > explicit
142
150
  * `--api-url` style override > stored value > `SKYDIVE_API_URL` env >
143
151
  * `DEFAULT_APP_URL`.
@@ -1003,7 +1011,8 @@ const authCommand = {
1003
1011
  //#region src/chat/api/rest.ts
1004
1012
  var rest_exports = /* @__PURE__ */ __exportAll({
1005
1013
  HttpError: () => HttpError,
1006
- createRestClient: () => createRestClient
1014
+ createRestClient: () => createRestClient,
1015
+ errorDetail: () => errorDetail
1007
1016
  });
1008
1017
  var HttpError = class extends Error {
1009
1018
  constructor(status, body) {
@@ -1013,6 +1022,20 @@ var HttpError = class extends Error {
1013
1022
  this.name = "HttpError";
1014
1023
  }
1015
1024
  };
1025
+ const ERROR_DETAIL_MAX_BODY = 2e3;
1026
+ /**
1027
+ * Fullest renderable text for a thrown value. `HttpError.message` clips the
1028
+ * response body to 200 chars (it flows into logs and one-line UIs); the
1029
+ * transcript renders errors collapsed to a single line, so it can afford the
1030
+ * whole body — capped with an explicit marker, never cut silently.
1031
+ */
1032
+ function errorDetail(err) {
1033
+ if (err instanceof HttpError) {
1034
+ const body = err.body.length > ERROR_DETAIL_MAX_BODY ? `${err.body.slice(0, ERROR_DETAIL_MAX_BODY)}… (+${err.body.length - ERROR_DETAIL_MAX_BODY} chars)` : err.body;
1035
+ return body ? `HTTP ${err.status}: ${body}` : `HTTP ${err.status}`;
1036
+ }
1037
+ return err instanceof Error ? err.message : String(err);
1038
+ }
1016
1039
  const MAX_STREAM_RECONNECTS = 5;
1017
1040
  function createRestClient({ appUrl, sessionToken }) {
1018
1041
  const baseHeaders = {
@@ -1162,6 +1185,23 @@ function createRestClient({ appUrl, sessionToken }) {
1162
1185
  const { messages } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/messages`, listMessagesResponseSchema);
1163
1186
  return messages;
1164
1187
  },
1188
+ listWorkspaceFiles: async ({ agentId }) => {
1189
+ const { files } = await get(`/api/v1/workspace-files?${new URLSearchParams({ agentId }).toString()}`, listWorkspaceFilesResponseSchema);
1190
+ return files;
1191
+ },
1192
+ readWorkspaceFile: async ({ fileId, maxBytes = 512 * 1024 }) => {
1193
+ const res = await fetch(`${appUrl}/api/v1/workspace-files/${encodeURIComponent(fileId)}/download?disposition=inline`, { headers: {
1194
+ ...baseHeaders,
1195
+ Range: `bytes=0-${maxBytes}`
1196
+ } });
1197
+ if (!res.ok) throw new HttpError(res.status, await res.text().catch(() => ""));
1198
+ const bytes = new Uint8Array(await res.arrayBuffer());
1199
+ const truncated = bytes.byteLength > maxBytes;
1200
+ return {
1201
+ text: new TextDecoder().decode(bytes.subarray(0, maxBytes)),
1202
+ truncated
1203
+ };
1204
+ },
1165
1205
  getRecap: async ({ conversationId }) => {
1166
1206
  const { recap } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/recap`, recapResponseSchema);
1167
1207
  return recap?.text ?? null;
@@ -1373,6 +1413,16 @@ const uiMessageSchema = z.object({
1373
1413
  });
1374
1414
  const recapResponseSchema = z.object({ recap: z.object({ text: z.string() }).nullable() });
1375
1415
  const listMessagesResponseSchema = z.object({ messages: z.array(uiMessageSchema) });
1416
+ const workspaceFileSchema = z.object({
1417
+ id: z.string(),
1418
+ path: z.string(),
1419
+ mediaType: z.string(),
1420
+ sizeBytes: z.number(),
1421
+ contentHash: z.string(),
1422
+ updatedAt: z.string(),
1423
+ shareUrl: z.string()
1424
+ });
1425
+ const listWorkspaceFilesResponseSchema = z.object({ files: z.array(workspaceFileSchema) });
1376
1426
  const sendResultSchema = z.object({
1377
1427
  runId: z.string(),
1378
1428
  messageId: z.string().uuid().nullish(),
@@ -2778,7 +2828,7 @@ const chatCommand = {
2778
2828
  printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
2779
2829
  process.exit(1);
2780
2830
  }
2781
- const { runChat } = await import("./boot-QnNiy1cA.mjs");
2831
+ const { runChat } = await import("./boot-B48ty_OV.mjs");
2782
2832
  await runChat({
2783
2833
  appUrl,
2784
2834
  sessionToken: session.value.sessionToken,
@@ -3572,7 +3622,7 @@ const switchCommand = {
3572
3622
  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.");
3573
3623
  process.exit(1);
3574
3624
  }
3575
- const { runWorkspacePicker } = await import("./boot-QnNiy1cA.mjs");
3625
+ const { runWorkspacePicker } = await import("./boot-B48ty_OV.mjs");
3576
3626
  await runWorkspacePicker(session);
3577
3627
  return;
3578
3628
  }
@@ -3700,8 +3750,8 @@ async function portalFetch(auth, path, init) {
3700
3750
  ...init.body ? { body: init.body } : {}
3701
3751
  });
3702
3752
  if (!res.ok) {
3703
- const body = await res.text().then((text) => text.slice(0, 120)).catch(() => "");
3704
- throw new Error(`${init.method} ${path} failed (${res.status}): ${body}`);
3753
+ const body = await res.text().catch(() => "");
3754
+ throw new HttpError(res.status, body);
3705
3755
  }
3706
3756
  return res.json();
3707
3757
  }
@@ -4299,4 +4349,4 @@ function resolveArgv(args, tty = {
4299
4349
  createCli(resolveArgv(hideBin(process.argv))).parse();
4300
4350
 
4301
4351
  //#endregion
4302
- export { HttpError as A, saveTheme as B, noColorRequested as C, themeModeFromColorFgBg as D, themeMode as E, DEFAULT_API_URL as F, DEFAULT_APP_URL as I, getConfigPath as L, getActiveWorkspaceId as M, listWorkspaces as N, themeVersion as O, setActiveWorkspace as P, getSavedTheme as R, monoTheme as S, themeForMode as T, errorMessage as _, mintPortalDeviceToken as a, applyTheme as b, portalWsUrl as c, cardActionErrorMessage as d, parseExternalOauthConnectParams as f, parseConnectCard as g, resolveConnectUrl as h, grantPortalAccess as i, createRestClient as j, themesForMode as k, resolveAgent as l, reconcileMaskedInput as m, fetchPortalDevices as n, buildEnv as o, parseOauthConnectParams as p, findThisDevice as r, machineIdentity as s, SandboxStream as t, MASK_CHAR as u, isRecord as v, theme as w, findTheme as x, DEFAULT_THEME_ID as y, resolveWebUrl as z };
4352
+ export { HttpError as A, getSavedTheme as B, noColorRequested as C, themeModeFromColorFgBg as D, themeMode as E, setActiveWorkspace as F, saveTheme as H, DEFAULT_API_URL as I, DEFAULT_APP_URL as L, errorDetail as M, getActiveWorkspaceId as N, themeVersion as O, listWorkspaces as P, getConfigPath as R, monoTheme as S, themeForMode as T, resolveWebUrl as V, errorMessage as _, mintPortalDeviceToken as a, applyTheme as b, portalWsUrl as c, cardActionErrorMessage as d, parseExternalOauthConnectParams as f, parseConnectCard as g, resolveConnectUrl as h, grantPortalAccess as i, createRestClient as j, themesForMode as k, resolveAgent as l, reconcileMaskedInput as m, fetchPortalDevices as n, buildEnv as o, parseOauthConnectParams as p, findThisDevice as r, machineIdentity as s, SandboxStream as t, MASK_CHAR as u, isRecord as v, theme as w, findTheme as x, DEFAULT_THEME_ID as y, getReviewStateDir as z };