fonino 0.1.0 → 0.1.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/cli/bin/fonino.mjs
CHANGED
|
@@ -7845,6 +7845,23 @@ function coveredByTask(g, risk, spec) {
|
|
|
7845
7845
|
if (amount === void 0) return true;
|
|
7846
7846
|
return g.cap !== void 0 && amount <= g.cap;
|
|
7847
7847
|
}
|
|
7848
|
+
function forAssistants(r) {
|
|
7849
|
+
if (!Array.isArray(r.content) || !r.content.some((c) => c.type === "image")) return r;
|
|
7850
|
+
const content = [...r.content.filter((c) => c.type !== "image"), ...r.content.filter((c) => c.type === "image")];
|
|
7851
|
+
const out = { ...r, content };
|
|
7852
|
+
if (!("structuredContent" in r)) {
|
|
7853
|
+
for (const c of content) {
|
|
7854
|
+
if (c.type !== "text") continue;
|
|
7855
|
+
try {
|
|
7856
|
+
const v = JSON.parse(c.text.split("\nDo NOT")[0]);
|
|
7857
|
+
if (v && typeof v === "object" && !Array.isArray(v)) out.structuredContent = v;
|
|
7858
|
+
} catch {
|
|
7859
|
+
}
|
|
7860
|
+
break;
|
|
7861
|
+
}
|
|
7862
|
+
}
|
|
7863
|
+
return out;
|
|
7864
|
+
}
|
|
7848
7865
|
async function modelImage(pngPath) {
|
|
7849
7866
|
const out = pathJoin(tmpdir7(), `fonino-${process.pid}-${randomUUID5().slice(0, 8)}.jpg`);
|
|
7850
7867
|
try {
|
|
@@ -8725,7 +8742,7 @@ ${describeSpec(spec)}
|
|
|
8725
8742
|
ms: Date.now() - t0,
|
|
8726
8743
|
heldMs: heldSince && !result.isError ? Date.now() - Date.parse(heldSince) : void 0
|
|
8727
8744
|
});
|
|
8728
|
-
return result;
|
|
8745
|
+
return forAssistants(result);
|
|
8729
8746
|
};
|
|
8730
8747
|
const c = { ...config, ...extra ?? {} };
|
|
8731
8748
|
c._meta = { ...c._meta ?? {}, securitySchemes: SECURITY };
|
|
@@ -10479,7 +10496,7 @@ var init_serve = __esm({
|
|
|
10479
10496
|
init_src2();
|
|
10480
10497
|
init_src4();
|
|
10481
10498
|
init_src();
|
|
10482
|
-
import { spawn as spawn5 } from "node:child_process";
|
|
10499
|
+
import { execFileSync as execFileSync3, spawn as spawn5 } from "node:child_process";
|
|
10483
10500
|
import { copyFileSync as copyFileSync2, existsSync as existsSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync6, readFileSync as readFileSync23, writeFileSync as writeFileSync20 } from "node:fs";
|
|
10484
10501
|
import { homedir as homedir22 } from "node:os";
|
|
10485
10502
|
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
@@ -10893,13 +10910,24 @@ async function main() {
|
|
|
10893
10910
|
const connected = (await listMuxDevices2()).filter((d) => d.connectionType === "USB").map((d) => d.udid);
|
|
10894
10911
|
const stampFile = join28(process.env.AGENTPHONE_HOME ?? join28(homedir22(), ".agentphone"), "resign.json");
|
|
10895
10912
|
const stamps = existsSync20(stampFile) ? JSON.parse(readFileSync23(stampFile, "utf8")) : {};
|
|
10896
|
-
const
|
|
10913
|
+
const profile = helperProfile(process.env.AGENTPHONE_WDA_BUILD ?? join28(fileURLToPath8(new URL("../../..", import.meta.url)), "vendor/wda-build"));
|
|
10914
|
+
const stale = (u) => {
|
|
10915
|
+
if (!stamps[u]) return true;
|
|
10916
|
+
if (profile) return profile.expires - Date.now() < 3 * 864e5 || Date.parse(stamps[u]) < profile.created;
|
|
10917
|
+
return Date.now() - Date.parse(stamps[u]) > 3 * 864e5;
|
|
10918
|
+
};
|
|
10919
|
+
const udids = flags["if-stale"] ? connected.filter(stale) : connected;
|
|
10897
10920
|
if (!udids.length) return ok(connected.length ? "all connected iPhones were renewed recently" : "no iPhone connected");
|
|
10898
10921
|
const repo = fileURLToPath8(new URL("../../..", import.meta.url));
|
|
10899
10922
|
const code = await new Promise(
|
|
10900
10923
|
(r) => spawn5("/bin/sh", [join28(repo, "scripts/wda.sh"), "setup", ...udids], {
|
|
10901
10924
|
stdio: "inherit",
|
|
10902
|
-
env: {
|
|
10925
|
+
env: {
|
|
10926
|
+
...process.env,
|
|
10927
|
+
AGENTPHONE_TEAM_ID: cfg.team,
|
|
10928
|
+
AGENTPHONE_BUNDLE: cfg.bundle ?? `com.fonino.${cfg.team.toLowerCase()}.helper`,
|
|
10929
|
+
...cfg.ascKey ? { AGENTPHONE_ASC_KEY: cfg.ascKey.path, AGENTPHONE_ASC_KEY_ID: cfg.ascKey.id, AGENTPHONE_ASC_ISSUER: cfg.ascKey.issuer } : {}
|
|
10930
|
+
}
|
|
10903
10931
|
}).on("exit", (c) => r(c ?? 1))
|
|
10904
10932
|
);
|
|
10905
10933
|
if (code !== 0) throw new DeviceError("resign_failed", "Couldn't renew the helper's signature", "Open Xcode \u2192 Settings \u2192 Accounts and check your Apple ID is still signed in.");
|
|
@@ -11360,6 +11388,19 @@ async function agentCommand() {
|
|
|
11360
11388
|
}
|
|
11361
11389
|
rl.close();
|
|
11362
11390
|
}
|
|
11391
|
+
function helperProfile(buildDir) {
|
|
11392
|
+
try {
|
|
11393
|
+
const products = join28(buildDir, "Build/Products/Debug-iphoneos");
|
|
11394
|
+
const app = readdirSync6(products).find((f) => f.endsWith("-Runner.app"));
|
|
11395
|
+
if (!app) return void 0;
|
|
11396
|
+
const plist2 = execFileSync3("/usr/bin/security", ["cms", "-D", "-i", join28(products, app, "embedded.mobileprovision")], { stdio: ["ignore", "pipe", "ignore"] }).toString();
|
|
11397
|
+
const date = (key) => Date.parse(plist2.match(new RegExp(`<key>${key}</key>\\s*<date>([^<]+)</date>`))?.[1] ?? "");
|
|
11398
|
+
const created = date("CreationDate"), expires = date("ExpirationDate");
|
|
11399
|
+
return Number.isFinite(created) && Number.isFinite(expires) ? { created, expires } : void 0;
|
|
11400
|
+
} catch {
|
|
11401
|
+
return void 0;
|
|
11402
|
+
}
|
|
11403
|
+
}
|
|
11363
11404
|
function listRuns(limit) {
|
|
11364
11405
|
const dir = defaultRunsDir();
|
|
11365
11406
|
const runs = existsSync20(dir) ? readdirSync6(dir).filter((f) => existsSync20(resolve(dir, f, "goal.json"))).sort().reverse().slice(0, limit) : [];
|
package/docs/setup.md
CHANGED
|
@@ -34,6 +34,11 @@ locked with Face ID ask for your Mac password, which AgentPhone will not enter.
|
|
|
34
34
|
Signing: a free Apple ID ("Personal Team") works for testing but allows **3 devices** and its
|
|
35
35
|
signing **expires after 7 days** (rerun step 4). A paid Apple Developer account ($99/yr) allows
|
|
36
36
|
100 iPhones per membership year and 1‑year certificates, and can be shared by several Macs.
|
|
37
|
+
With a paid account, add an App Store Connect API key (Users and Access → Integrations, role
|
|
38
|
+
Developer or higher) to `~/.agentphone/setup.json` as
|
|
39
|
+
`"ascKey": {"path": "/path/AuthKey_XXXX.p8", "id": "XXXX", "issuer": "<issuer id>"}`: the helper is
|
|
40
|
+
then signed for a year without an Xcode sign-in, and `fonino wda resign --if-stale` only renews it
|
|
41
|
+
near the end of that year instead of every few days.
|
|
37
42
|
|
|
38
43
|
1. Install Xcode, open it once (install iOS components), accept the license, then
|
|
39
44
|
`sudo xcode-select -s /Applications/Xcode.app/Contents/Developer` and sign in under
|
|
Binary file
|
package/native/ocr/fonino-ocr
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/scripts/wda.sh
CHANGED
|
@@ -36,6 +36,10 @@ case "${1:-}" in
|
|
|
36
36
|
DESTS=""
|
|
37
37
|
for u in "$@"; do DESTS="$DESTS -destination id=$u"; done
|
|
38
38
|
[ -n "$DESTS" ] || DESTS="-destination generic/platform=iOS"
|
|
39
|
+
# With a paid team's App Store Connect API key, Xcode needs no signed-in account and the profile
|
|
40
|
+
# lasts a year; without one it uses Xcode's account (free Apple IDs: 7 days).
|
|
41
|
+
AUTH=""
|
|
42
|
+
[ -n "${AGENTPHONE_ASC_KEY:-}" ] && AUTH="-authenticationKeyPath $AGENTPHONE_ASC_KEY -authenticationKeyID $AGENTPHONE_ASC_KEY_ID -authenticationKeyIssuerID $AGENTPHONE_ASC_ISSUER"
|
|
39
43
|
# shellcheck disable=SC2086
|
|
40
44
|
xcodebuild build-for-testing \
|
|
41
45
|
-project "$WDA_DIR/WebDriverAgent.xcodeproj" \
|
|
@@ -44,6 +48,7 @@ case "${1:-}" in
|
|
|
44
48
|
-derivedDataPath "$DERIVED" \
|
|
45
49
|
-allowProvisioningUpdates \
|
|
46
50
|
-allowProvisioningDeviceRegistration \
|
|
51
|
+
$AUTH \
|
|
47
52
|
DEVELOPMENT_TEAM="$AGENTPHONE_TEAM_ID" \
|
|
48
53
|
PRODUCT_BUNDLE_IDENTIFIER="$BUNDLE" \
|
|
49
54
|
CODE_SIGN_STYLE=Automatic
|