vibeview 0.45.0 → 0.46.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.
@@ -796,6 +796,90 @@ function describeLocalChanges(before, after) {
796
796
 
797
797
  // src/commands/build.ts
798
798
  import { spawn as spawn2 } from "child_process";
799
+
800
+ // src/lib/build-source.ts
801
+ import { execFile } from "child_process";
802
+ import { readFileSync as readFileSync5 } from "fs";
803
+ import { promisify } from "util";
804
+ var COMMIT_RE = /^[0-9a-f]{7,64}$/;
805
+ function clean(source) {
806
+ const out = {};
807
+ const commit = source.commit?.trim().toLowerCase();
808
+ if (commit && COMMIT_RE.test(commit)) out.commit = commit;
809
+ const branch = source.branch?.trim().replace(/^refs\/heads\//, "");
810
+ if (branch && branch.length <= 255 && !/[\u0000-\u001f\u007f]/.test(branch)) {
811
+ out.branch = branch;
812
+ }
813
+ const url = source.ci_run_url?.trim();
814
+ if (url && url.length <= 2048 && url.startsWith("https://") && !/\s/.test(url)) {
815
+ out.ci_run_url = url;
816
+ }
817
+ return Object.keys(out).length ? out : void 0;
818
+ }
819
+ function pullRequestHeadSha(eventPath) {
820
+ if (!eventPath) return void 0;
821
+ try {
822
+ const event = JSON.parse(readFileSync5(eventPath, "utf8"));
823
+ const sha = event.pull_request?.head?.sha;
824
+ return typeof sha === "string" ? sha : void 0;
825
+ } catch {
826
+ return void 0;
827
+ }
828
+ }
829
+ function ciBuildSource(env = process.env) {
830
+ if (env.GITHUB_ACTIONS === "true") {
831
+ const run = env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY && env.GITHUB_RUN_ID ? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}` : void 0;
832
+ return clean({
833
+ commit: env.GITHUB_HEAD_REF && pullRequestHeadSha(env.GITHUB_EVENT_PATH) || env.GITHUB_SHA,
834
+ branch: env.GITHUB_HEAD_REF || env.GITHUB_REF_NAME,
835
+ ci_run_url: run
836
+ });
837
+ }
838
+ if (env.GITLAB_CI === "true") {
839
+ return clean({
840
+ commit: env.CI_COMMIT_SHA,
841
+ branch: env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME || env.CI_COMMIT_REF_NAME,
842
+ ci_run_url: env.CI_JOB_URL || env.CI_PIPELINE_URL
843
+ });
844
+ }
845
+ if (env.BITRISE_IO === "true") {
846
+ return clean({
847
+ commit: env.BITRISE_GIT_COMMIT || env.GIT_CLONE_COMMIT_HASH,
848
+ branch: env.BITRISE_GIT_BRANCH,
849
+ ci_run_url: env.BITRISE_BUILD_URL
850
+ });
851
+ }
852
+ if (env.CIRCLECI === "true") {
853
+ return clean({
854
+ commit: env.CIRCLE_SHA1,
855
+ branch: env.CIRCLE_BRANCH,
856
+ ci_run_url: env.CIRCLE_BUILD_URL
857
+ });
858
+ }
859
+ return void 0;
860
+ }
861
+ async function git(cwd, args) {
862
+ try {
863
+ const { stdout } = await promisify(execFile)("git", args, { cwd, timeout: 5e3 });
864
+ return stdout.trim();
865
+ } catch {
866
+ return void 0;
867
+ }
868
+ }
869
+ async function buildSource(cwd, env = process.env) {
870
+ const ci = ciBuildSource(env);
871
+ if (ci) return ci;
872
+ const commit = await git(cwd, ["rev-parse", "HEAD"]);
873
+ if (!commit) return void 0;
874
+ const branch = await git(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]);
875
+ const dirty = await git(cwd, ["status", "--porcelain"]);
876
+ return clean({
877
+ commit: dirty === "" ? commit : void 0,
878
+ branch: branch && branch !== "HEAD" ? branch : void 0
879
+ });
880
+ }
881
+
882
+ // src/commands/build.ts
799
883
  import { createInterface } from "readline";
800
884
  import { select as select2 } from "@inquirer/prompts";
801
885
  import chalk3 from "chalk";
@@ -805,13 +889,13 @@ import chalk2 from "chalk";
805
889
  import { input, select } from "@inquirer/prompts";
806
890
 
807
891
  // src/lib/project-detect.ts
808
- import { execFile } from "child_process";
809
- import { existsSync as existsSync3, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
892
+ import { execFile as execFile2 } from "child_process";
893
+ import { existsSync as existsSync3, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
810
894
  import { join as join5 } from "path";
811
895
  import ignore from "ignore";
812
896
  function readJson(cwd, name) {
813
897
  try {
814
- return JSON.parse(readFileSync5(join5(cwd, name), "utf-8"));
898
+ return JSON.parse(readFileSync6(join5(cwd, name), "utf-8"));
815
899
  } catch {
816
900
  return null;
817
901
  }
@@ -826,7 +910,7 @@ function isFile(path) {
826
910
  function detectFlavor(cwd) {
827
911
  let deps = {};
828
912
  try {
829
- const pkg = JSON.parse(readFileSync5(join5(cwd, "package.json"), "utf-8"));
913
+ const pkg = JSON.parse(readFileSync6(join5(cwd, "package.json"), "utf-8"));
830
914
  deps = { ...pkg.dependencies, ...pkg.devDependencies };
831
915
  } catch {
832
916
  }
@@ -851,7 +935,7 @@ var CAPACITOR_CONFIGS = ["capacitor.config.ts", "capacitor.config.js", "capacito
851
935
  function nativeDirShipped(cwd, dir) {
852
936
  if (!existsSync3(join5(cwd, dir))) return false;
853
937
  try {
854
- const ig = ignore().add(readFileSync5(join5(cwd, ".gitignore"), "utf-8"));
938
+ const ig = ignore().add(readFileSync6(join5(cwd, ".gitignore"), "utf-8"));
855
939
  return !ig.ignores(`${dir}/`);
856
940
  } catch {
857
941
  return true;
@@ -890,7 +974,7 @@ function dirShipped(cwd, rel) {
890
974
  if (slash !== -1) checks.push([rel.slice(0, slash), rel.slice(slash + 1)]);
891
975
  return checks.every(([dir, path]) => {
892
976
  try {
893
- return !ignore().add(readFileSync5(join5(cwd, dir, ".gitignore"), "utf-8")).ignores(`${path}/`);
977
+ return !ignore().add(readFileSync6(join5(cwd, dir, ".gitignore"), "utf-8")).ignores(`${path}/`);
894
978
  } catch {
895
979
  return true;
896
980
  }
@@ -986,7 +1070,7 @@ var FVM_CONFIGS = [".fvmrc", ".fvm/fvm_config.json"];
986
1070
  function flutterCommand(cwd) {
987
1071
  let ig = null;
988
1072
  try {
989
- ig = ignore().add(readFileSync5(join5(cwd, ".gitignore"), "utf-8"));
1073
+ ig = ignore().add(readFileSync6(join5(cwd, ".gitignore"), "utf-8"));
990
1074
  } catch {
991
1075
  }
992
1076
  const pinned = FVM_CONFIGS.some((f) => isFile(join5(cwd, f)) && !ig?.ignores(f));
@@ -1228,7 +1312,7 @@ function uniqueMatch(text, re) {
1228
1312
  }
1229
1313
  function readText(path) {
1230
1314
  try {
1231
- return readFileSync5(path, "utf-8");
1315
+ return readFileSync6(path, "utf-8");
1232
1316
  } catch {
1233
1317
  return null;
1234
1318
  }
@@ -1270,7 +1354,7 @@ var readExpoConfig = (cwd, timeoutMs = EXPO_CONFIG_TIMEOUT_MS) => {
1270
1354
  clearTimeout(timer);
1271
1355
  fn();
1272
1356
  };
1273
- const child = execFile(
1357
+ const child = execFile2(
1274
1358
  process.execPath,
1275
1359
  [cli, "config", "--json", "--type", "public"],
1276
1360
  {
@@ -1516,8 +1600,8 @@ async function promptMetroCommand(cwd, platform) {
1516
1600
  }
1517
1601
 
1518
1602
  // src/lib/source-pack.ts
1519
- import { execFile as execFile2, spawn } from "child_process";
1520
- import { lstatSync, mkdtempSync, readFileSync as readFileSync6, rmSync as rmSync5, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
1603
+ import { execFile as execFile3, spawn } from "child_process";
1604
+ import { lstatSync, mkdtempSync, readFileSync as readFileSync7, rmSync as rmSync5, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
1521
1605
  import { tmpdir } from "os";
1522
1606
  import { join as join6 } from "path";
1523
1607
  import ignore2 from "ignore";
@@ -1547,7 +1631,7 @@ async function listSourceFiles(projectRoot) {
1547
1631
  let filtered = rawPaths;
1548
1632
  const vvignorePath = join6(projectRoot, ".vvignore");
1549
1633
  if (statOrNull(vvignorePath)?.isFile()) {
1550
- const ig = ignore2().add(readFileSync6(vvignorePath, "utf-8"));
1634
+ const ig = ignore2().add(readFileSync7(vvignorePath, "utf-8"));
1551
1635
  filtered = filtered.filter((p) => !ig.ignores(p));
1552
1636
  }
1553
1637
  const result = [];
@@ -1655,7 +1739,7 @@ function probeTarNullSupport() {
1655
1739
  const listPath = join6(tmp, "empty.list");
1656
1740
  writeFileSync5(listPath, "");
1657
1741
  const out = join6(tmp, "probe.tgz");
1658
- execFile2("tar", ["-czf", out, "-C", tmp, "--null", "-T", listPath], (err) => {
1742
+ execFile3("tar", ["-czf", out, "-C", tmp, "--null", "-T", listPath], (err) => {
1659
1743
  rmSync5(tmp, { recursive: true, force: true });
1660
1744
  resolve(!err);
1661
1745
  });
@@ -1686,7 +1770,7 @@ function runTar(args) {
1686
1770
  }
1687
1771
 
1688
1772
  // src/lib/build-preflight.ts
1689
- import { execFile as execFile3 } from "child_process";
1773
+ import { execFile as execFile4 } from "child_process";
1690
1774
  import { realpathSync, statSync as statSync4 } from "fs";
1691
1775
  import { dirname as dirname2, isAbsolute, join as join7, relative } from "path";
1692
1776
  import { parse } from "shell-quote";
@@ -1876,7 +1960,7 @@ function isFile2(path) {
1876
1960
  }
1877
1961
  async function gitToplevel(cwd) {
1878
1962
  return new Promise((resolve) => {
1879
- execFile3("git", ["rev-parse", "--show-toplevel"], { cwd }, (err, stdout) => {
1963
+ execFile4("git", ["rev-parse", "--show-toplevel"], { cwd }, (err, stdout) => {
1880
1964
  resolve(err ? null : stdout.trim() || null);
1881
1965
  });
1882
1966
  });
@@ -2291,6 +2375,7 @@ function defaultCloudBuildDeps(client) {
2291
2375
  packSource,
2292
2376
  listApps: client.listApps.bind(client),
2293
2377
  createCloudBuilds: client.createCloudBuilds.bind(client),
2378
+ buildSource,
2294
2379
  getCloudBuildLogs: client.getCloudBuildLogs.bind(client),
2295
2380
  getCloudBuild: client.getCloudBuild.bind(client),
2296
2381
  downloadCloudBuildArtifact: client.downloadCloudBuildArtifact.bind(client)
@@ -2420,7 +2505,11 @@ ${offenders}`);
2420
2505
  uploadSpinner?.start();
2421
2506
  let created;
2422
2507
  try {
2423
- const resp = await d.createCloudBuilds({ builds: manifestEntries }, tarPath);
2508
+ const source = d.buildSource ? await d.buildSource(cwd) : void 0;
2509
+ const resp = await d.createCloudBuilds(
2510
+ source ? { builds: manifestEntries, source } : { builds: manifestEntries },
2511
+ tarPath
2512
+ );
2424
2513
  created = resp.builds;
2425
2514
  } catch (err) {
2426
2515
  uploadSpinner?.stop();
@@ -2744,7 +2833,7 @@ your build command must produce a zip \u2014 use the package/zip step, not deplo
2744
2833
 
2745
2834
  // src/commands/dev.ts
2746
2835
  import { spawn as spawn4 } from "child_process";
2747
- import { closeSync, createWriteStream, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync8 } from "fs";
2836
+ import { closeSync, createWriteStream, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync9 } from "fs";
2748
2837
  import { dirname as dirname5, join as join9 } from "path";
2749
2838
  import { createInterface as createInterface3 } from "readline";
2750
2839
  import { stripVTControlCharacters } from "util";
@@ -2948,7 +3037,7 @@ import { spawn as spawn3 } from "child_process";
2948
3037
  import { createInterface as createInterface2 } from "readline";
2949
3038
 
2950
3039
  // src/lib/metro-state.ts
2951
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync7, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
3040
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync8, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
2952
3041
  import { dirname as dirname3, join as join8 } from "path";
2953
3042
  var STATE_DIR2 = ".vibeview";
2954
3043
  var STATE_FILE2 = "metro-state.json";
@@ -2974,7 +3063,7 @@ function writeMetroState(cwd, state) {
2974
3063
  function readMetroState(cwd) {
2975
3064
  let parsed;
2976
3065
  try {
2977
- parsed = JSON.parse(readFileSync7(statePath2(cwd), "utf-8"));
3066
+ parsed = JSON.parse(readFileSync8(statePath2(cwd), "utf-8"));
2978
3067
  } catch {
2979
3068
  return null;
2980
3069
  }
@@ -4483,7 +4572,7 @@ function openDetachLog(path) {
4483
4572
  function lastErrorLine(path) {
4484
4573
  let text;
4485
4574
  try {
4486
- text = readFileSync8(path, "utf-8");
4575
+ text = readFileSync9(path, "utf-8");
4487
4576
  } catch {
4488
4577
  return null;
4489
4578
  }
package/dist/cli.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  runAgentVerb,
31
31
  runStepsNotChecked,
32
32
  stepsNotCheckedLabel
33
- } from "./chunk-YF4L2WO2.js";
33
+ } from "./chunk-NHM2FHA2.js";
34
34
  import {
35
35
  ApiClient,
36
36
  ApiStatusError,
@@ -4461,7 +4461,7 @@ program.command("dev-reload").description(
4461
4461
  program.command("mcp").description(
4462
4462
  "Run an MCP stdio server exposing the agent verbs (tap, swipe, type, ...) plus dev_start/dev_stop/dev_reload as tools"
4463
4463
  ).option("--token <token>", "API token (or set VIBEVIEW_API_TOKEN)").action(async (opts) => {
4464
- const { runMcpServer } = await import("./server-LC2EYAPO.js");
4464
+ const { runMcpServer } = await import("./server-W66J6PY5.js");
4465
4465
  await runMcpServer({ ...opts, version: pkg.version });
4466
4466
  });
4467
4467
  program.command("agent-setup").description(
@@ -30,7 +30,7 @@ import {
30
30
  renderEnvelope,
31
31
  resolveMetro,
32
32
  startDevSession
33
- } from "./chunk-YF4L2WO2.js";
33
+ } from "./chunk-NHM2FHA2.js";
34
34
  import {
35
35
  ApiClient,
36
36
  NotFoundError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeview",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
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",