vibeview 0.51.1 → 0.52.1
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-IVVLPLPM.js → chunk-6U4WMOVF.js} +116 -38
- package/dist/{chunk-42GZ4UEJ.js → chunk-LRPZFDKL.js} +2 -1
- package/dist/cli.js +5 -3
- package/dist/{server-322WCIKD.js → server-B4OVM2L7.js} +3 -3
- package/dist/{upload-app-DLBU3ZZY.js → upload-app-OV3QKL7O.js} +1 -1
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
resolveArtifact,
|
|
14
14
|
resolveAuth,
|
|
15
15
|
uploadAppBuild
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-LRPZFDKL.js";
|
|
17
17
|
|
|
18
18
|
// src/lib/formatters/not-checked.ts
|
|
19
19
|
function notCheckedSteps(steps) {
|
|
@@ -1057,6 +1057,8 @@ import { select as select2 } from "@inquirer/prompts";
|
|
|
1057
1057
|
import chalk3 from "chalk";
|
|
1058
1058
|
|
|
1059
1059
|
// src/lib/dev-setup.ts
|
|
1060
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
1061
|
+
import { basename, join as join6 } from "path";
|
|
1060
1062
|
import chalk2 from "chalk";
|
|
1061
1063
|
import { input, select } from "@inquirer/prompts";
|
|
1062
1064
|
|
|
@@ -1123,8 +1125,14 @@ function isManagedExpo(cwd, platform) {
|
|
|
1123
1125
|
}
|
|
1124
1126
|
function iosWorkspaceName(cwd) {
|
|
1125
1127
|
try {
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
+
const entries = readdirSync2(join5(cwd, "ios"));
|
|
1129
|
+
const found = entries.find((f) => f.endsWith(".xcworkspace"));
|
|
1130
|
+
if (found) return found.replace(/\.xcworkspace$/, "");
|
|
1131
|
+
const projects = entries.filter((f) => f.endsWith(".xcodeproj"));
|
|
1132
|
+
if (projects.length === 1 && entries.includes("Podfile")) {
|
|
1133
|
+
return projects[0].replace(/\.xcodeproj$/, "");
|
|
1134
|
+
}
|
|
1135
|
+
return null;
|
|
1128
1136
|
} catch {
|
|
1129
1137
|
return null;
|
|
1130
1138
|
}
|
|
@@ -1770,6 +1778,7 @@ function usesMetroBuild(cwd, platform) {
|
|
|
1770
1778
|
const flavor = detectFlavor(cwd);
|
|
1771
1779
|
return (flavor === "expo" || flavor === "bare-rn") && (platform === "ios" || platform === "android");
|
|
1772
1780
|
}
|
|
1781
|
+
var SAVED_LINE = " The answer is saved to vibeview.json. Commit it so your team and CI build the same way.";
|
|
1773
1782
|
function profileIntro(cwd, platform, profile, defaults) {
|
|
1774
1783
|
const label = platformLabel(platform);
|
|
1775
1784
|
const metro = usesMetroBuild(cwd, platform);
|
|
@@ -1777,7 +1786,7 @@ function profileIntro(cwd, platform, profile, defaults) {
|
|
|
1777
1786
|
return [
|
|
1778
1787
|
`No development build profile for ${label} in vibeview.json yet.`,
|
|
1779
1788
|
metro ? " development is the debug build VibeView devices run while you code: it loads your JavaScript from Metro (vibeview dev)." : " development is the build VibeView devices run while you work: vibeview build and vibeview dev use it.",
|
|
1780
|
-
|
|
1789
|
+
SAVED_LINE,
|
|
1781
1790
|
` Build profiles: ${PROFILES_DOCS_URL}`
|
|
1782
1791
|
];
|
|
1783
1792
|
}
|
|
@@ -1796,20 +1805,22 @@ function profileIntro(cwd, platform, profile, defaults) {
|
|
|
1796
1805
|
" Your development build already runs by itself, so the suggestion is the same command."
|
|
1797
1806
|
);
|
|
1798
1807
|
}
|
|
1799
|
-
lines.push(` Build profiles: ${PROFILES_DOCS_URL}`);
|
|
1808
|
+
lines.push(SAVED_LINE, ` Build profiles: ${PROFILES_DOCS_URL}`);
|
|
1800
1809
|
return lines;
|
|
1801
1810
|
}
|
|
1802
1811
|
if (profile === PRODUCTION) {
|
|
1803
1812
|
return [
|
|
1804
1813
|
`No production build profile for ${label} in vibeview.json yet.`,
|
|
1805
1814
|
" production is the signed build for the stores (.ipa for TestFlight, .aab for Google Play).",
|
|
1806
|
-
` It builds in the cloud with the signing you set up in VibeView: ${SIGNING_DOCS_URL}
|
|
1815
|
+
` It builds in the cloud with the signing you set up in VibeView: ${SIGNING_DOCS_URL}`,
|
|
1816
|
+
SAVED_LINE
|
|
1807
1817
|
];
|
|
1808
1818
|
}
|
|
1809
1819
|
return [
|
|
1810
1820
|
`No "${profile}" build profile for ${label} in vibeview.json yet.`,
|
|
1811
1821
|
" A profile of your own makes a build that runs on VibeView devices, like development.",
|
|
1812
|
-
` To make it a signed store build, add "distribution": "production" to it in vibeview.json: ${PROFILES_DOCS_URL}
|
|
1822
|
+
` To make it a signed store build, add "distribution": "production" to it in vibeview.json: ${PROFILES_DOCS_URL}`,
|
|
1823
|
+
SAVED_LINE
|
|
1813
1824
|
];
|
|
1814
1825
|
}
|
|
1815
1826
|
function previewSkippedNote(cwd, platform) {
|
|
@@ -1826,6 +1837,13 @@ function previewSavedNote() {
|
|
|
1826
1837
|
" GitHub pull requests. Build it with `vibeview build --cloud --profile preview`."
|
|
1827
1838
|
];
|
|
1828
1839
|
}
|
|
1840
|
+
function installTipExample(platform, production) {
|
|
1841
|
+
if (platform === "roku") return "npm ci && npm run package";
|
|
1842
|
+
if (platform === "ios" || platform === "tvos") {
|
|
1843
|
+
return production ? "yarn install --immutable && cd ios && pod install && cd .. && xcodebuild archive \u2026" : "yarn install --immutable && cd ios && pod install && cd .. && xcodebuild \u2026";
|
|
1844
|
+
}
|
|
1845
|
+
return production ? "yarn install --immutable && cd android && ./gradlew bundleRelease" : "yarn install --immutable && cd android && ./gradlew assembleDebug";
|
|
1846
|
+
}
|
|
1829
1847
|
function commandLabel(profile, platform) {
|
|
1830
1848
|
return `Build command for ${platformLabel(platform)} (${profile} profile)`;
|
|
1831
1849
|
}
|
|
@@ -1842,7 +1860,8 @@ async function promptProfileConfig(cwd, platform, profile) {
|
|
|
1842
1860
|
}
|
|
1843
1861
|
console.log(
|
|
1844
1862
|
chalk2.dim(
|
|
1845
|
-
|
|
1863
|
+
` Tip: include your install step \u2014 dependencies are not uploaded.
|
|
1864
|
+
e.g. \`${installTipExample(platform, production)}\``
|
|
1846
1865
|
)
|
|
1847
1866
|
);
|
|
1848
1867
|
const command = await input({ message: label, required: true });
|
|
@@ -1872,12 +1891,42 @@ async function promptMetroCommand(cwd, platform) {
|
|
|
1872
1891
|
if (choice === "default") return defaults.metroCommand;
|
|
1873
1892
|
return input({ message: "Metro command", required: true });
|
|
1874
1893
|
}
|
|
1894
|
+
var normalizeName = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1895
|
+
function projectNames(cwd) {
|
|
1896
|
+
const names = [basename(cwd)];
|
|
1897
|
+
const readJson2 = (file) => {
|
|
1898
|
+
try {
|
|
1899
|
+
return JSON.parse(readFileSync7(join6(cwd, file), "utf-8"));
|
|
1900
|
+
} catch {
|
|
1901
|
+
return null;
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
const pkg = readJson2("package.json");
|
|
1905
|
+
if (typeof pkg?.name === "string") names.push(pkg.name.replace(/^@[^/]+\//, ""));
|
|
1906
|
+
const appJson = readJson2("app.json");
|
|
1907
|
+
const expo = appJson?.expo;
|
|
1908
|
+
if (typeof expo?.name === "string") names.push(expo.name);
|
|
1909
|
+
if (typeof appJson?.name === "string") names.push(appJson.name);
|
|
1910
|
+
try {
|
|
1911
|
+
const m = /^name:\s*([\w-]+)/m.exec(readFileSync7(join6(cwd, "pubspec.yaml"), "utf-8"));
|
|
1912
|
+
if (m) names.push(m[1]);
|
|
1913
|
+
} catch {
|
|
1914
|
+
}
|
|
1915
|
+
return new Set(names.map(normalizeName).filter(Boolean));
|
|
1916
|
+
}
|
|
1917
|
+
function rankAppsForProject(apps, cwd) {
|
|
1918
|
+
const names = projectNames(cwd);
|
|
1919
|
+
const nameMatches = (n) => names.has(n) || [...names].some((p) => p.length >= 4 && n.startsWith(p));
|
|
1920
|
+
const matches = (a) => nameMatches(normalizeName(a.name)) || !!a.package_name && names.has(normalizeName(a.package_name.split(".").pop() ?? ""));
|
|
1921
|
+
const first = apps.filter(matches);
|
|
1922
|
+
return { apps: [...first, ...apps.filter((a) => !matches(a))], matched: first.length > 0 };
|
|
1923
|
+
}
|
|
1875
1924
|
|
|
1876
1925
|
// src/lib/source-pack.ts
|
|
1877
1926
|
import { execFile as execFile3, spawn } from "child_process";
|
|
1878
|
-
import { lstatSync, mkdtempSync, readFileSync as
|
|
1927
|
+
import { lstatSync, mkdtempSync, readFileSync as readFileSync8, rmSync as rmSync5, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
1879
1928
|
import { tmpdir } from "os";
|
|
1880
|
-
import { join as
|
|
1929
|
+
import { join as join7 } from "path";
|
|
1881
1930
|
import ignore2 from "ignore";
|
|
1882
1931
|
var NotAGitRepoError = class extends Error {
|
|
1883
1932
|
constructor(message) {
|
|
@@ -1903,15 +1952,15 @@ async function listSourceFiles(projectRoot) {
|
|
|
1903
1952
|
const stdout = await runGitLsFiles(projectRoot);
|
|
1904
1953
|
const rawPaths = stdout.length ? stdout.split("\0").filter((p) => p.length > 0) : [];
|
|
1905
1954
|
let filtered = rawPaths;
|
|
1906
|
-
const vvignorePath =
|
|
1955
|
+
const vvignorePath = join7(projectRoot, ".vvignore");
|
|
1907
1956
|
if (statOrNull(vvignorePath)?.isFile()) {
|
|
1908
|
-
const ig = ignore2().add(
|
|
1957
|
+
const ig = ignore2().add(readFileSync8(vvignorePath, "utf-8"));
|
|
1909
1958
|
filtered = filtered.filter((p) => !ig.ignores(p));
|
|
1910
1959
|
}
|
|
1911
1960
|
const result = [];
|
|
1912
1961
|
for (const relPath of filtered) {
|
|
1913
1962
|
if (isForceExcluded(relPath)) continue;
|
|
1914
|
-
const st = statOrNull(
|
|
1963
|
+
const st = statOrNull(join7(projectRoot, relPath));
|
|
1915
1964
|
if (!st) continue;
|
|
1916
1965
|
result.push(relPath);
|
|
1917
1966
|
}
|
|
@@ -1961,7 +2010,7 @@ async function packSource(projectRoot, files, opts = {}) {
|
|
|
1961
2010
|
let totalBytes = 0;
|
|
1962
2011
|
const sized = [];
|
|
1963
2012
|
for (const relPath of files) {
|
|
1964
|
-
const bytes = lstatSync(
|
|
2013
|
+
const bytes = lstatSync(join7(projectRoot, relPath)).size;
|
|
1965
2014
|
totalBytes += bytes;
|
|
1966
2015
|
sized.push({ path: relPath, bytes });
|
|
1967
2016
|
}
|
|
@@ -1972,13 +2021,13 @@ async function packSource(projectRoot, files, opts = {}) {
|
|
|
1972
2021
|
largest
|
|
1973
2022
|
);
|
|
1974
2023
|
}
|
|
1975
|
-
const tmpDir = mkdtempSync(
|
|
2024
|
+
const tmpDir = mkdtempSync(join7(tmpdir(), "vibeview-source-pack-"));
|
|
1976
2025
|
const cleanup = () => rmSync5(tmpDir, { recursive: true, force: true });
|
|
1977
2026
|
try {
|
|
1978
2027
|
const supportsNull = await probeTarNullSupport();
|
|
1979
|
-
const tarPath =
|
|
2028
|
+
const tarPath = join7(tmpDir, "source.tgz");
|
|
1980
2029
|
if (supportsNull) {
|
|
1981
|
-
const listPath =
|
|
2030
|
+
const listPath = join7(tmpDir, "files.list");
|
|
1982
2031
|
writeFileSync5(listPath, files.map((f) => `${f}\0`).join(""));
|
|
1983
2032
|
await runTar(["-czf", tarPath, "-C", projectRoot, "--null", "-T", listPath]);
|
|
1984
2033
|
} else {
|
|
@@ -1988,7 +2037,7 @@ async function packSource(projectRoot, files, opts = {}) {
|
|
|
1988
2037
|
`cannot pack source: filename contains a newline (${JSON.stringify(badName)}) and the installed tar doesn't support --null -T; rename the file or install a tar that supports --null`
|
|
1989
2038
|
);
|
|
1990
2039
|
}
|
|
1991
|
-
const listPath =
|
|
2040
|
+
const listPath = join7(tmpDir, "files.list");
|
|
1992
2041
|
writeFileSync5(listPath, files.map((f) => `${f}
|
|
1993
2042
|
`).join(""));
|
|
1994
2043
|
await runTar(["-czf", tarPath, "-C", projectRoot, "-T", listPath]);
|
|
@@ -2009,10 +2058,10 @@ var nullSupportCache = null;
|
|
|
2009
2058
|
function probeTarNullSupport() {
|
|
2010
2059
|
if (!nullSupportCache) {
|
|
2011
2060
|
nullSupportCache = new Promise((resolve) => {
|
|
2012
|
-
const tmp = mkdtempSync(
|
|
2013
|
-
const listPath =
|
|
2061
|
+
const tmp = mkdtempSync(join7(tmpdir(), "vibeview-tar-probe-"));
|
|
2062
|
+
const listPath = join7(tmp, "empty.list");
|
|
2014
2063
|
writeFileSync5(listPath, "");
|
|
2015
|
-
const out =
|
|
2064
|
+
const out = join7(tmp, "probe.tgz");
|
|
2016
2065
|
execFile3("tar", ["-czf", out, "-C", tmp, "--null", "-T", listPath], (err) => {
|
|
2017
2066
|
rmSync5(tmp, { recursive: true, force: true });
|
|
2018
2067
|
resolve(!err);
|
|
@@ -2079,7 +2128,7 @@ function cloudManifestEntry(platform, profile, opts = {}) {
|
|
|
2079
2128
|
// src/lib/build-preflight.ts
|
|
2080
2129
|
import { execFile as execFile4 } from "child_process";
|
|
2081
2130
|
import { realpathSync, statSync as statSync4 } from "fs";
|
|
2082
|
-
import { dirname as dirname2, isAbsolute, join as
|
|
2131
|
+
import { dirname as dirname2, isAbsolute, join as join8, relative } from "path";
|
|
2083
2132
|
import { parse } from "shell-quote";
|
|
2084
2133
|
var DIRECTORY_CHANGERS = /* @__PURE__ */ new Set(["cd", "pushd"]);
|
|
2085
2134
|
var DIRECTORY_FLAGS = /^(--cwd|--prefix|--dir|-C)(=|$)/;
|
|
@@ -2238,7 +2287,7 @@ function buildCommandWarnings(command, files) {
|
|
|
2238
2287
|
missingLockfileWarning(command, files)
|
|
2239
2288
|
].filter((w) => w !== null);
|
|
2240
2289
|
}
|
|
2241
|
-
function projectRootHint(cwd, gitRoot, files, hasPackageJson = (dir) => isFile2(
|
|
2290
|
+
function projectRootHint(cwd, gitRoot, files, hasPackageJson = (dir) => isFile2(join8(dir, "package.json"))) {
|
|
2242
2291
|
if (!gitRoot || files.has("package.json")) return null;
|
|
2243
2292
|
cwd = realPathOr(cwd);
|
|
2244
2293
|
gitRoot = realPathOr(gitRoot);
|
|
@@ -2639,7 +2688,8 @@ async function resolveCloudAppIds(cwd, cfgRef, platforms, opts, listApps) {
|
|
|
2639
2688
|
);
|
|
2640
2689
|
}
|
|
2641
2690
|
for (const platform of missing) {
|
|
2642
|
-
const
|
|
2691
|
+
const ranked = rankAppsForProject(appsForPlatform(allApps, platform), cwd);
|
|
2692
|
+
const apps = ranked.apps;
|
|
2643
2693
|
if (apps.length === 0) {
|
|
2644
2694
|
createFromArtifact.add(platform);
|
|
2645
2695
|
if (!opts.json) {
|
|
@@ -2662,13 +2712,19 @@ async function resolveCloudAppIds(cwd, cfgRef, platforms, opts, listApps) {
|
|
|
2662
2712
|
// is suppressed there): production builds aren't linked to an app
|
|
2663
2713
|
// unless the user explicitly wants the link — see APP_PICKER_SENTINEL.
|
|
2664
2714
|
...opts.production ? [{ value: APP_PICKER_SENTINEL.DONT_LINK_APP, name: "Don't link an app" }] : [],
|
|
2715
|
+
...!opts.production && !ranked.matched ? [
|
|
2716
|
+
{
|
|
2717
|
+
value: APP_PICKER_SENTINEL.CREATE_NEW_APP,
|
|
2718
|
+
name: "Create a new app from this build"
|
|
2719
|
+
}
|
|
2720
|
+
] : [],
|
|
2665
2721
|
...apps.map((a) => ({ value: a.public_id, name: a.name })),
|
|
2666
2722
|
// No create-from-artifact row under --production: a production build
|
|
2667
2723
|
// never creates an app (internal_builds returns before app creation),
|
|
2668
2724
|
// so offering it would promise something that can't happen. Picking
|
|
2669
2725
|
// an EXISTING app is still meaningful — app-scoped signing
|
|
2670
2726
|
// credentials resolve by app.
|
|
2671
|
-
...opts.production ? [] : [
|
|
2727
|
+
...opts.production || !ranked.matched ? [] : [
|
|
2672
2728
|
{
|
|
2673
2729
|
value: APP_PICKER_SENTINEL.CREATE_NEW_APP,
|
|
2674
2730
|
name: "Create a new app from this build"
|
|
@@ -2762,6 +2818,13 @@ async function runCloudBuildCommand(cwd, cfgRef, opts, deps) {
|
|
|
2762
2818
|
if (nodeFlag === null) {
|
|
2763
2819
|
fail(opts, `--node must be a Node.js major version like 24, got "${opts.node}"`, "usage");
|
|
2764
2820
|
}
|
|
2821
|
+
if (!deps && !await gitToplevel(cwd)) {
|
|
2822
|
+
fail(
|
|
2823
|
+
opts,
|
|
2824
|
+
`${cwd} is not a git repository \u2014 cloud builds pack your project source via git; run \`git init\` and commit, then try again`,
|
|
2825
|
+
"config_required"
|
|
2826
|
+
);
|
|
2827
|
+
}
|
|
2765
2828
|
const platforms = await resolveCloudPlatforms(cwd, cfgRef, opts);
|
|
2766
2829
|
if (opts.xcode !== void 0 && !platforms.some(platformUsesXcode)) {
|
|
2767
2830
|
fail(
|
|
@@ -3014,6 +3077,8 @@ async function waitForCloudBuilds(builds, opts, deps) {
|
|
|
3014
3077
|
id: final.id,
|
|
3015
3078
|
status: final.status,
|
|
3016
3079
|
cost_micro: final.cost_micro,
|
|
3080
|
+
included_minutes: final.included_minutes ?? null,
|
|
3081
|
+
billed_minutes: final.billed_minutes ?? null,
|
|
3017
3082
|
error_summary: final.error_summary,
|
|
3018
3083
|
app_build_id: final.app_build_id ?? null,
|
|
3019
3084
|
app_public_id: final.app_public_id ?? null,
|
|
@@ -3166,9 +3231,22 @@ function printOutcomeLine(build, multi) {
|
|
|
3166
3231
|
let line = `${prefix}${mark} ${build.status}`;
|
|
3167
3232
|
if (duration) line += ` (${duration})`;
|
|
3168
3233
|
if (build.error_summary) line += ` \u2014 ${build.error_summary}`;
|
|
3169
|
-
|
|
3234
|
+
const minutes = buildMinutesSuffix(build);
|
|
3235
|
+
if (minutes) line += ` \u2014 ${minutes}`;
|
|
3236
|
+
else if (build.cost_micro > 0) line += ` \u2014 cost: ${formatCost(build.cost_micro)} usage credit`;
|
|
3170
3237
|
console.error(line);
|
|
3171
3238
|
}
|
|
3239
|
+
function buildMinutesSuffix(build) {
|
|
3240
|
+
const included = build.included_minutes ?? 0;
|
|
3241
|
+
const billed = build.billed_minutes ?? 0;
|
|
3242
|
+
if (build.included_minutes == null && build.billed_minutes == null) return null;
|
|
3243
|
+
const plural = (n) => n === 1 ? "minute" : "minutes";
|
|
3244
|
+
if (billed === 0) return included > 0 ? `${included} included build ${plural(included)}` : null;
|
|
3245
|
+
const cost = `${formatCost(build.cost_micro)} usage credit`;
|
|
3246
|
+
if (included === 0) return `${billed} billed build ${plural(billed)} (${cost})`;
|
|
3247
|
+
const total = included + billed;
|
|
3248
|
+
return `${total} build ${plural(total)}: ${included} included, ${billed} billed (${cost})`;
|
|
3249
|
+
}
|
|
3172
3250
|
|
|
3173
3251
|
// src/lib/roku-push.ts
|
|
3174
3252
|
function createRokuPush(opts) {
|
|
@@ -3204,8 +3282,8 @@ your build command must produce a zip \u2014 use the package/zip step, not deplo
|
|
|
3204
3282
|
|
|
3205
3283
|
// src/commands/dev.ts
|
|
3206
3284
|
import { spawn as spawn4 } from "child_process";
|
|
3207
|
-
import { closeSync, createWriteStream, mkdirSync as mkdirSync5, openSync, readFileSync as
|
|
3208
|
-
import { dirname as dirname5, join as
|
|
3285
|
+
import { closeSync, createWriteStream, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync10 } from "fs";
|
|
3286
|
+
import { dirname as dirname5, join as join10 } from "path";
|
|
3209
3287
|
import { createInterface as createInterface3 } from "readline";
|
|
3210
3288
|
import { stripVTControlCharacters } from "util";
|
|
3211
3289
|
import { select as select3 } from "@inquirer/prompts";
|
|
@@ -3408,15 +3486,15 @@ import { spawn as spawn3 } from "child_process";
|
|
|
3408
3486
|
import { createInterface as createInterface2 } from "readline";
|
|
3409
3487
|
|
|
3410
3488
|
// src/lib/metro-state.ts
|
|
3411
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as
|
|
3412
|
-
import { dirname as dirname3, join as
|
|
3489
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync9, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
3490
|
+
import { dirname as dirname3, join as join9 } from "path";
|
|
3413
3491
|
var STATE_DIR2 = ".vibeview";
|
|
3414
3492
|
var STATE_FILE2 = "metro-state.json";
|
|
3415
3493
|
function statePath2(cwd) {
|
|
3416
|
-
return
|
|
3494
|
+
return join9(cwd, STATE_DIR2, STATE_FILE2);
|
|
3417
3495
|
}
|
|
3418
3496
|
function metroLogPath(cwd) {
|
|
3419
|
-
return
|
|
3497
|
+
return join9(cwd, STATE_DIR2, "metro.log");
|
|
3420
3498
|
}
|
|
3421
3499
|
function isPidAlive2(pid) {
|
|
3422
3500
|
try {
|
|
@@ -3434,7 +3512,7 @@ function writeMetroState(cwd, state) {
|
|
|
3434
3512
|
function readMetroState(cwd) {
|
|
3435
3513
|
let parsed;
|
|
3436
3514
|
try {
|
|
3437
|
-
parsed = JSON.parse(
|
|
3515
|
+
parsed = JSON.parse(readFileSync9(statePath2(cwd), "utf-8"));
|
|
3438
3516
|
} catch {
|
|
3439
3517
|
return null;
|
|
3440
3518
|
}
|
|
@@ -3567,7 +3645,7 @@ async function waitFor(cond, timeoutMs, everyMs) {
|
|
|
3567
3645
|
|
|
3568
3646
|
// src/lib/reload-loop.ts
|
|
3569
3647
|
import { watch } from "fs";
|
|
3570
|
-
import { basename, dirname as dirname4 } from "path";
|
|
3648
|
+
import { basename as basename2, dirname as dirname4 } from "path";
|
|
3571
3649
|
function createReloadLoop(deps) {
|
|
3572
3650
|
let inFlight = null;
|
|
3573
3651
|
let pendingFollowUp = false;
|
|
@@ -3653,9 +3731,9 @@ function isIgnoredWatchPath(relPath, artifact, userIgnore = []) {
|
|
|
3653
3731
|
return true;
|
|
3654
3732
|
}
|
|
3655
3733
|
if (dirname4(rel) !== artifactDir) return false;
|
|
3656
|
-
const name =
|
|
3734
|
+
const name = basename2(artifactPattern);
|
|
3657
3735
|
const re = new RegExp(`^${name.split("*").map(escapeRegExp).join(".*")}$`);
|
|
3658
|
-
return re.test(
|
|
3736
|
+
return re.test(basename2(rel));
|
|
3659
3737
|
}
|
|
3660
3738
|
function escapeRegExp(s) {
|
|
3661
3739
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -4942,7 +5020,7 @@ async function dev(opts) {
|
|
|
4942
5020
|
if (process.exitCode === 1) return;
|
|
4943
5021
|
}
|
|
4944
5022
|
function detachLogPath(cwd) {
|
|
4945
|
-
return
|
|
5023
|
+
return join10(cwd, ".vibeview", "dev-detach.log");
|
|
4946
5024
|
}
|
|
4947
5025
|
function openDetachLog(path) {
|
|
4948
5026
|
try {
|
|
@@ -4956,7 +5034,7 @@ function openDetachLog(path) {
|
|
|
4956
5034
|
function lastErrorLine(path) {
|
|
4957
5035
|
let text;
|
|
4958
5036
|
try {
|
|
4959
|
-
text =
|
|
5037
|
+
text = readFileSync10(path, "utf-8");
|
|
4960
5038
|
} catch {
|
|
4961
5039
|
return null;
|
|
4962
5040
|
}
|
|
@@ -869,9 +869,10 @@ function prepareUploadArtifact(path) {
|
|
|
869
869
|
import ora from "ora";
|
|
870
870
|
function createSpinner(text, opts = {}) {
|
|
871
871
|
const isCI = process.env.CI === "true" || process.env.CI === "1" || !process.stdout.isTTY;
|
|
872
|
+
const drawable = process.stderr.isTTY === true && (process.stderr.columns ?? 0) > 0;
|
|
872
873
|
return ora({
|
|
873
874
|
text,
|
|
874
|
-
isEnabled: !isCI,
|
|
875
|
+
isEnabled: !isCI && drawable,
|
|
875
876
|
stream: process.stderr,
|
|
876
877
|
discardStdin: false,
|
|
877
878
|
isSilent: opts.silent === true
|
package/dist/cli.js
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
runAgentVerb,
|
|
36
36
|
runStepsNotChecked,
|
|
37
37
|
stepsNotCheckedLabel
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-6U4WMOVF.js";
|
|
39
39
|
import {
|
|
40
40
|
ApiClient,
|
|
41
41
|
ApiStatusError,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
runCommandParseExitCode,
|
|
59
59
|
saveConfig,
|
|
60
60
|
uploadApp
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-LRPZFDKL.js";
|
|
62
62
|
|
|
63
63
|
// src/cli.ts
|
|
64
64
|
import { createRequire } from "module";
|
|
@@ -2291,6 +2291,8 @@ The build may still be running server-side \u2014 resume watching it with \`vibe
|
|
|
2291
2291
|
id: final.id,
|
|
2292
2292
|
status: final.status,
|
|
2293
2293
|
cost_micro: final.cost_micro,
|
|
2294
|
+
included_minutes: final.included_minutes ?? null,
|
|
2295
|
+
billed_minutes: final.billed_minutes ?? null,
|
|
2294
2296
|
error_summary: final.error_summary
|
|
2295
2297
|
})
|
|
2296
2298
|
);
|
|
@@ -4518,7 +4520,7 @@ program.command("dev-reload").description(
|
|
|
4518
4520
|
program.command("mcp").description(
|
|
4519
4521
|
"Run an MCP stdio server exposing the agent verbs (tap, swipe, type, ...) plus dev_start/dev_stop/dev_reload as tools"
|
|
4520
4522
|
).option("--token <token>", "API token (or set VIBEVIEW_API_TOKEN)").action(async (opts) => {
|
|
4521
|
-
const { runMcpServer } = await import("./server-
|
|
4523
|
+
const { runMcpServer } = await import("./server-B4OVM2L7.js");
|
|
4522
4524
|
await runMcpServer({ ...opts, version: pkg.version });
|
|
4523
4525
|
});
|
|
4524
4526
|
program.command("agent-setup").description(
|
|
@@ -35,12 +35,12 @@ import {
|
|
|
35
35
|
renderEnvelope,
|
|
36
36
|
resolveMetro,
|
|
37
37
|
startDevSession
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-6U4WMOVF.js";
|
|
39
39
|
import {
|
|
40
40
|
ApiClient,
|
|
41
41
|
NotFoundError,
|
|
42
42
|
resolveAuth
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-LRPZFDKL.js";
|
|
44
44
|
|
|
45
45
|
// src/mcp/server.ts
|
|
46
46
|
import { writeFileSync } from "fs";
|
|
@@ -999,7 +999,7 @@ async function handleUploadApp(args, deps) {
|
|
|
999
999
|
}
|
|
1000
1000
|
const name = typeof args.name === "string" && args.name ? args.name : void 0;
|
|
1001
1001
|
const upload = deps.uploadApp ?? (async (f, n) => {
|
|
1002
|
-
const { uploadAppBuild } = await import("./upload-app-
|
|
1002
|
+
const { uploadAppBuild } = await import("./upload-app-OV3QKL7O.js");
|
|
1003
1003
|
const { result: result2 } = await uploadAppBuild(f, { ...deps.auth, name: n });
|
|
1004
1004
|
return result2;
|
|
1005
1005
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeview",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.1",
|
|
4
4
|
"description": "VibeView CLI -- run your app on cloud iOS simulators, Android emulators, Apple TV, Android TV and Roku 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",
|