vibeview 0.23.0 → 0.24.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.
- package/dist/{chunk-PSFXVUHG.js → chunk-2WNJYNDW.js} +39 -6
- package/dist/{chunk-E2LZSLRF.js → chunk-MVNMGB6I.js} +24 -4
- package/dist/cli.js +4 -4
- package/dist/{server-XMSBLIWY.js → server-KIJCEN6T.js} +9 -3
- package/dist/{upload-app-ZAKAOJKE.js → upload-app-BXXKH65S.js} +3 -1
- package/package.json +1 -1
|
@@ -197,7 +197,7 @@ var ApiClient = class {
|
|
|
197
197
|
async listApps() {
|
|
198
198
|
return this.requestRaw("GET", "/apps/");
|
|
199
199
|
}
|
|
200
|
-
async uploadApp(filePath, name) {
|
|
200
|
+
async uploadApp(filePath, name, note) {
|
|
201
201
|
const fileBuffer = readFileSync2(filePath);
|
|
202
202
|
const blob = new Blob([fileBuffer]);
|
|
203
203
|
const formData = new FormData();
|
|
@@ -205,8 +205,15 @@ var ApiClient = class {
|
|
|
205
205
|
if (name) {
|
|
206
206
|
formData.append("name", name);
|
|
207
207
|
}
|
|
208
|
+
if (note) {
|
|
209
|
+
formData.append("note", note);
|
|
210
|
+
}
|
|
208
211
|
return this.requestFormData("POST", "/apps/upload", formData);
|
|
209
212
|
}
|
|
213
|
+
/** PATCH a build's note (null clears it). */
|
|
214
|
+
async updateBuildNote(appPublicId, buildId, note) {
|
|
215
|
+
return this.requestRaw("PATCH", `/apps/${appPublicId}/builds/${buildId}`, { note });
|
|
216
|
+
}
|
|
210
217
|
async uploadBuild(appPublicId, filePath, version) {
|
|
211
218
|
const fileBuffer = readFileSync2(filePath);
|
|
212
219
|
const blob = new Blob([fileBuffer]);
|
|
@@ -613,9 +620,15 @@ function sanitizeDownloadFilename(raw) {
|
|
|
613
620
|
|
|
614
621
|
// src/lib/spinner.ts
|
|
615
622
|
import ora from "ora";
|
|
616
|
-
function createSpinner(text) {
|
|
623
|
+
function createSpinner(text, opts = {}) {
|
|
617
624
|
const isCI = process.env.CI === "true" || process.env.CI === "1" || !process.stdout.isTTY;
|
|
618
|
-
return ora({
|
|
625
|
+
return ora({
|
|
626
|
+
text,
|
|
627
|
+
isEnabled: !isCI,
|
|
628
|
+
stream: process.stderr,
|
|
629
|
+
discardStdin: false,
|
|
630
|
+
isSilent: opts.silent === true
|
|
631
|
+
});
|
|
619
632
|
}
|
|
620
633
|
|
|
621
634
|
// src/lib/types.ts
|
|
@@ -636,16 +649,26 @@ async function uploadAppBuild(filePath, options) {
|
|
|
636
649
|
}
|
|
637
650
|
const { token, baseUrl } = resolveAuth(options);
|
|
638
651
|
const client = new ApiClient(baseUrl, token);
|
|
639
|
-
const
|
|
652
|
+
const note = options.note?.trim() || void 0;
|
|
653
|
+
const result = await client.uploadApp(filePath, options.name, note);
|
|
654
|
+
if (note && result.deduplicated && result.build_id != null) {
|
|
655
|
+
await client.updateBuildNote(result.public_id, result.build_id, note);
|
|
656
|
+
}
|
|
640
657
|
return { result, baseUrl };
|
|
641
658
|
}
|
|
659
|
+
function describeBuild(result) {
|
|
660
|
+
if (result.build_id == null) return null;
|
|
661
|
+
const version = result.version ? `v${result.version}${result.build_number ? ` (${result.build_number})` : ""}` : "";
|
|
662
|
+
const dedup = result.deduplicated ? chalk.dim(" identical build already uploaded") : "";
|
|
663
|
+
return `Build ${chalk.cyan(String(result.build_id))}${version ? ` ${version}` : ""}${dedup}`;
|
|
664
|
+
}
|
|
642
665
|
async function uploadApp(filePath, options) {
|
|
643
666
|
if (!existsSync(filePath)) {
|
|
644
667
|
console.error(chalk.red(`Error: File not found: ${filePath}`));
|
|
645
668
|
process.exit(EXIT_INFRA_ERROR);
|
|
646
669
|
}
|
|
647
670
|
const { baseUrl } = resolveAuth(options);
|
|
648
|
-
const spinner = createSpinner("Uploading app...");
|
|
671
|
+
const spinner = createSpinner("Uploading app...", { silent: options.output === "json" });
|
|
649
672
|
spinner.start();
|
|
650
673
|
try {
|
|
651
674
|
const { result } = await uploadAppBuild(filePath, options);
|
|
@@ -662,6 +685,11 @@ async function uploadApp(filePath, options) {
|
|
|
662
685
|
package_name: result.package_name,
|
|
663
686
|
platform: result.platform,
|
|
664
687
|
is_new: isNew,
|
|
688
|
+
build_id: result.build_id ?? null,
|
|
689
|
+
version: result.version ?? null,
|
|
690
|
+
build_number: result.build_number ?? null,
|
|
691
|
+
deduplicated: result.deduplicated === true,
|
|
692
|
+
note: options.note?.trim() || null,
|
|
665
693
|
url: `${baseUrl}/apps/${result.public_id}`,
|
|
666
694
|
warnings: result.warnings ?? []
|
|
667
695
|
},
|
|
@@ -675,6 +703,8 @@ async function uploadApp(filePath, options) {
|
|
|
675
703
|
${chalk.cyan(result.public_id)} ${result.name} ${chalk.dim(`[${result.platform}]`)}`
|
|
676
704
|
);
|
|
677
705
|
console.log(` ${chalk.dim(result.package_name)}`);
|
|
706
|
+
const build = describeBuild(result);
|
|
707
|
+
if (build) console.log(` ${build}`);
|
|
678
708
|
console.log(chalk.dim(` ${baseUrl}/apps/${result.public_id}
|
|
679
709
|
`));
|
|
680
710
|
}
|
|
@@ -683,7 +713,9 @@ async function uploadApp(filePath, options) {
|
|
|
683
713
|
\u26A0 ${w}`));
|
|
684
714
|
}
|
|
685
715
|
} catch (err) {
|
|
686
|
-
|
|
716
|
+
const message = err instanceof Error ? err.message : "Upload failed";
|
|
717
|
+
spinner.fail(message);
|
|
718
|
+
if (options.output === "json") console.error(chalk.red(`Error: ${message}`));
|
|
687
719
|
process.exit(EXIT_INFRA_ERROR);
|
|
688
720
|
}
|
|
689
721
|
}
|
|
@@ -700,5 +732,6 @@ export {
|
|
|
700
732
|
EXIT_INFRA_ERROR,
|
|
701
733
|
UsageError,
|
|
702
734
|
uploadAppBuild,
|
|
735
|
+
describeBuild,
|
|
703
736
|
uploadApp
|
|
704
737
|
};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
loadConfig,
|
|
7
7
|
resolveAuth,
|
|
8
8
|
uploadAppBuild
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2WNJYNDW.js";
|
|
10
10
|
|
|
11
11
|
// src/lib/dev-state.ts
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
@@ -1646,6 +1646,26 @@ function decodeFrame(data) {
|
|
|
1646
1646
|
return { type, streamId: data.readUInt32BE(1), payload: data.subarray(HEADER_LEN) };
|
|
1647
1647
|
}
|
|
1648
1648
|
|
|
1649
|
+
// src/lib/redact.ts
|
|
1650
|
+
var SECRET_PARAMS = /* @__PURE__ */ new Set([
|
|
1651
|
+
"token",
|
|
1652
|
+
"access_token",
|
|
1653
|
+
"refresh_token",
|
|
1654
|
+
"api_key",
|
|
1655
|
+
"apikey",
|
|
1656
|
+
"key",
|
|
1657
|
+
"secret",
|
|
1658
|
+
"signature",
|
|
1659
|
+
"sig",
|
|
1660
|
+
"jwt"
|
|
1661
|
+
]);
|
|
1662
|
+
function redactSecrets(text) {
|
|
1663
|
+
return text.replace(
|
|
1664
|
+
/\b([A-Za-z_]+)=([^&\s"'#]+)/g,
|
|
1665
|
+
(match, name) => SECRET_PARAMS.has(name.toLowerCase()) ? `${name}=[redacted]` : match
|
|
1666
|
+
);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1649
1669
|
// src/lib/tunnel-client.ts
|
|
1650
1670
|
var FATAL_CLOSE_CODES = /* @__PURE__ */ new Set([4008, 4009]);
|
|
1651
1671
|
var MAX_BACKOFF_MS = 8e3;
|
|
@@ -1665,7 +1685,7 @@ var TunnelClient = class {
|
|
|
1665
1685
|
url;
|
|
1666
1686
|
connCount = 0;
|
|
1667
1687
|
debug(msg) {
|
|
1668
|
-
this.opts.onDebug?.(msg);
|
|
1688
|
+
this.opts.onDebug?.(redactSecrets(msg));
|
|
1669
1689
|
}
|
|
1670
1690
|
start() {
|
|
1671
1691
|
this.connect();
|
|
@@ -3412,9 +3432,9 @@ function deviceStateLine(r) {
|
|
|
3412
3432
|
const parts = [];
|
|
3413
3433
|
if (r.action === "rotated") {
|
|
3414
3434
|
if (typeof r.device_orientation === "string") {
|
|
3415
|
-
let o = `
|
|
3435
|
+
let o = `device held ${r.device_orientation}`;
|
|
3416
3436
|
if (typeof r.screen_orientation === "string" && r.screen_orientation !== r.device_orientation) {
|
|
3417
|
-
o += ` (screen
|
|
3437
|
+
o += ` (picture on the lit screen: ${r.screen_orientation})`;
|
|
3418
3438
|
}
|
|
3419
3439
|
parts.push(o);
|
|
3420
3440
|
}
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
readDevState,
|
|
20
20
|
readMetroState,
|
|
21
21
|
runAgentVerb
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-MVNMGB6I.js";
|
|
23
23
|
import {
|
|
24
24
|
ApiClient,
|
|
25
25
|
EXIT_INFRA_ERROR,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
resolveAuth,
|
|
33
33
|
saveConfig,
|
|
34
34
|
uploadApp
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-2WNJYNDW.js";
|
|
36
36
|
|
|
37
37
|
// src/cli.ts
|
|
38
38
|
import { createRequire } from "module";
|
|
@@ -3229,7 +3229,7 @@ program.command("list-devices").description("List devices registered with the pl
|
|
|
3229
3229
|
).action((opts) => listDevicesCommand(opts));
|
|
3230
3230
|
program.command("upload-app <file>").description(
|
|
3231
3231
|
"Upload an app build (zipped simulator .app for iOS/tvOS, .apk for Android/Android TV, or a Roku channel .zip)"
|
|
3232
|
-
).option("--token <token>", "API token").option("--output <format>", "Output format: human, json", "human").option("--name <name>", "App name (auto-detected if not provided)").action((file, opts) => uploadApp(file, opts));
|
|
3232
|
+
).option("--token <token>", "API token").option("--output <format>", "Output format: human, json", "human").option("--name <name>", "App name (auto-detected if not provided)").option("--note <text>", "Note stored on the uploaded build (shown in the dashboard)").action((file, opts) => uploadApp(file, opts));
|
|
3233
3233
|
program.command("create-test [name]").description("Create a standalone AI test case").option("--token <token>", "API token").option("--output <format>", "Output format: human, json", "human").option("--app <app>", "App ID (public_id) or package name (requires --platform)").option("--platform <platform>", "Platform (ios, android) when using package name for --app").option("--steps <json>", "Test steps as inline JSON array").option("--steps-file <path>", "Path to JSON file containing test steps").option("--context <text>", "Additional context for AI test execution").option("--test-name <name>", "Test case name (alternative to positional arg)").action((name, opts) => createTest({ ...opts, testName: name || opts.testName || "CLI Test" }));
|
|
3234
3234
|
program.command("login").description("Log in to VibeView (interactive)").option("--base-url <url>", "VibeView server URL (defaults to https://vibeview.io)").action((opts) => login(opts));
|
|
3235
3235
|
program.command("logout").description("Revoke the saved login token and remove it from ~/.vibeview/config.json").action(() => logout());
|
|
@@ -3393,7 +3393,7 @@ program.command("dev-reload").description(
|
|
|
3393
3393
|
program.command("mcp").description(
|
|
3394
3394
|
"Run an MCP stdio server exposing the agent verbs (tap, swipe, type, ...) plus dev_start/dev_stop/dev_reload as tools"
|
|
3395
3395
|
).option("--token <token>", "API token (or set VIBEVIEW_API_TOKEN)").action(async (opts) => {
|
|
3396
|
-
const { runMcpServer } = await import("./server-
|
|
3396
|
+
const { runMcpServer } = await import("./server-KIJCEN6T.js");
|
|
3397
3397
|
await runMcpServer(opts);
|
|
3398
3398
|
});
|
|
3399
3399
|
program.command("agent-setup").description(
|
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
readDevState,
|
|
17
17
|
renderEnvelope,
|
|
18
18
|
startDevSession
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-MVNMGB6I.js";
|
|
20
20
|
import {
|
|
21
21
|
ApiClient,
|
|
22
22
|
resolveAuth
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2WNJYNDW.js";
|
|
24
24
|
|
|
25
25
|
// src/mcp/server.ts
|
|
26
26
|
import { writeFileSync } from "fs";
|
|
@@ -301,7 +301,7 @@ async function handleUploadApp(args, deps) {
|
|
|
301
301
|
}
|
|
302
302
|
const name = typeof args.name === "string" && args.name ? args.name : void 0;
|
|
303
303
|
const upload = deps.uploadApp ?? (async (f, n) => {
|
|
304
|
-
const { uploadAppBuild } = await import("./upload-app-
|
|
304
|
+
const { uploadAppBuild } = await import("./upload-app-BXXKH65S.js");
|
|
305
305
|
const { result: result2 } = await uploadAppBuild(f, { ...deps.auth, name: n });
|
|
306
306
|
return result2;
|
|
307
307
|
});
|
|
@@ -319,11 +319,17 @@ async function handleUploadApp(args, deps) {
|
|
|
319
319
|
package_name: result.package_name,
|
|
320
320
|
platform: result.platform,
|
|
321
321
|
is_new: isNew,
|
|
322
|
+
build_id: result.build_id ?? null,
|
|
323
|
+
version: result.version ?? null,
|
|
324
|
+
build_number: result.build_number ?? null,
|
|
322
325
|
warnings
|
|
323
326
|
};
|
|
324
327
|
const lines = [
|
|
325
328
|
`${isNew ? "New app created" : "Build added to existing app"}: ${result.name}`,
|
|
326
329
|
`app_id: ${result.public_id} [${result.platform}] ${result.package_name}`,
|
|
330
|
+
...result.build_id != null ? [
|
|
331
|
+
`build_id: ${result.build_id}${result.version ? ` version ${result.version}${result.build_number ? ` (${result.build_number})` : ""}` : ""}`
|
|
332
|
+
] : [],
|
|
327
333
|
...warnings.map((w) => `warning: ${w}`)
|
|
328
334
|
];
|
|
329
335
|
return textResult(lines.join("\n"), payload);
|