@yoqa/runner 1.0.3 → 1.0.5
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/index.js +207 -188
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18066,9 +18066,47 @@ var require_src5 = __commonJS((exports) => {
|
|
|
18066
18066
|
|
|
18067
18067
|
// src/domains/android-toolchain/android-sdk.ts
|
|
18068
18068
|
import { existsSync } from "fs";
|
|
18069
|
+
import { homedir as homedir2 } from "os";
|
|
18070
|
+
import { posix as posix2, win32 as win322 } from "path";
|
|
18071
|
+
|
|
18072
|
+
// src/domains/android-toolchain/host-path.ts
|
|
18069
18073
|
import { homedir } from "os";
|
|
18070
|
-
import {
|
|
18071
|
-
function
|
|
18074
|
+
import { posix, win32 } from "path";
|
|
18075
|
+
function pathDelimiter(platform = process.platform) {
|
|
18076
|
+
return platform === "win32" ? win32.delimiter : posix.delimiter;
|
|
18077
|
+
}
|
|
18078
|
+
function prependPathEntries(currentPath, entries, platform = process.platform) {
|
|
18079
|
+
const delimiter = pathDelimiter(platform);
|
|
18080
|
+
const existing = currentPath.split(delimiter).filter(Boolean);
|
|
18081
|
+
const prepend = entries.filter((dir) => !existing.includes(dir));
|
|
18082
|
+
return [...prepend, ...existing].join(delimiter);
|
|
18083
|
+
}
|
|
18084
|
+
function pathWithHostTools(currentPath = process.env.PATH ?? "", home = homedir(), platform = process.platform) {
|
|
18085
|
+
const { join } = platform === "win32" ? win32 : posix;
|
|
18086
|
+
const extras = [
|
|
18087
|
+
...platform === "win32" ? [] : ["/opt/homebrew/bin", "/opt/homebrew/sbin", "/usr/local/bin"],
|
|
18088
|
+
join(home, ".local", "bin"),
|
|
18089
|
+
join(home, ".bun", "bin"),
|
|
18090
|
+
join(home, ".opencode", "bin"),
|
|
18091
|
+
join(home, ".grok", "bin"),
|
|
18092
|
+
join(home, ".antigravity", "antigravity", "bin")
|
|
18093
|
+
];
|
|
18094
|
+
return prependPathEntries(currentPath, extras, platform);
|
|
18095
|
+
}
|
|
18096
|
+
var hostToolPathReady = false;
|
|
18097
|
+
function ensureHostToolPath() {
|
|
18098
|
+
if (hostToolPathReady)
|
|
18099
|
+
return;
|
|
18100
|
+
hostToolPathReady = true;
|
|
18101
|
+
process.env.PATH = pathWithHostTools();
|
|
18102
|
+
}
|
|
18103
|
+
|
|
18104
|
+
// src/domains/android-toolchain/android-sdk.ts
|
|
18105
|
+
function pathModule(platform) {
|
|
18106
|
+
return platform === "win32" ? win322 : posix2;
|
|
18107
|
+
}
|
|
18108
|
+
function defaultAndroidSdkRoot(home = homedir2(), platform = process.platform, localAppData) {
|
|
18109
|
+
const { join } = pathModule(platform);
|
|
18072
18110
|
if (platform === "win32") {
|
|
18073
18111
|
const base = localAppData || join(home, "AppData", "Local");
|
|
18074
18112
|
return join(base, "Android", "Sdk");
|
|
@@ -18079,6 +18117,7 @@ function defaultAndroidSdkRoot(home = homedir(), platform = process.platform, lo
|
|
|
18079
18117
|
return join(home, "Android", "Sdk");
|
|
18080
18118
|
}
|
|
18081
18119
|
function defaultJavaHomeCandidates(home, platform = process.platform) {
|
|
18120
|
+
const { join } = pathModule(platform);
|
|
18082
18121
|
if (platform === "darwin") {
|
|
18083
18122
|
return [
|
|
18084
18123
|
join("/Applications", "Android Studio.app", "Contents", "jbr", "Contents", "Home"),
|
|
@@ -18101,28 +18140,29 @@ function resolveAndroidSdkRoot(env = {
|
|
|
18101
18140
|
const fromEnv = env.ANDROID_HOME?.trim() || env.ANDROID_SDK_ROOT?.trim();
|
|
18102
18141
|
if (fromEnv)
|
|
18103
18142
|
return fromEnv;
|
|
18104
|
-
const home = options?.home ??
|
|
18143
|
+
const home = options?.home ?? homedir2();
|
|
18105
18144
|
const platform = options?.platform ?? process.platform;
|
|
18106
18145
|
return defaultAndroidSdkRoot(home, platform, options?.localAppData);
|
|
18107
18146
|
}
|
|
18108
|
-
function androidSdkBinDirs(sdkRoot) {
|
|
18147
|
+
function androidSdkBinDirs(sdkRoot, platform = process.platform) {
|
|
18148
|
+
const { join } = pathModule(platform);
|
|
18109
18149
|
return [
|
|
18110
18150
|
join(sdkRoot, "platform-tools"),
|
|
18111
18151
|
join(sdkRoot, "cmdline-tools", "latest", "bin"),
|
|
18112
18152
|
join(sdkRoot, "emulator")
|
|
18113
18153
|
];
|
|
18114
18154
|
}
|
|
18115
|
-
function
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
return
|
|
18155
|
+
function androidSdkToolPath(sdkRoot, subdir, name, platform = process.platform) {
|
|
18156
|
+
return pathModule(platform).join(sdkRoot, subdir, platform === "win32" ? `${name}.exe` : name);
|
|
18157
|
+
}
|
|
18158
|
+
function pathWithAndroidSdk(currentPath, sdkRoot, platform = process.platform) {
|
|
18159
|
+
return prependPathEntries(currentPath, androidSdkBinDirs(sdkRoot, platform), platform);
|
|
18120
18160
|
}
|
|
18121
18161
|
function androidSdkEnvPatch(env, options) {
|
|
18122
18162
|
const patch = {};
|
|
18123
18163
|
const resolved = resolveAndroidSdkRoot(env, options);
|
|
18124
18164
|
if (resolved && options.pathExists(resolved)) {
|
|
18125
|
-
patch.PATH = pathWithAndroidSdk(env.PATH ?? "", resolved);
|
|
18165
|
+
patch.PATH = pathWithAndroidSdk(env.PATH ?? "", resolved, options.platform);
|
|
18126
18166
|
if (!env.ANDROID_HOME?.trim() && !env.ANDROID_SDK_ROOT?.trim()) {
|
|
18127
18167
|
patch.ANDROID_HOME = resolved;
|
|
18128
18168
|
patch.ANDROID_SDK_ROOT = resolved;
|
|
@@ -18165,7 +18205,7 @@ function androidProcessEnv(env = process.env, options) {
|
|
|
18165
18205
|
JAVA_HOME: next.JAVA_HOME,
|
|
18166
18206
|
PATH: next.PATH
|
|
18167
18207
|
}, {
|
|
18168
|
-
home: options?.home ??
|
|
18208
|
+
home: options?.home ?? homedir2(),
|
|
18169
18209
|
platform: options?.platform ?? process.platform,
|
|
18170
18210
|
localAppData: next.LOCALAPPDATA,
|
|
18171
18211
|
pathExists: options?.pathExists ?? existsSync
|
|
@@ -18184,37 +18224,11 @@ function ensureAndroidSdkEnv() {
|
|
|
18184
18224
|
process.env.PATH = next.PATH;
|
|
18185
18225
|
}
|
|
18186
18226
|
|
|
18187
|
-
// src/domains/android-toolchain/host-path.ts
|
|
18188
|
-
import { homedir as homedir2 } from "os";
|
|
18189
|
-
import { join as join2 } from "path";
|
|
18190
|
-
function pathWithHostTools(currentPath = process.env.PATH ?? "", home = homedir2()) {
|
|
18191
|
-
const extras = [
|
|
18192
|
-
"/opt/homebrew/bin",
|
|
18193
|
-
"/opt/homebrew/sbin",
|
|
18194
|
-
"/usr/local/bin",
|
|
18195
|
-
join2(home, ".local", "bin"),
|
|
18196
|
-
join2(home, ".bun", "bin"),
|
|
18197
|
-
join2(home, ".opencode", "bin"),
|
|
18198
|
-
join2(home, ".grok", "bin"),
|
|
18199
|
-
join2(home, ".antigravity", "antigravity", "bin")
|
|
18200
|
-
];
|
|
18201
|
-
const existing = currentPath.split(":").filter(Boolean);
|
|
18202
|
-
const prepend = extras.filter((dir) => !existing.includes(dir));
|
|
18203
|
-
return [...prepend, ...existing].join(":");
|
|
18204
|
-
}
|
|
18205
|
-
var hostToolPathReady = false;
|
|
18206
|
-
function ensureHostToolPath() {
|
|
18207
|
-
if (hostToolPathReady)
|
|
18208
|
-
return;
|
|
18209
|
-
hostToolPathReady = true;
|
|
18210
|
-
process.env.PATH = pathWithHostTools();
|
|
18211
|
-
}
|
|
18212
|
-
|
|
18213
18227
|
// src/domains/catalog/db.ts
|
|
18214
18228
|
import { Database as Database2 } from "bun:sqlite";
|
|
18215
18229
|
import { mkdirSync } from "fs";
|
|
18216
18230
|
import { homedir as homedir3 } from "os";
|
|
18217
|
-
import { dirname, join
|
|
18231
|
+
import { dirname, join } from "path";
|
|
18218
18232
|
|
|
18219
18233
|
// ../../node_modules/drizzle-orm/bun-sqlite/driver.js
|
|
18220
18234
|
import { Database } from "bun:sqlite";
|
|
@@ -18850,7 +18864,7 @@ function sql(strings, ...params) {
|
|
|
18850
18864
|
return new SQL([new StringChunk(str)]);
|
|
18851
18865
|
}
|
|
18852
18866
|
sql2.raw = raw;
|
|
18853
|
-
function
|
|
18867
|
+
function join(chunks, separator) {
|
|
18854
18868
|
const result = [];
|
|
18855
18869
|
for (const [i, chunk] of chunks.entries()) {
|
|
18856
18870
|
if (i > 0 && separator !== undefined) {
|
|
@@ -18860,7 +18874,7 @@ function sql(strings, ...params) {
|
|
|
18860
18874
|
}
|
|
18861
18875
|
return new SQL(result);
|
|
18862
18876
|
}
|
|
18863
|
-
sql2.join =
|
|
18877
|
+
sql2.join = join;
|
|
18864
18878
|
function identifier(value) {
|
|
18865
18879
|
return new Name(value);
|
|
18866
18880
|
}
|
|
@@ -21094,7 +21108,7 @@ class SQLiteSelectQueryBuilderBase extends TypedQueryBuilder {
|
|
|
21094
21108
|
const tableName = getTableLikeName(table);
|
|
21095
21109
|
for (const item of extractUsedTable(table))
|
|
21096
21110
|
this.usedTables.add(item);
|
|
21097
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
21111
|
+
if (typeof tableName === "string" && this.config.joins?.some((join) => join.alias === tableName)) {
|
|
21098
21112
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
21099
21113
|
}
|
|
21100
21114
|
if (!this.isPartialSelect) {
|
|
@@ -21508,7 +21522,7 @@ class SQLiteUpdateBase extends QueryPromise {
|
|
|
21508
21522
|
createJoin(joinType) {
|
|
21509
21523
|
return (table, on) => {
|
|
21510
21524
|
const tableName = getTableLikeName(table);
|
|
21511
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
21525
|
+
if (typeof tableName === "string" && this.config.joins.some((join) => join.alias === tableName)) {
|
|
21512
21526
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
21513
21527
|
}
|
|
21514
21528
|
if (typeof on === "function") {
|
|
@@ -22376,8 +22390,8 @@ var runSteps = sqliteTable("run_steps", {
|
|
|
22376
22390
|
|
|
22377
22391
|
// src/domains/catalog/db.ts
|
|
22378
22392
|
var drizzleSchema = { ...exports_schema3, ...exports_schema2, ...exports_schema4, ...exports_schema };
|
|
22379
|
-
var YOQA_ROOT =
|
|
22380
|
-
var DEFAULT_DB_PATH =
|
|
22393
|
+
var YOQA_ROOT = join(homedir3(), ".yoqa");
|
|
22394
|
+
var DEFAULT_DB_PATH = join(YOQA_ROOT, "yoqa.db");
|
|
22381
22395
|
var catalogDb = null;
|
|
22382
22396
|
var sqliteClient = null;
|
|
22383
22397
|
function ensureSchema(sqlite) {
|
|
@@ -22719,7 +22733,7 @@ function getCatalogDb() {
|
|
|
22719
22733
|
}
|
|
22720
22734
|
|
|
22721
22735
|
// src/domains/runs/application.ts
|
|
22722
|
-
import { existsSync as
|
|
22736
|
+
import { existsSync as existsSync10 } from "fs";
|
|
22723
22737
|
|
|
22724
22738
|
// ../../node_modules/zod/v3/external.js
|
|
22725
22739
|
var exports_external = {};
|
|
@@ -27838,9 +27852,10 @@ function startTargetRequest(platform, target) {
|
|
|
27838
27852
|
import { basename, extname } from "path";
|
|
27839
27853
|
|
|
27840
27854
|
// src/domains/devices/application.ts
|
|
27855
|
+
import { existsSync as existsSync2 } from "fs";
|
|
27841
27856
|
import { mkdtemp as mkdtemp2, readFile as readFile2, rm as rm2 } from "fs/promises";
|
|
27842
27857
|
import { tmpdir as tmpdir2 } from "os";
|
|
27843
|
-
import { join as
|
|
27858
|
+
import { isAbsolute, join as join3 } from "path";
|
|
27844
27859
|
|
|
27845
27860
|
// src/domains/devices/android-identity.ts
|
|
27846
27861
|
function matchAndroidIdentity(deviceId, connected, knownAvds = []) {
|
|
@@ -27872,7 +27887,7 @@ function parseAdbEmuAvdName(stdout) {
|
|
|
27872
27887
|
import { constants } from "fs";
|
|
27873
27888
|
import { access, mkdtemp, readFile, rm } from "fs/promises";
|
|
27874
27889
|
import { homedir as homedir4, tmpdir } from "os";
|
|
27875
|
-
import { join as
|
|
27890
|
+
import { join as join2 } from "path";
|
|
27876
27891
|
var KNOWN_BROWSERS = [
|
|
27877
27892
|
{ id: "web-chrome", name: "Google Chrome", app: "Google Chrome" },
|
|
27878
27893
|
{ id: "web-edge", name: "Microsoft Edge", app: "Microsoft Edge" },
|
|
@@ -27892,17 +27907,17 @@ function discoveryDeps() {
|
|
|
27892
27907
|
}
|
|
27893
27908
|
var VERSION_RE = /<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/;
|
|
27894
27909
|
async function bundleVersion(appPath, deps) {
|
|
27895
|
-
const plist = await deps.readText(
|
|
27910
|
+
const plist = await deps.readText(join2(appPath, "Contents/Info.plist")).catch(() => "");
|
|
27896
27911
|
return VERSION_RE.exec(plist)?.[1]?.trim() || null;
|
|
27897
27912
|
}
|
|
27898
27913
|
async function findInstalledBrowsers(deps = discoveryDeps()) {
|
|
27899
27914
|
if (deps.platform !== "darwin")
|
|
27900
27915
|
return [];
|
|
27901
|
-
const roots = ["/Applications",
|
|
27916
|
+
const roots = ["/Applications", join2(deps.home, "Applications")];
|
|
27902
27917
|
const found = await Promise.all(KNOWN_BROWSERS.map(async ({ id, name, app }) => {
|
|
27903
27918
|
for (const root of roots) {
|
|
27904
|
-
const appPath =
|
|
27905
|
-
const executable =
|
|
27919
|
+
const appPath = join2(root, `${app}.app`);
|
|
27920
|
+
const executable = join2(appPath, "Contents/MacOS", app);
|
|
27906
27921
|
if (!await deps.isExecutable(executable))
|
|
27907
27922
|
continue;
|
|
27908
27923
|
return { id, name, version: await bundleVersion(appPath, deps), executable };
|
|
@@ -27947,7 +27962,7 @@ function spawnBrowser(command) {
|
|
|
27947
27962
|
return Bun.spawn(command, { stdin: "ignore", stdout: "ignore", stderr: "pipe" });
|
|
27948
27963
|
}
|
|
27949
27964
|
async function readActivePort(profileDir) {
|
|
27950
|
-
const text2 = await readFile(
|
|
27965
|
+
const text2 = await readFile(join2(profileDir, "DevToolsActivePort"), "utf8").catch(() => "");
|
|
27951
27966
|
const [port, path] = text2.split(`
|
|
27952
27967
|
`).map((line) => line.trim());
|
|
27953
27968
|
if (!port || !/^\d+$/.test(port) || !path?.startsWith("/"))
|
|
@@ -27957,7 +27972,7 @@ async function readActivePort(profileDir) {
|
|
|
27957
27972
|
async function launchChromium(browser, deps = {}) {
|
|
27958
27973
|
const spawn = deps.spawn ?? spawnBrowser;
|
|
27959
27974
|
const readyTimeoutMs = deps.readyTimeoutMs ?? READY_TIMEOUT_MS;
|
|
27960
|
-
const profileDir = await mkdtemp(
|
|
27975
|
+
const profileDir = await mkdtemp(join2(tmpdir(), "yoqa-web-"));
|
|
27961
27976
|
const removeProfile = () => rm(profileDir, { recursive: true, force: true });
|
|
27962
27977
|
let proc;
|
|
27963
27978
|
try {
|
|
@@ -28134,19 +28149,27 @@ async function resolveTool(candidates) {
|
|
|
28134
28149
|
for (const candidate of candidates) {
|
|
28135
28150
|
if (!candidate)
|
|
28136
28151
|
continue;
|
|
28137
|
-
|
|
28138
|
-
|
|
28139
|
-
|
|
28152
|
+
if (isAbsolute(candidate)) {
|
|
28153
|
+
if (existsSync2(candidate))
|
|
28154
|
+
return candidate;
|
|
28155
|
+
continue;
|
|
28156
|
+
}
|
|
28157
|
+
const onPath = Bun.which(candidate);
|
|
28158
|
+
if (onPath)
|
|
28159
|
+
return onPath;
|
|
28140
28160
|
}
|
|
28141
28161
|
return null;
|
|
28142
28162
|
}
|
|
28143
28163
|
async function resolveAdb() {
|
|
28144
28164
|
const sdk = androidSdkRoot();
|
|
28145
|
-
return resolveTool([...sdk ? [
|
|
28165
|
+
return resolveTool([...sdk ? [androidSdkToolPath(sdk, "platform-tools", "adb")] : [], "adb"]);
|
|
28146
28166
|
}
|
|
28147
28167
|
async function resolveEmulator() {
|
|
28148
28168
|
const sdk = androidSdkRoot();
|
|
28149
|
-
return resolveTool([
|
|
28169
|
+
return resolveTool([
|
|
28170
|
+
...sdk ? [androidSdkToolPath(sdk, "emulator", "emulator")] : [],
|
|
28171
|
+
"emulator"
|
|
28172
|
+
]);
|
|
28150
28173
|
}
|
|
28151
28174
|
function formatIosVersion2(version2) {
|
|
28152
28175
|
const trimmed = version2.trim();
|
|
@@ -28250,8 +28273,8 @@ async function readDevicectlDevices(jsonPath) {
|
|
|
28250
28273
|
}
|
|
28251
28274
|
}
|
|
28252
28275
|
async function listIosPhysicalDevices(includeUnavailable) {
|
|
28253
|
-
const dir = await mkdtemp2(
|
|
28254
|
-
const jsonPath =
|
|
28276
|
+
const dir = await mkdtemp2(join3(tmpdir2(), "yoqa-devices-"));
|
|
28277
|
+
const jsonPath = join3(dir, "devices.json");
|
|
28255
28278
|
try {
|
|
28256
28279
|
let parsed = await readDevicectlDevices(jsonPath);
|
|
28257
28280
|
if (parsed === null)
|
|
@@ -28315,9 +28338,9 @@ function humanizeModel(model) {
|
|
|
28315
28338
|
}
|
|
28316
28339
|
async function findAvdConfigPath(avdName) {
|
|
28317
28340
|
const home = process.env.HOME ?? "";
|
|
28318
|
-
const roots = [
|
|
28341
|
+
const roots = [join3(home, ".android/avd"), join3(home, "Library/Android/sdk/.android/avd")];
|
|
28319
28342
|
for (const root of roots) {
|
|
28320
|
-
const direct =
|
|
28343
|
+
const direct = join3(root, `${avdName}.avd`, "config.ini");
|
|
28321
28344
|
try {
|
|
28322
28345
|
await readFile2(direct, "utf8");
|
|
28323
28346
|
return direct;
|
|
@@ -28325,7 +28348,7 @@ async function findAvdConfigPath(avdName) {
|
|
|
28325
28348
|
try {
|
|
28326
28349
|
const glob = new Bun.Glob("*.avd/config.ini");
|
|
28327
28350
|
for await (const match of glob.scan({ cwd: root, onlyFiles: true })) {
|
|
28328
|
-
const path =
|
|
28351
|
+
const path = join3(root, match);
|
|
28329
28352
|
const text2 = await readFile2(path, "utf8");
|
|
28330
28353
|
const idLine = text2.split(`
|
|
28331
28354
|
`).find((line) => line.startsWith("AvdId="));
|
|
@@ -28854,7 +28877,7 @@ function normalizeVisionJson(value) {
|
|
|
28854
28877
|
import { mkdtemp as mkdtemp3, readFile as readFile3, rm as rm3, writeFile } from "fs/promises";
|
|
28855
28878
|
import { homedir as homedir5 } from "os";
|
|
28856
28879
|
import { tmpdir as tmpdir3 } from "os";
|
|
28857
|
-
import { join as
|
|
28880
|
+
import { join as join4 } from "path";
|
|
28858
28881
|
|
|
28859
28882
|
// ../../node_modules/@ai-sdk/gateway/node_modules/@ai-sdk/provider/dist/index.js
|
|
28860
28883
|
var marker = "vercel.ai.error";
|
|
@@ -51531,9 +51554,9 @@ async function prepareVisionImage(pngBase64) {
|
|
|
51531
51554
|
if (process.platform !== "darwin") {
|
|
51532
51555
|
return { base64: pngBase64, mediaType: "image/png" };
|
|
51533
51556
|
}
|
|
51534
|
-
const dir = await mkdtemp3(
|
|
51535
|
-
const inPath =
|
|
51536
|
-
const outPath =
|
|
51557
|
+
const dir = await mkdtemp3(join4(tmpdir3(), "yoqa-vision-"));
|
|
51558
|
+
const inPath = join4(dir, "shot.png");
|
|
51559
|
+
const outPath = join4(dir, "shot.jpg");
|
|
51537
51560
|
try {
|
|
51538
51561
|
await writeFile(inPath, new Uint8Array(bytes));
|
|
51539
51562
|
const proc = Bun.spawn([
|
|
@@ -51749,8 +51772,8 @@ function openCodeAuthPaths() {
|
|
|
51749
51772
|
const paths = [];
|
|
51750
51773
|
const xdg = process.env.XDG_DATA_HOME?.trim();
|
|
51751
51774
|
if (xdg)
|
|
51752
|
-
paths.push(
|
|
51753
|
-
paths.push(
|
|
51775
|
+
paths.push(join4(xdg, "opencode", "auth.json"));
|
|
51776
|
+
paths.push(join4(homedir5(), ".local", "share", "opencode", "auth.json"));
|
|
51754
51777
|
return paths;
|
|
51755
51778
|
}
|
|
51756
51779
|
function apiKeyFromOpenCodeAuthEntry(value) {
|
|
@@ -60962,7 +60985,7 @@ var anthropic = createAnthropic();
|
|
|
60962
60985
|
import { constants as constants2 } from "fs";
|
|
60963
60986
|
import { access as access2 } from "fs/promises";
|
|
60964
60987
|
import { homedir as homedir6 } from "os";
|
|
60965
|
-
import { isAbsolute, join as
|
|
60988
|
+
import { isAbsolute as isAbsolute2, join as join5 } from "path";
|
|
60966
60989
|
async function pathExists(path) {
|
|
60967
60990
|
try {
|
|
60968
60991
|
await access2(path, constants2.F_OK);
|
|
@@ -60989,11 +61012,11 @@ async function which(binary) {
|
|
|
60989
61012
|
}
|
|
60990
61013
|
function knownHomeBinCandidates(binaryName, home = homedir6()) {
|
|
60991
61014
|
return [
|
|
60992
|
-
|
|
60993
|
-
|
|
60994
|
-
|
|
60995
|
-
|
|
60996
|
-
|
|
61015
|
+
join5(home, ".opencode", "bin", binaryName),
|
|
61016
|
+
join5(home, ".grok", "bin", binaryName),
|
|
61017
|
+
join5(home, ".antigravity", "antigravity", "bin", binaryName),
|
|
61018
|
+
join5(home, ".local", "bin", binaryName),
|
|
61019
|
+
join5(home, ".bun", "bin", binaryName),
|
|
60997
61020
|
`/opt/homebrew/bin/${binaryName}`,
|
|
60998
61021
|
`/usr/local/bin/${binaryName}`
|
|
60999
61022
|
];
|
|
@@ -61008,7 +61031,7 @@ async function resolveFromKnownBins(binaryName) {
|
|
|
61008
61031
|
}
|
|
61009
61032
|
async function resolveBinary(defaultName, binaryPath) {
|
|
61010
61033
|
const candidate = binaryPath?.trim() || defaultName;
|
|
61011
|
-
if (
|
|
61034
|
+
if (isAbsolute2(candidate) || candidate.includes("/")) {
|
|
61012
61035
|
if (await pathExists(candidate)) {
|
|
61013
61036
|
return { path: candidate, detail: `Found at ${candidate}` };
|
|
61014
61037
|
}
|
|
@@ -61260,7 +61283,7 @@ function resolveAgyModelId(raw, fallback = ANTIGRAVITY_DEFAULT_VISION_MODEL) {
|
|
|
61260
61283
|
// src/domains/providers/drivers/antigravity-vision.ts
|
|
61261
61284
|
import { mkdtemp as mkdtemp4, rm as rm4, writeFile as writeFile2 } from "fs/promises";
|
|
61262
61285
|
import { tmpdir as tmpdir4 } from "os";
|
|
61263
|
-
import { join as
|
|
61286
|
+
import { join as join6 } from "path";
|
|
61264
61287
|
|
|
61265
61288
|
// ../../node_modules/@ai-sdk/google/node_modules/@ai-sdk/provider/dist/index.js
|
|
61266
61289
|
var marker29 = "vercel.ai.error";
|
|
@@ -70735,8 +70758,8 @@ async function completeWithAgyCli(input, repairHint) {
|
|
|
70735
70758
|
const image = input.image ?? await prepareVisionImage(input.imageBase64);
|
|
70736
70759
|
const model = resolveAgyModelId(input.auth.defaultModel);
|
|
70737
70760
|
const ext = image.mediaType === "image/jpeg" ? "jpg" : "png";
|
|
70738
|
-
const dir = await mkdtemp4(
|
|
70739
|
-
const shotPath =
|
|
70761
|
+
const dir = await mkdtemp4(join6(tmpdir4(), "yoqa-agy-"));
|
|
70762
|
+
const shotPath = join6(dir, `shot.${ext}`);
|
|
70740
70763
|
try {
|
|
70741
70764
|
await writeFile2(shotPath, new Uint8Array(Buffer.from(image.base64, "base64")));
|
|
70742
70765
|
const userText = [
|
|
@@ -79246,7 +79269,7 @@ ${result.stderr}`.toLowerCase();
|
|
|
79246
79269
|
// src/domains/providers/drivers/cursor-vision.ts
|
|
79247
79270
|
import { mkdtemp as mkdtemp5, rm as rm5, writeFile as writeFile3 } from "fs/promises";
|
|
79248
79271
|
import { tmpdir as tmpdir5 } from "os";
|
|
79249
|
-
import { join as
|
|
79272
|
+
import { join as join7 } from "path";
|
|
79250
79273
|
var CURSOR_DEFAULT_VISION_MODEL = "auto";
|
|
79251
79274
|
var JSON_REPAIR_PROMPT3 = "Your previous reply was not valid JSON for this task. Reply again with ONLY one strict JSON object using double quotes for every key and string (no single quotes, no markdown, no prose).";
|
|
79252
79275
|
function resolveCursorApiKey(auth) {
|
|
@@ -79259,8 +79282,8 @@ async function invokeCursorPrint(input) {
|
|
|
79259
79282
|
}
|
|
79260
79283
|
const model = input.auth.defaultModel?.trim() || CURSOR_DEFAULT_VISION_MODEL;
|
|
79261
79284
|
const ext = input.mediaType === "image/jpeg" ? "jpg" : "png";
|
|
79262
|
-
const dir = await mkdtemp5(
|
|
79263
|
-
const shotPath =
|
|
79285
|
+
const dir = await mkdtemp5(join7(tmpdir5(), "yoqa-cursor-"));
|
|
79286
|
+
const shotPath = join7(dir, `shot.${ext}`);
|
|
79264
79287
|
const apiKey = resolveCursorApiKey(input.auth);
|
|
79265
79288
|
try {
|
|
79266
79289
|
await writeFile3(shotPath, new Uint8Array(Buffer.from(input.imageBase64, "base64")));
|
|
@@ -99390,7 +99413,7 @@ var openaiDriver = {
|
|
|
99390
99413
|
|
|
99391
99414
|
// src/domains/providers/drivers/opencode-config.ts
|
|
99392
99415
|
import { homedir as homedir7 } from "os";
|
|
99393
|
-
import { join as
|
|
99416
|
+
import { join as join8 } from "path";
|
|
99394
99417
|
var OPENAI_COMPATIBLE_PACKAGES = new Set([
|
|
99395
99418
|
"@ai-sdk/openai-compatible",
|
|
99396
99419
|
"@ai-sdk/openai",
|
|
@@ -99418,8 +99441,8 @@ function openCodeConfigPaths() {
|
|
|
99418
99441
|
const paths = [];
|
|
99419
99442
|
const xdg = process.env.XDG_CONFIG_HOME?.trim();
|
|
99420
99443
|
if (xdg)
|
|
99421
|
-
paths.push(
|
|
99422
|
-
paths.push(
|
|
99444
|
+
paths.push(join8(xdg, "opencode", "opencode.json"));
|
|
99445
|
+
paths.push(join8(homedir7(), ".config", "opencode", "opencode.json"));
|
|
99423
99446
|
return paths;
|
|
99424
99447
|
}
|
|
99425
99448
|
function parseOpenCodeCompatibleProvider(config2, providerId) {
|
|
@@ -101680,8 +101703,8 @@ function abortAllMjpegProxies() {
|
|
|
101680
101703
|
}
|
|
101681
101704
|
|
|
101682
101705
|
// src/domains/devices/android-devtools.ts
|
|
101683
|
-
import { existsSync as
|
|
101684
|
-
import { join as
|
|
101706
|
+
import { existsSync as existsSync3 } from "fs";
|
|
101707
|
+
import { join as join9 } from "path";
|
|
101685
101708
|
function escapeAttr(value) {
|
|
101686
101709
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
101687
101710
|
}
|
|
@@ -101715,8 +101738,8 @@ function resolveDevtoolsApk() {
|
|
|
101715
101738
|
const fromEnv = process.env.YOQA_ANDROID_DEVTOOLS_APK?.trim();
|
|
101716
101739
|
if (fromEnv)
|
|
101717
101740
|
return fromEnv;
|
|
101718
|
-
const built =
|
|
101719
|
-
return
|
|
101741
|
+
const built = join9(import.meta.dir, "../../../../../native/android-devtools/app/build/outputs/apk/debug/app-debug.apk");
|
|
101742
|
+
return existsSync3(built) ? built : null;
|
|
101720
101743
|
}
|
|
101721
101744
|
async function adbOk(adb, args, label) {
|
|
101722
101745
|
const result = await adb(args);
|
|
@@ -101837,7 +101860,7 @@ async function startAndroidDevtools(context, deps = {}) {
|
|
|
101837
101860
|
|
|
101838
101861
|
// src/domains/devices/android-direct-lane.ts
|
|
101839
101862
|
import { mkdir } from "fs/promises";
|
|
101840
|
-
import { dirname as dirname2, join as
|
|
101863
|
+
import { dirname as dirname2, join as join11 } from "path";
|
|
101841
101864
|
|
|
101842
101865
|
// src/domains/devices/adb-input.ts
|
|
101843
101866
|
var ANDROID_KEYCODES = {
|
|
@@ -102159,8 +102182,8 @@ async function exitsWithin(proc, ms) {
|
|
|
102159
102182
|
// src/domains/devices/screenshot-retention.ts
|
|
102160
102183
|
import { readdir, stat, unlink } from "fs/promises";
|
|
102161
102184
|
import { homedir as homedir8 } from "os";
|
|
102162
|
-
import { join as
|
|
102163
|
-
var SCREENSHOT_DIR =
|
|
102185
|
+
import { join as join10 } from "path";
|
|
102186
|
+
var SCREENSHOT_DIR = join10(homedir8(), ".yoqa", "runs", "screenshots");
|
|
102164
102187
|
var SHOT_FILE_RE = /^shot_\d+_[0-9a-f-]+\.png$/i;
|
|
102165
102188
|
var DEFAULT_RETENTION_DAYS = 7;
|
|
102166
102189
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -102188,7 +102211,7 @@ async function pruneOldRunScreenshots(options = {}) {
|
|
|
102188
102211
|
const names = (await readdir(dir)).filter((name30) => SHOT_FILE_RE.test(name30));
|
|
102189
102212
|
const entries = [];
|
|
102190
102213
|
for (const name30 of names) {
|
|
102191
|
-
const info = await stat(
|
|
102214
|
+
const info = await stat(join10(dir, name30));
|
|
102192
102215
|
entries.push({ name: name30, mtimeMs: info.mtimeMs });
|
|
102193
102216
|
}
|
|
102194
102217
|
let removed = 0;
|
|
@@ -102197,7 +102220,7 @@ async function pruneOldRunScreenshots(options = {}) {
|
|
|
102197
102220
|
now: options.now ?? Date.now()
|
|
102198
102221
|
})) {
|
|
102199
102222
|
try {
|
|
102200
|
-
await unlink(
|
|
102223
|
+
await unlink(join10(dir, name30));
|
|
102201
102224
|
removed += 1;
|
|
102202
102225
|
} catch {}
|
|
102203
102226
|
}
|
|
@@ -102335,7 +102358,7 @@ async function createAndroidDirectSession(options, deps = {}) {
|
|
|
102335
102358
|
const screenshot = async () => {
|
|
102336
102359
|
await mkdir(SCREENSHOT_DIR, { recursive: true });
|
|
102337
102360
|
const frame = await captureFrame();
|
|
102338
|
-
const path =
|
|
102361
|
+
const path = join11(SCREENSHOT_DIR, `shot_${Date.now()}_${crypto.randomUUID()}.png`);
|
|
102339
102362
|
await Bun.write(path, Uint8Array.from(Buffer.from(frame.base64, "base64")));
|
|
102340
102363
|
return { path, base64: frame.base64 };
|
|
102341
102364
|
};
|
|
@@ -102561,7 +102584,7 @@ async function createAndroidDirectSession(options, deps = {}) {
|
|
|
102561
102584
|
|
|
102562
102585
|
// src/domains/devices/ios-device-lane.ts
|
|
102563
102586
|
import { mkdir as mkdir5 } from "fs/promises";
|
|
102564
|
-
import { join as
|
|
102587
|
+
import { join as join17 } from "path";
|
|
102565
102588
|
|
|
102566
102589
|
// src/domains/devices/error-chain.ts
|
|
102567
102590
|
var MAX_LINKS = 8;
|
|
@@ -102592,7 +102615,7 @@ function errorChain(error40) {
|
|
|
102592
102615
|
// src/domains/devices/frame-recorder.ts
|
|
102593
102616
|
import { mkdir as mkdir2, mkdtemp as mkdtemp6, rm as rm6 } from "fs/promises";
|
|
102594
102617
|
import { tmpdir as tmpdir6 } from "os";
|
|
102595
|
-
import { dirname as dirname3, join as
|
|
102618
|
+
import { dirname as dirname3, join as join12 } from "path";
|
|
102596
102619
|
var LAST_FRAME_HOLD_S = 0.5;
|
|
102597
102620
|
async function encodeWithFfmpeg(ffmpeg, list, out) {
|
|
102598
102621
|
const proc = Bun.spawn([
|
|
@@ -102640,7 +102663,7 @@ async function recordFrames(source, path, deps = realDeps) {
|
|
|
102640
102663
|
if (!ffmpeg)
|
|
102641
102664
|
throw new Error("ffmpeg not found on PATH");
|
|
102642
102665
|
await mkdir2(dirname3(path), { recursive: true });
|
|
102643
|
-
const dir = await mkdtemp6(
|
|
102666
|
+
const dir = await mkdtemp6(join12(tmpdir6(), "yoqa-frames-"));
|
|
102644
102667
|
try {
|
|
102645
102668
|
await source.start?.();
|
|
102646
102669
|
} catch (error40) {
|
|
@@ -102654,7 +102677,7 @@ async function recordFrames(source, path, deps = realDeps) {
|
|
|
102654
102677
|
const pullOnce = async () => {
|
|
102655
102678
|
try {
|
|
102656
102679
|
for (const frame of await source.pull()) {
|
|
102657
|
-
const file2 =
|
|
102680
|
+
const file2 = join12(dir, `${String(frames.length).padStart(6, "0")}.${frame.ext}`);
|
|
102658
102681
|
await Bun.write(file2, frame.bytes);
|
|
102659
102682
|
frames.push({ file: file2, at: frame.at });
|
|
102660
102683
|
}
|
|
@@ -102685,7 +102708,7 @@ async function recordFrames(source, path, deps = realDeps) {
|
|
|
102685
102708
|
lines.push(`file '${frame.file}'`, `duration ${Math.max(seconds, 0.001).toFixed(3)}`);
|
|
102686
102709
|
}
|
|
102687
102710
|
lines.push(`file '${frames[frames.length - 1]?.file}'`);
|
|
102688
|
-
const list =
|
|
102711
|
+
const list = join12(dir, "frames.txt");
|
|
102689
102712
|
await Bun.write(list, `${lines.join(`
|
|
102690
102713
|
`)}
|
|
102691
102714
|
`);
|
|
@@ -103029,16 +103052,16 @@ async function startPhonePreview(send) {
|
|
|
103029
103052
|
// src/domains/devices/ios-direct-lane.ts
|
|
103030
103053
|
import { mkdir as mkdir3, readFile as readFile4 } from "fs/promises";
|
|
103031
103054
|
import { tmpdir as tmpdir7 } from "os";
|
|
103032
|
-
import { dirname as dirname4, join as
|
|
103055
|
+
import { dirname as dirname4, join as join15 } from "path";
|
|
103033
103056
|
|
|
103034
103057
|
// src/domains/devices/idb-companion.ts
|
|
103035
|
-
import { existsSync as
|
|
103058
|
+
import { existsSync as existsSync4 } from "fs";
|
|
103036
103059
|
import { homedir as homedir9 } from "os";
|
|
103037
|
-
import { join as
|
|
103038
|
-
var IDB_COMPANION_HOME =
|
|
103039
|
-
var IDB_CLIENT_HOME =
|
|
103060
|
+
import { join as join13 } from "path";
|
|
103061
|
+
var IDB_COMPANION_HOME = join13(homedir9(), ".yoqa", "idb", "idb_companion");
|
|
103062
|
+
var IDB_CLIENT_HOME = join13(homedir9(), ".yoqa", "idb", "venv", "bin", "idb");
|
|
103040
103063
|
var MISSING_IDB_MESSAGE = "idb_companion not found. Install the official facebook/idb v1.6.5 macOS binary from GitHub releases to ~/.yoqa/idb/idb_companion (or set YOQA_IDB_COMPANION). Do not use `brew trust facebook/fb`.";
|
|
103041
|
-
function resolveIdbCompanionPath(env = process.env, exists2 =
|
|
103064
|
+
function resolveIdbCompanionPath(env = process.env, exists2 = existsSync4, which2 = (name30) => Bun.which(name30)) {
|
|
103042
103065
|
const fromEnv = env.YOQA_IDB_COMPANION?.trim();
|
|
103043
103066
|
if (fromEnv)
|
|
103044
103067
|
return fromEnv;
|
|
@@ -103046,7 +103069,7 @@ function resolveIdbCompanionPath(env = process.env, exists2 = existsSync3, which
|
|
|
103046
103069
|
return IDB_COMPANION_HOME;
|
|
103047
103070
|
return which2("idb_companion") ?? undefined;
|
|
103048
103071
|
}
|
|
103049
|
-
function resolveIdbClientPath(env = process.env, exists2 =
|
|
103072
|
+
function resolveIdbClientPath(env = process.env, exists2 = existsSync4, which2 = (name30) => Bun.which(name30)) {
|
|
103050
103073
|
const fromEnv = env.YOQA_IDB?.trim();
|
|
103051
103074
|
if (fromEnv)
|
|
103052
103075
|
return fromEnv;
|
|
@@ -103054,7 +103077,7 @@ function resolveIdbClientPath(env = process.env, exists2 = existsSync3, which2 =
|
|
|
103054
103077
|
return IDB_CLIENT_HOME;
|
|
103055
103078
|
return which2("idb") ?? undefined;
|
|
103056
103079
|
}
|
|
103057
|
-
function requireIdbBins(env = process.env, exists2 =
|
|
103080
|
+
function requireIdbBins(env = process.env, exists2 = existsSync4, which2 = (name30) => Bun.which(name30)) {
|
|
103058
103081
|
const companion = resolveIdbCompanionPath(env, exists2, which2);
|
|
103059
103082
|
const client = resolveIdbClientPath(env, exists2, which2);
|
|
103060
103083
|
if (!companion || !client) {
|
|
@@ -103337,8 +103360,8 @@ function cleanPageSource(xml, window2) {
|
|
|
103337
103360
|
}
|
|
103338
103361
|
|
|
103339
103362
|
// src/domains/devices/yoqa-sim.ts
|
|
103340
|
-
import { existsSync as
|
|
103341
|
-
import { join as
|
|
103363
|
+
import { existsSync as existsSync5 } from "fs";
|
|
103364
|
+
import { join as join14 } from "path";
|
|
103342
103365
|
|
|
103343
103366
|
class YoqaSimUnreachableError extends Error {
|
|
103344
103367
|
constructor(message) {
|
|
@@ -103359,10 +103382,10 @@ function resolveYoqaSimBin() {
|
|
|
103359
103382
|
const fromEnv = process.env.YOQA_SIM_BIN?.trim();
|
|
103360
103383
|
if (fromEnv)
|
|
103361
103384
|
return fromEnv;
|
|
103362
|
-
const root =
|
|
103385
|
+
const root = join14(import.meta.dir, "../../../../../native/yoqa-sim/.build");
|
|
103363
103386
|
for (const config2 of ["release", "debug"]) {
|
|
103364
|
-
const built =
|
|
103365
|
-
if (
|
|
103387
|
+
const built = join14(root, config2, "yoqa-sim");
|
|
103388
|
+
if (existsSync5(built))
|
|
103366
103389
|
return built;
|
|
103367
103390
|
}
|
|
103368
103391
|
return null;
|
|
@@ -103614,7 +103637,7 @@ async function recordViaSimctl(udid, path) {
|
|
|
103614
103637
|
};
|
|
103615
103638
|
}
|
|
103616
103639
|
async function captureViaSimctl(udid) {
|
|
103617
|
-
const dest =
|
|
103640
|
+
const dest = join15(tmpdir7(), `yoqa-simctl-${crypto.randomUUID()}.png`);
|
|
103618
103641
|
const proc = Bun.spawn(["xcrun", "simctl", "io", udid, "screenshot", dest], {
|
|
103619
103642
|
stdout: "pipe",
|
|
103620
103643
|
stderr: "pipe"
|
|
@@ -103697,7 +103720,7 @@ async function createIosDirectSession(options, deps = {}) {
|
|
|
103697
103720
|
return lock.withLock(fn);
|
|
103698
103721
|
};
|
|
103699
103722
|
const captureViaIdb = async () => {
|
|
103700
|
-
const dest =
|
|
103723
|
+
const dest = join15(tmpdir7(), `yoqa-idb-${crypto.randomUUID()}.png`);
|
|
103701
103724
|
let bytes;
|
|
103702
103725
|
try {
|
|
103703
103726
|
const result = await run(["screenshot", dest, "--udid", udid], "idb screenshot");
|
|
@@ -103728,7 +103751,7 @@ async function createIosDirectSession(options, deps = {}) {
|
|
|
103728
103751
|
const screenshot = async () => {
|
|
103729
103752
|
await mkdir3(SCREENSHOT_DIR, { recursive: true });
|
|
103730
103753
|
const frame = await captureFrame();
|
|
103731
|
-
const path =
|
|
103754
|
+
const path = join15(SCREENSHOT_DIR, `shot_${Date.now()}_${crypto.randomUUID()}.png`);
|
|
103732
103755
|
await Bun.write(path, Uint8Array.from(Buffer.from(frame.base64, "base64")));
|
|
103733
103756
|
return { path, base64: frame.base64 };
|
|
103734
103757
|
};
|
|
@@ -104176,10 +104199,10 @@ async function connectUsbmux(udid, port, socketPath = USBMUXD_SOCKET) {
|
|
|
104176
104199
|
|
|
104177
104200
|
// src/domains/devices/yoqa-runner.ts
|
|
104178
104201
|
import { X509Certificate, createHash } from "crypto";
|
|
104179
|
-
import { existsSync as
|
|
104202
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync, renameSync, rmSync } from "fs";
|
|
104180
104203
|
import { copyFile, cp, mkdir as mkdir4, readFile as readFile5, readdir as readdir2, rename, rm as rm7, writeFile as writeFile4 } from "fs/promises";
|
|
104181
104204
|
import { homedir as homedir10 } from "os";
|
|
104182
|
-
import { dirname as dirname5, join as
|
|
104205
|
+
import { dirname as dirname5, join as join16, relative } from "path";
|
|
104183
104206
|
|
|
104184
104207
|
class YoqaRunnerError extends Error {
|
|
104185
104208
|
constructor(message) {
|
|
@@ -104323,12 +104346,12 @@ async function hashSources(projectDir) {
|
|
|
104323
104346
|
}
|
|
104324
104347
|
for (const entry of entries) {
|
|
104325
104348
|
if (!IGNORED.has(entry))
|
|
104326
|
-
await visit9(
|
|
104349
|
+
await visit9(join16(path, entry));
|
|
104327
104350
|
}
|
|
104328
104351
|
};
|
|
104329
104352
|
for (const entry of SOURCE_ENTRIES) {
|
|
104330
|
-
const path =
|
|
104331
|
-
if (
|
|
104353
|
+
const path = join16(projectDir, entry);
|
|
104354
|
+
if (existsSync6(path))
|
|
104332
104355
|
await visit9(path);
|
|
104333
104356
|
}
|
|
104334
104357
|
return hash.digest("hex");
|
|
@@ -104348,12 +104371,12 @@ function parseProfile(plist) {
|
|
|
104348
104371
|
};
|
|
104349
104372
|
}
|
|
104350
104373
|
async function readProfiles(products, exec) {
|
|
104351
|
-
const platform =
|
|
104374
|
+
const platform = join16(products, "Debug-iphoneos");
|
|
104352
104375
|
const apps2 = (await readdir2(platform).catch(() => [])).filter((name30) => name30.endsWith(".app"));
|
|
104353
104376
|
const profiles = [];
|
|
104354
104377
|
for (const app of apps2) {
|
|
104355
|
-
const path =
|
|
104356
|
-
if (!
|
|
104378
|
+
const path = join16(platform, app, "embedded.mobileprovision");
|
|
104379
|
+
if (!existsSync6(path))
|
|
104357
104380
|
continue;
|
|
104358
104381
|
const decoded = await exec(["security", "cms", "-D", "-i", path]);
|
|
104359
104382
|
const profile = decoded.exitCode === 0 ? parseProfile(decoded.stdout) : null;
|
|
@@ -104363,7 +104386,7 @@ async function readProfiles(products, exec) {
|
|
|
104363
104386
|
return profiles;
|
|
104364
104387
|
}
|
|
104365
104388
|
function usableFor(manifest, udid, now) {
|
|
104366
|
-
return manifest.version === MANIFEST_VERSION &&
|
|
104389
|
+
return manifest.version === MANIFEST_VERSION && existsSync6(manifest.xctestrun) && Date.parse(manifest.profileExpiresAt) > now.getTime() && (manifest.devices === null || manifest.devices.includes(udid));
|
|
104367
104390
|
}
|
|
104368
104391
|
async function readManifest(path) {
|
|
104369
104392
|
try {
|
|
@@ -104375,14 +104398,14 @@ async function readManifest(path) {
|
|
|
104375
104398
|
async function findXctestrun(products) {
|
|
104376
104399
|
const entries = await readdir2(products).catch(() => []);
|
|
104377
104400
|
const name30 = entries.find((entry) => entry.endsWith(".xctestrun"));
|
|
104378
|
-
return name30 ?
|
|
104401
|
+
return name30 ? join16(products, name30) : null;
|
|
104379
104402
|
}
|
|
104380
104403
|
async function brandRunnerApp(products, exec) {
|
|
104381
|
-
const platform =
|
|
104382
|
-
const host =
|
|
104383
|
-
const runner =
|
|
104384
|
-
const staging =
|
|
104385
|
-
const copy =
|
|
104404
|
+
const platform = join16(products, "Debug-iphoneos");
|
|
104405
|
+
const host = join16(platform, "YoqaRunner.app");
|
|
104406
|
+
const runner = join16(platform, "YoqaRunnerUITests-Runner.app");
|
|
104407
|
+
const staging = join16(products, "branding");
|
|
104408
|
+
const copy = join16(staging, "YoqaRunnerUITests-Runner.app");
|
|
104386
104409
|
const run = async (command) => {
|
|
104387
104410
|
const result = await exec(command);
|
|
104388
104411
|
if (result.exitCode !== 0) {
|
|
@@ -104397,7 +104420,7 @@ async function brandRunnerApp(products, exec) {
|
|
|
104397
104420
|
await rm7(staging, { recursive: true, force: true });
|
|
104398
104421
|
await cp(runner, copy, { recursive: true, verbatimSymlinks: true });
|
|
104399
104422
|
for (const name30 of icons)
|
|
104400
|
-
await copyFile(
|
|
104423
|
+
await copyFile(join16(host, name30), join16(copy, name30));
|
|
104401
104424
|
const plist = await run([
|
|
104402
104425
|
"plutil",
|
|
104403
104426
|
"-extract",
|
|
@@ -104405,7 +104428,7 @@ async function brandRunnerApp(products, exec) {
|
|
|
104405
104428
|
"json",
|
|
104406
104429
|
"-o",
|
|
104407
104430
|
"-",
|
|
104408
|
-
|
|
104431
|
+
join16(host, "Info.plist")
|
|
104409
104432
|
]);
|
|
104410
104433
|
await run([
|
|
104411
104434
|
"plutil",
|
|
@@ -104413,9 +104436,9 @@ async function brandRunnerApp(products, exec) {
|
|
|
104413
104436
|
"CFBundleIcons",
|
|
104414
104437
|
"-json",
|
|
104415
104438
|
plist.trim(),
|
|
104416
|
-
|
|
104439
|
+
join16(copy, "Info.plist")
|
|
104417
104440
|
]);
|
|
104418
|
-
const certificates =
|
|
104441
|
+
const certificates = join16(staging, "certificate");
|
|
104419
104442
|
await run(["codesign", "-d", `--extract-certificates=${certificates}`, runner]);
|
|
104420
104443
|
const identity2 = createHash("sha1").update(await readFile5(`${certificates}0`)).digest("hex").toUpperCase();
|
|
104421
104444
|
await run([
|
|
@@ -104427,7 +104450,7 @@ async function brandRunnerApp(products, exec) {
|
|
|
104427
104450
|
"--generate-entitlement-der",
|
|
104428
104451
|
copy
|
|
104429
104452
|
]);
|
|
104430
|
-
const unbranded =
|
|
104453
|
+
const unbranded = join16(staging, "unbranded.app");
|
|
104431
104454
|
await rename(runner, unbranded);
|
|
104432
104455
|
try {
|
|
104433
104456
|
await rename(copy, runner);
|
|
@@ -104499,7 +104522,7 @@ function prepareYoqaRunner(udid, deps) {
|
|
|
104499
104522
|
return next;
|
|
104500
104523
|
}
|
|
104501
104524
|
async function prepare(udid, deps) {
|
|
104502
|
-
if (!
|
|
104525
|
+
if (!existsSync6(join16(deps.projectDir, "YoqaRunner.xcodeproj"))) {
|
|
104503
104526
|
throw new YoqaRunnerError(`YoqaRunner's Xcode project is missing from this install (looked in ${deps.projectDir}). Reinstall yoqa, or set YOQA_RUNNER_PROJECT to a native/yoqa-runner checkout.`);
|
|
104504
104527
|
}
|
|
104505
104528
|
const team = await signingTeam(deps);
|
|
@@ -104508,8 +104531,8 @@ async function prepare(udid, deps) {
|
|
|
104508
104531
|
deps.exec(["xcodebuild", "-version"])
|
|
104509
104532
|
]);
|
|
104510
104533
|
const key = createHash("sha256").update(`${sources}\x00${xcodeVersion(xcode)}\x00${team}`).digest("hex").slice(0, 16);
|
|
104511
|
-
const dir =
|
|
104512
|
-
const manifestPath =
|
|
104534
|
+
const dir = join16(deps.cacheRoot, key);
|
|
104535
|
+
const manifestPath = join16(dir, "build.json");
|
|
104513
104536
|
const cached2 = await readManifest(manifestPath);
|
|
104514
104537
|
if (cached2 && usableFor(cached2, udid, deps.now())) {
|
|
104515
104538
|
return {
|
|
@@ -104520,12 +104543,12 @@ async function prepare(udid, deps) {
|
|
|
104520
104543
|
devices: cached2.devices
|
|
104521
104544
|
};
|
|
104522
104545
|
}
|
|
104523
|
-
const derivedData =
|
|
104546
|
+
const derivedData = join16(dir, "DerivedData");
|
|
104524
104547
|
const build = await deps.exec([
|
|
104525
104548
|
"xcodebuild",
|
|
104526
104549
|
"build-for-testing",
|
|
104527
104550
|
"-project",
|
|
104528
|
-
|
|
104551
|
+
join16(deps.projectDir, "YoqaRunner.xcodeproj"),
|
|
104529
104552
|
"-scheme",
|
|
104530
104553
|
"YoqaRunner",
|
|
104531
104554
|
"-destination",
|
|
@@ -104542,7 +104565,7 @@ async function prepare(udid, deps) {
|
|
|
104542
104565
|
throw new YoqaRunnerError(explainBuildFailure(`${build.stdout}
|
|
104543
104566
|
${build.stderr}`, team));
|
|
104544
104567
|
}
|
|
104545
|
-
const products =
|
|
104568
|
+
const products = join16(derivedData, "Build/Products");
|
|
104546
104569
|
const unbranded = await brandRunnerApp(products, deps.exec);
|
|
104547
104570
|
if (unbranded)
|
|
104548
104571
|
console.warn(`[yoqa-runner] the runner keeps Xcode's blank icon: ${unbranded}`);
|
|
@@ -104697,13 +104720,13 @@ function resolveYoqaRunnerProject(at) {
|
|
|
104697
104720
|
const fromEnv = at.env.YOQA_RUNNER_PROJECT?.trim();
|
|
104698
104721
|
if (fromEnv)
|
|
104699
104722
|
return fromEnv;
|
|
104700
|
-
if (
|
|
104723
|
+
if (existsSync6(join16(at.checkout, "YoqaRunner.xcodeproj")))
|
|
104701
104724
|
return at.checkout;
|
|
104702
|
-
if (!
|
|
104725
|
+
if (!existsSync6(at.archive))
|
|
104703
104726
|
return at.checkout;
|
|
104704
104727
|
const key = createHash("sha256").update(readFileSync(at.archive)).digest("hex").slice(0, 16);
|
|
104705
|
-
const dir =
|
|
104706
|
-
if (
|
|
104728
|
+
const dir = join16(at.cacheRoot, "source", key);
|
|
104729
|
+
if (existsSync6(join16(dir, "YoqaRunner.xcodeproj")))
|
|
104707
104730
|
return dir;
|
|
104708
104731
|
const staging = `${dir}.${process.pid}.tmp`;
|
|
104709
104732
|
rmSync(staging, { recursive: true, force: true });
|
|
@@ -104721,7 +104744,7 @@ function resolveYoqaRunnerProject(at) {
|
|
|
104721
104744
|
return dir;
|
|
104722
104745
|
}
|
|
104723
104746
|
function yoqaRunnerDeps() {
|
|
104724
|
-
const cacheRoot =
|
|
104747
|
+
const cacheRoot = join16(homedir10(), ".yoqa", "yoqa-runner");
|
|
104725
104748
|
return {
|
|
104726
104749
|
exec: execCommand,
|
|
104727
104750
|
spawn: (command, env) => Bun.spawn(command, {
|
|
@@ -104733,12 +104756,12 @@ function yoqaRunnerDeps() {
|
|
|
104733
104756
|
env: process.env,
|
|
104734
104757
|
projectDir: resolveYoqaRunnerProject({
|
|
104735
104758
|
env: process.env,
|
|
104736
|
-
checkout:
|
|
104737
|
-
archive:
|
|
104759
|
+
checkout: join16(import.meta.dir, "../../../../../native/yoqa-runner"),
|
|
104760
|
+
archive: join16(dirname5(process.execPath), RUNNER_SOURCE_ARCHIVE),
|
|
104738
104761
|
cacheRoot
|
|
104739
104762
|
}),
|
|
104740
104763
|
cacheRoot,
|
|
104741
|
-
settingsPath:
|
|
104764
|
+
settingsPath: join16(homedir10(), ".yoqa", "ios-signing.json"),
|
|
104742
104765
|
now: () => new Date
|
|
104743
104766
|
};
|
|
104744
104767
|
}
|
|
@@ -104982,7 +105005,7 @@ async function createIosDeviceSession(options, deps = iosDeviceDeps()) {
|
|
|
104982
105005
|
const screenshot = async () => {
|
|
104983
105006
|
await mkdir5(SCREENSHOT_DIR, { recursive: true });
|
|
104984
105007
|
const frame = await captureFrame();
|
|
104985
|
-
const path =
|
|
105008
|
+
const path = join17(SCREENSHOT_DIR, `shot_${Date.now()}_${crypto.randomUUID()}.png`);
|
|
104986
105009
|
await Bun.write(path, Uint8Array.from(Buffer.from(frame.base64, "base64")));
|
|
104987
105010
|
return { path, base64: frame.base64 };
|
|
104988
105011
|
};
|
|
@@ -105117,7 +105140,7 @@ function directOptIn(deviceClass, env = process.env) {
|
|
|
105117
105140
|
|
|
105118
105141
|
// src/domains/devices/web-direct-lane.ts
|
|
105119
105142
|
import { mkdir as mkdir6 } from "fs/promises";
|
|
105120
|
-
import { join as
|
|
105143
|
+
import { join as join18 } from "path";
|
|
105121
105144
|
|
|
105122
105145
|
// src/domains/devices/cdp-client.ts
|
|
105123
105146
|
class CdpClosedError extends Error {
|
|
@@ -105659,7 +105682,7 @@ async function createWebDirectSession(options, deps = webDirectDeps()) {
|
|
|
105659
105682
|
const screenshot = async () => {
|
|
105660
105683
|
await mkdir6(SCREENSHOT_DIR, { recursive: true });
|
|
105661
105684
|
const frame = await captureFrame();
|
|
105662
|
-
const path =
|
|
105685
|
+
const path = join18(SCREENSHOT_DIR, `shot_${Date.now()}_${crypto.randomUUID()}.png`);
|
|
105663
105686
|
await Bun.write(path, Uint8Array.from(Buffer.from(frame.base64, "base64")));
|
|
105664
105687
|
return { path, base64: frame.base64 };
|
|
105665
105688
|
};
|
|
@@ -105740,9 +105763,9 @@ async function createWebDirectSession(options, deps = webDirectDeps()) {
|
|
|
105740
105763
|
|
|
105741
105764
|
// src/domains/devices/yoqa-ax.ts
|
|
105742
105765
|
import { randomBytes } from "crypto";
|
|
105743
|
-
import { existsSync as
|
|
105766
|
+
import { existsSync as existsSync7, rmSync as rmSync2 } from "fs";
|
|
105744
105767
|
import { createServer } from "net";
|
|
105745
|
-
import { join as
|
|
105768
|
+
import { join as join19 } from "path";
|
|
105746
105769
|
var CONNECT_TIMEOUT_MS2 = 1e4;
|
|
105747
105770
|
var REQUEST_TIMEOUT_MS2 = 5000;
|
|
105748
105771
|
var STOP_GRACE_MS3 = 2000;
|
|
@@ -105753,10 +105776,10 @@ function resolveYoqaAxBin() {
|
|
|
105753
105776
|
const fromEnv = process.env.YOQA_AX_BIN?.trim();
|
|
105754
105777
|
if (fromEnv)
|
|
105755
105778
|
return fromEnv;
|
|
105756
|
-
const products =
|
|
105779
|
+
const products = join19(import.meta.dir, "../../../../../native/yoqa-ax/.build/out/Products");
|
|
105757
105780
|
for (const config2 of ["Release-iphonesimulator", "Debug-iphonesimulator"]) {
|
|
105758
|
-
const built =
|
|
105759
|
-
if (
|
|
105781
|
+
const built = join19(products, config2, "yoqa-ax");
|
|
105782
|
+
if (existsSync7(built))
|
|
105760
105783
|
return built;
|
|
105761
105784
|
}
|
|
105762
105785
|
return null;
|
|
@@ -106282,11 +106305,11 @@ import {
|
|
|
106282
106305
|
createDecipheriv,
|
|
106283
106306
|
randomBytes as randomBytes2
|
|
106284
106307
|
} from "crypto";
|
|
106285
|
-
import { chmodSync, existsSync as
|
|
106308
|
+
import { chmodSync, existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
106286
106309
|
import { homedir as homedir11 } from "os";
|
|
106287
|
-
import { dirname as dirname6, join as
|
|
106288
|
-
var YOQA_ROOT2 =
|
|
106289
|
-
var KEY_PATH =
|
|
106310
|
+
import { dirname as dirname6, join as join20 } from "path";
|
|
106311
|
+
var YOQA_ROOT2 = join20(homedir11(), ".yoqa");
|
|
106312
|
+
var KEY_PATH = join20(YOQA_ROOT2, ".provider-key");
|
|
106290
106313
|
var ALGORITHM = "aes-256-gcm";
|
|
106291
106314
|
var IV_LENGTH = 12;
|
|
106292
106315
|
var KEY_LENGTH = 32;
|
|
@@ -106320,7 +106343,7 @@ function base64ToBytes(value) {
|
|
|
106320
106343
|
}
|
|
106321
106344
|
function ensureProviderKey() {
|
|
106322
106345
|
mkdirSync3(YOQA_ROOT2, { recursive: true });
|
|
106323
|
-
if (
|
|
106346
|
+
if (existsSync8(KEY_PATH)) {
|
|
106324
106347
|
const existing = toBytes(readFileSync2(KEY_PATH));
|
|
106325
106348
|
if (existing.length === KEY_LENGTH) {
|
|
106326
106349
|
return existing;
|
|
@@ -107975,13 +107998,13 @@ function reportedLaneWarning(warning) {
|
|
|
107975
107998
|
}
|
|
107976
107999
|
|
|
107977
108000
|
// src/domains/runs/run-recording.ts
|
|
107978
|
-
import { existsSync as
|
|
108001
|
+
import { existsSync as existsSync9 } from "fs";
|
|
107979
108002
|
import { rm as rm8 } from "fs/promises";
|
|
107980
108003
|
import { homedir as homedir12 } from "os";
|
|
107981
|
-
import { join as
|
|
107982
|
-
var RUN_VIDEO_DIR =
|
|
108004
|
+
import { join as join21 } from "path";
|
|
108005
|
+
var RUN_VIDEO_DIR = join21(homedir12(), ".yoqa", "runs", "videos");
|
|
107983
108006
|
function runVideoPath(runTestId, dir = RUN_VIDEO_DIR) {
|
|
107984
|
-
return
|
|
108007
|
+
return join21(dir, `${runTestId}.mp4`);
|
|
107985
108008
|
}
|
|
107986
108009
|
var STOP_TIMEOUT_MS = 20000;
|
|
107987
108010
|
function errorMessage7(error40) {
|
|
@@ -108017,7 +108040,7 @@ async function startRunRecording(session, path) {
|
|
|
108017
108040
|
} catch (error40) {
|
|
108018
108041
|
return { status: "unavailable", note: `Could not save recording: ${errorMessage7(error40)}` };
|
|
108019
108042
|
}
|
|
108020
|
-
if (!
|
|
108043
|
+
if (!existsSync9(path)) {
|
|
108021
108044
|
return { status: "unavailable", note: "The device produced no video file" };
|
|
108022
108045
|
}
|
|
108023
108046
|
return { status: "ready" };
|
|
@@ -108031,7 +108054,7 @@ async function deleteRunVideo(runTestId, dir = RUN_VIDEO_DIR) {
|
|
|
108031
108054
|
}
|
|
108032
108055
|
function readyVideoPath(runTestId, status, dir = RUN_VIDEO_DIR) {
|
|
108033
108056
|
const path = runVideoPath(runTestId, dir);
|
|
108034
|
-
return status === "ready" &&
|
|
108057
|
+
return status === "ready" && existsSync9(path) ? path : null;
|
|
108035
108058
|
}
|
|
108036
108059
|
async function recordCase(session, path, options, run) {
|
|
108037
108060
|
if (!options.enabled)
|
|
@@ -108717,7 +108740,7 @@ async function getRunStepScreenshotPath(runId, stepId) {
|
|
|
108717
108740
|
const step = test.steps?.find((item) => item.id === stepId);
|
|
108718
108741
|
if (!step)
|
|
108719
108742
|
continue;
|
|
108720
|
-
if (!step.screenshotUri || !
|
|
108743
|
+
if (!step.screenshotUri || !existsSync10(step.screenshotUri)) {
|
|
108721
108744
|
throw new RunNotFoundError("Screenshot not found");
|
|
108722
108745
|
}
|
|
108723
108746
|
return step.screenshotUri;
|
|
@@ -110730,12 +110753,11 @@ function createDevicesRoutes() {
|
|
|
110730
110753
|
}
|
|
110731
110754
|
|
|
110732
110755
|
// src/domains/doctor/application.ts
|
|
110733
|
-
import {
|
|
110734
|
-
import { join as join24 } from "path";
|
|
110756
|
+
import { join as join22 } from "path";
|
|
110735
110757
|
// package.json
|
|
110736
110758
|
var package_default = {
|
|
110737
110759
|
name: "@yoqa/runner",
|
|
110738
|
-
version: "1.0.
|
|
110760
|
+
version: "1.0.5",
|
|
110739
110761
|
description: "Yoqa local runner \u2014 device control + catalog HTTP API (Bun). Start with yoqa serve or the yoqa-runner bin.",
|
|
110740
110762
|
license: "UNLICENSED",
|
|
110741
110763
|
type: "module",
|
|
@@ -110920,12 +110942,8 @@ async function runCommand3(command, options) {
|
|
|
110920
110942
|
}
|
|
110921
110943
|
}
|
|
110922
110944
|
async function which2(bin) {
|
|
110923
|
-
|
|
110924
|
-
|
|
110925
|
-
return null;
|
|
110926
|
-
const path = stdout.trim().split(`
|
|
110927
|
-
`)[0]?.trim();
|
|
110928
|
-
return path || null;
|
|
110945
|
+
ensureHostToolPath();
|
|
110946
|
+
return Bun.which(bin);
|
|
110929
110947
|
}
|
|
110930
110948
|
async function probeJava() {
|
|
110931
110949
|
const javaHome = process.env.JAVA_HOME;
|
|
@@ -110934,7 +110952,7 @@ async function probeJava() {
|
|
|
110934
110952
|
let detail = javaBin ?? "java not on PATH";
|
|
110935
110953
|
if (javaHome)
|
|
110936
110954
|
detail = `JAVA_HOME=${javaHome}`;
|
|
110937
|
-
else if (await Bun.file(
|
|
110955
|
+
else if (await Bun.file(join22(studioJbr, "bin/java")).exists()) {
|
|
110938
110956
|
detail = `Android Studio JBR available at ${studioJbr} (JAVA_HOME unset)`;
|
|
110939
110957
|
}
|
|
110940
110958
|
const ok = Boolean(javaBin || javaHome);
|
|
@@ -110965,8 +110983,9 @@ async function probeXcodeSelect() {
|
|
|
110965
110983
|
};
|
|
110966
110984
|
}
|
|
110967
110985
|
async function probeAdbDevices() {
|
|
110968
|
-
const
|
|
110969
|
-
|
|
110986
|
+
const sdk = resolveAndroidSdkRoot();
|
|
110987
|
+
const adb = await which2("adb") ?? (sdk ? androidSdkToolPath(sdk, "platform-tools", "adb") : null);
|
|
110988
|
+
if (!adb || !await Bun.file(adb).exists()) {
|
|
110970
110989
|
return {
|
|
110971
110990
|
id: "adb-devices",
|
|
110972
110991
|
label: "ADB devices",
|
|
@@ -111604,12 +111623,12 @@ import { dirname as dirname7 } from "path";
|
|
|
111604
111623
|
|
|
111605
111624
|
// src/domains/devices/action-result.ts
|
|
111606
111625
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
111607
|
-
import { join as
|
|
111626
|
+
import { join as join24 } from "path";
|
|
111608
111627
|
|
|
111609
111628
|
// src/domains/devices/agent-image.ts
|
|
111610
111629
|
import { mkdtemp as mkdtemp7, readFile as readFile7, rm as rm9, writeFile as writeFile5 } from "fs/promises";
|
|
111611
111630
|
import { tmpdir as tmpdir8 } from "os";
|
|
111612
|
-
import { join as
|
|
111631
|
+
import { join as join23 } from "path";
|
|
111613
111632
|
var DEFAULT_AGENT_IMAGE_EDGE = 1000;
|
|
111614
111633
|
function targetEdge(pngBase64, options) {
|
|
111615
111634
|
if (options.full || options.scale === 1)
|
|
@@ -111628,9 +111647,9 @@ async function prepareAgentImage(pngBase64, options = {}) {
|
|
|
111628
111647
|
if (bytes.byteLength === 0 || edge == null || process.platform !== "darwin") {
|
|
111629
111648
|
return { base64: pngBase64, mediaType: "image/png", downscaled: false };
|
|
111630
111649
|
}
|
|
111631
|
-
const dir = await mkdtemp7(
|
|
111632
|
-
const inPath =
|
|
111633
|
-
const outPath =
|
|
111650
|
+
const dir = await mkdtemp7(join23(tmpdir8(), "yoqa-agent-image-"));
|
|
111651
|
+
const inPath = join23(dir, "shot.png");
|
|
111652
|
+
const outPath = join23(dir, "shot.jpg");
|
|
111634
111653
|
try {
|
|
111635
111654
|
await writeFile5(inPath, new Uint8Array(bytes));
|
|
111636
111655
|
const proc = Bun.spawn([
|
|
@@ -111720,7 +111739,7 @@ function actionMarks(body, resolved) {
|
|
|
111720
111739
|
}
|
|
111721
111740
|
async function writeImage(dir, base643, label, ext) {
|
|
111722
111741
|
await mkdir7(dir, { recursive: true });
|
|
111723
|
-
const path =
|
|
111742
|
+
const path = join24(dir, `${label}_${Date.now()}_${crypto.randomUUID()}.${ext}`);
|
|
111724
111743
|
await Bun.write(path, Uint8Array.from(Buffer.from(base643, "base64")));
|
|
111725
111744
|
return path;
|
|
111726
111745
|
}
|
package/package.json
CHANGED