vibeview 0.34.0 → 0.35.0

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.
@@ -113,9 +113,10 @@ var NotFoundError = class extends Error {
113
113
  }
114
114
  };
115
115
  var ApiStatusError = class extends Error {
116
- constructor(status, message) {
116
+ constructor(status, message, data = null) {
117
117
  super(message);
118
118
  this.status = status;
119
+ this.data = data;
119
120
  this.name = "ApiStatusError";
120
121
  }
121
122
  };
@@ -129,12 +130,22 @@ function extractDetail(text) {
129
130
  try {
130
131
  const parsed = JSON.parse(text);
131
132
  if (parsed && typeof parsed.detail === "string") return parsed.detail;
132
- if (parsed && parsed.detail && typeof parsed.detail.message === "string")
133
- return parsed.detail.message;
133
+ if (parsed && parsed.detail && typeof parsed.detail.message === "string") {
134
+ const fix = parsed.detail.fix;
135
+ return typeof fix === "string" && fix.trim() ? `${parsed.detail.message} ${fix}` : parsed.detail.message;
136
+ }
134
137
  } catch {
135
138
  }
136
139
  return void 0;
137
140
  }
141
+ function extractDetailObject(text) {
142
+ try {
143
+ const detail = JSON.parse(text)?.detail;
144
+ if (detail && typeof detail === "object" && !Array.isArray(detail)) return detail;
145
+ } catch {
146
+ }
147
+ return null;
148
+ }
138
149
  function httpErrorMessage(status, text) {
139
150
  const body = text.trim();
140
151
  const looksLikeHtml = /^<(!doctype|html|head|body)\b/i.test(body) || /<\/html>\s*$/i.test(body);
@@ -192,7 +203,8 @@ var ApiClient = class {
192
203
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
193
204
  throw new ApiStatusError(
194
205
  resp.status,
195
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
206
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
207
+ extractDetailObject(text)
196
208
  );
197
209
  }
198
210
  return parseJsonBody(resp);
@@ -273,7 +285,8 @@ var ApiClient = class {
273
285
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
274
286
  throw new ApiStatusError(
275
287
  resp.status,
276
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
288
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
289
+ extractDetailObject(text)
277
290
  );
278
291
  }
279
292
  return parseJsonBody(resp);
@@ -297,7 +310,8 @@ var ApiClient = class {
297
310
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
298
311
  throw new ApiStatusError(
299
312
  resp.status,
300
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
313
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
314
+ extractDetailObject(text)
301
315
  );
302
316
  }
303
317
  return parseJsonBody(resp);
@@ -471,7 +485,8 @@ var ApiClient = class {
471
485
  throw new NotFoundError(`Not found: ${extractDetail(text) ?? `/builds/${id}/artifact`}`);
472
486
  throw new ApiStatusError(
473
487
  resp.status,
474
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
488
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
489
+ extractDetailObject(text)
475
490
  );
476
491
  }
477
492
  const rawFilename = parseContentDispositionFilename(resp.headers.get("content-disposition"));
@@ -891,7 +906,9 @@ async function uploadApp(filePath, options) {
891
906
  deduplicated: result.deduplicated === true,
892
907
  note: options.note?.trim() || null,
893
908
  url: `${baseUrl}/apps/${result.public_id}`,
894
- warnings: result.warnings ?? []
909
+ warnings: result.warnings ?? [],
910
+ compat_status: result.compat_status ?? null,
911
+ findings: result.findings ?? []
895
912
  },
896
913
  null,
897
914
  2
@@ -908,11 +925,36 @@ async function uploadApp(filePath, options) {
908
925
  console.log(chalk.dim(` ${baseUrl}/apps/${result.public_id}
909
926
  `));
910
927
  }
911
- for (const w of result.warnings ?? []) {
912
- console.error(chalk.yellow(`
928
+ const findings = result.findings ?? [];
929
+ if (findings.length) {
930
+ for (const f of findings) console.error(chalk.yellow(`
931
+ \u26A0 ${f.message}`) + `
932
+ ${f.fix}`);
933
+ } else {
934
+ for (const w of result.warnings ?? []) console.error(chalk.yellow(`
913
935
  \u26A0 ${w}`));
914
936
  }
915
937
  } catch (err) {
938
+ if (err instanceof ApiStatusError && err.status === 422 && err.data?.error === "build_refused") {
939
+ const findings = Array.isArray(err.data.findings) ? err.data.findings : [];
940
+ spinner.fail("Build refused: it cannot run on VibeView devices");
941
+ if (options.output === "json") {
942
+ const message2 = typeof err.data.message === "string" ? err.data.message : err.message;
943
+ console.log(JSON.stringify({ error: "build_refused", message: message2, findings }, null, 2));
944
+ } else {
945
+ for (const f of findings.filter((x) => x.severity === "refuse")) {
946
+ console.error(chalk.red(`
947
+ \u2716 ${f.message}`));
948
+ console.error(` ${f.fix}`);
949
+ }
950
+ console.error(
951
+ chalk.dim(
952
+ "\nThink this is a mistake? Email support@vibeview.io with the file name and we'll take a look."
953
+ )
954
+ );
955
+ }
956
+ process.exit(EXIT_TEST_FAIL);
957
+ }
916
958
  const message = err instanceof Error ? err.message : "Upload failed";
917
959
  spinner.fail(message);
918
960
  if (options.output === "json") console.error(chalk.red(`Error: ${message}`));
@@ -13,7 +13,7 @@ import {
13
13
  resolveArtifact,
14
14
  resolveAuth,
15
15
  uploadAppBuild
16
- } from "./chunk-4D2E2PE4.js";
16
+ } from "./chunk-QRJAFBH3.js";
17
17
 
18
18
  // src/lib/dev-config.ts
19
19
  import { readFileSync, renameSync, rmSync, writeFileSync } from "fs";
package/dist/cli.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  readDevStateFile,
25
25
  readMetroState,
26
26
  runAgentVerb
27
- } from "./chunk-TPZG7NCU.js";
27
+ } from "./chunk-Z6UVEAYO.js";
28
28
  import {
29
29
  ApiClient,
30
30
  ApiStatusError,
@@ -45,7 +45,7 @@ import {
45
45
  resolveAuth,
46
46
  saveConfig,
47
47
  uploadApp
48
- } from "./chunk-4D2E2PE4.js";
48
+ } from "./chunk-QRJAFBH3.js";
49
49
 
50
50
  // src/cli.ts
51
51
  import { createRequire } from "module";
@@ -412,6 +412,7 @@ function printStepLines(stepNum, total, status, text, actions, error) {
412
412
  process.stderr.write(` ${icon} Step ${stepNum}/${total}: ${text}
413
413
  `);
414
414
  for (const action of actions ?? []) {
415
+ if (action.tool === "fast_replay") continue;
415
416
  process.stderr.write(` ${chalk2.dim(formatAction(action))}
416
417
  `);
417
418
  }
@@ -4144,7 +4145,7 @@ program.command("dev-reload").description(
4144
4145
  program.command("mcp").description(
4145
4146
  "Run an MCP stdio server exposing the agent verbs (tap, swipe, type, ...) plus dev_start/dev_stop/dev_reload as tools"
4146
4147
  ).option("--token <token>", "API token (or set VIBEVIEW_API_TOKEN)").action(async (opts) => {
4147
- const { runMcpServer } = await import("./server-RDGEVJD4.js");
4148
+ const { runMcpServer } = await import("./server-EKFF2JBU.js");
4148
4149
  await runMcpServer({ ...opts, version: pkg.version });
4149
4150
  });
4150
4151
  program.command("agent-setup").description(
@@ -25,12 +25,12 @@ import {
25
25
  renderEnvelope,
26
26
  resolveMetro,
27
27
  startDevSession
28
- } from "./chunk-TPZG7NCU.js";
28
+ } from "./chunk-Z6UVEAYO.js";
29
29
  import {
30
30
  ApiClient,
31
31
  NotFoundError,
32
32
  resolveAuth
33
- } from "./chunk-4D2E2PE4.js";
33
+ } from "./chunk-QRJAFBH3.js";
34
34
 
35
35
  // src/mcp/server.ts
36
36
  import { writeFileSync } from "fs";
@@ -629,7 +629,7 @@ async function handleUploadApp(args, deps) {
629
629
  }
630
630
  const name = typeof args.name === "string" && args.name ? args.name : void 0;
631
631
  const upload = deps.uploadApp ?? (async (f, n) => {
632
- const { uploadAppBuild } = await import("./upload-app-AKD73742.js");
632
+ const { uploadAppBuild } = await import("./upload-app-BPTGBDQB.js");
633
633
  const { result: result2 } = await uploadAppBuild(f, { ...deps.auth, name: n });
634
634
  return result2;
635
635
  });
@@ -3,7 +3,7 @@ import {
3
3
  describeBuild,
4
4
  uploadApp,
5
5
  uploadAppBuild
6
- } from "./chunk-4D2E2PE4.js";
6
+ } from "./chunk-QRJAFBH3.js";
7
7
  export {
8
8
  describeBuild,
9
9
  uploadApp,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeview",
3
- "version": "0.34.0",
3
+ "version": "0.35.0",
4
4
  "description": "VibeView CLI -- run your app on cloud iOS simulators, Android emulators, Apple TV, Android TV and Roku (beta) devices: a React Native dev loop, device control for you or your coding agent (CLI or MCP), and tests from CI",
5
5
  "mcpName": "io.github.vibeview/vibeview",
6
6
  "type": "module",