codeloop-mcp-server 0.1.88 → 0.1.95
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/README.md +30 -0
- package/dist/evidence/change_coverage.d.ts +41 -0
- package/dist/evidence/change_coverage.d.ts.map +1 -1
- package/dist/evidence/change_coverage.js +69 -2
- package/dist/evidence/change_coverage.js.map +1 -1
- package/dist/evidence/interaction_coverage.d.ts.map +1 -1
- package/dist/evidence/interaction_coverage.js +2 -0
- package/dist/evidence/interaction_coverage.js.map +1 -1
- package/dist/evidence/interaction_evidence.d.ts +38 -0
- package/dist/evidence/interaction_evidence.d.ts.map +1 -1
- package/dist/evidence/interaction_evidence.js +60 -0
- package/dist/evidence/interaction_evidence.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +311 -57
- package/dist/index.js.map +1 -1
- package/dist/runners/active_target.d.ts +31 -0
- package/dist/runners/active_target.d.ts.map +1 -0
- package/dist/runners/active_target.js +65 -0
- package/dist/runners/active_target.js.map +1 -0
- package/dist/runners/android_sdk.d.ts +50 -0
- package/dist/runners/android_sdk.d.ts.map +1 -0
- package/dist/runners/android_sdk.js +123 -0
- package/dist/runners/android_sdk.js.map +1 -0
- package/dist/runners/app_launcher.d.ts +59 -1
- package/dist/runners/app_launcher.d.ts.map +1 -1
- package/dist/runners/app_launcher.js +184 -33
- package/dist/runners/app_launcher.js.map +1 -1
- package/dist/runners/app_logger.d.ts +1 -1
- package/dist/runners/app_logger.d.ts.map +1 -1
- package/dist/runners/app_logger.js +9 -8
- package/dist/runners/app_logger.js.map +1 -1
- package/dist/runners/device_probe.d.ts +18 -0
- package/dist/runners/device_probe.d.ts.map +1 -1
- package/dist/runners/device_probe.js +52 -22
- package/dist/runners/device_probe.js.map +1 -1
- package/dist/runners/interaction_engine.d.ts +6 -0
- package/dist/runners/interaction_engine.d.ts.map +1 -1
- package/dist/runners/interaction_engine.js +71 -21
- package/dist/runners/interaction_engine.js.map +1 -1
- package/dist/runners/ios_sim_input.d.ts +106 -0
- package/dist/runners/ios_sim_input.d.ts.map +1 -0
- package/dist/runners/ios_sim_input.js +453 -0
- package/dist/runners/ios_sim_input.js.map +1 -0
- package/dist/runners/journey_to_maestro.d.ts +27 -0
- package/dist/runners/journey_to_maestro.d.ts.map +1 -1
- package/dist/runners/journey_to_maestro.js +54 -0
- package/dist/runners/journey_to_maestro.js.map +1 -1
- package/dist/runners/logging_readiness.d.ts.map +1 -1
- package/dist/runners/logging_readiness.js +38 -7
- package/dist/runners/logging_readiness.js.map +1 -1
- package/dist/runners/maestro.d.ts +27 -2
- package/dist/runners/maestro.d.ts.map +1 -1
- package/dist/runners/maestro.js +57 -7
- package/dist/runners/maestro.js.map +1 -1
- package/dist/runners/maestro_generator.d.ts +1 -1
- package/dist/runners/maestro_generator.d.ts.map +1 -1
- package/dist/runners/maestro_generator.js +3 -2
- package/dist/runners/maestro_generator.js.map +1 -1
- package/dist/runners/screenshot.d.ts +6 -0
- package/dist/runners/screenshot.d.ts.map +1 -1
- package/dist/runners/screenshot.js +20 -10
- package/dist/runners/screenshot.js.map +1 -1
- package/dist/runners/semantics_audit.d.ts +32 -0
- package/dist/runners/semantics_audit.d.ts.map +1 -0
- package/dist/runners/semantics_audit.js +140 -0
- package/dist/runners/semantics_audit.js.map +1 -0
- package/dist/runners/video_recorder.d.ts +3 -1
- package/dist/runners/video_recorder.d.ts.map +1 -1
- package/dist/runners/video_recorder.js +44 -12
- package/dist/runners/video_recorder.js.map +1 -1
- package/dist/runners/wayland.d.ts +32 -0
- package/dist/runners/wayland.d.ts.map +1 -0
- package/dist/runners/wayland.js +49 -0
- package/dist/runners/wayland.js.map +1 -0
- package/dist/runners/window_manager.d.ts +55 -25
- package/dist/runners/window_manager.d.ts.map +1 -1
- package/dist/runners/window_manager.js +171 -71
- package/dist/runners/window_manager.js.map +1 -1
- package/dist/tools/discover_interactions.d.ts +22 -0
- package/dist/tools/discover_interactions.d.ts.map +1 -1
- package/dist/tools/discover_interactions.js +283 -6
- package/dist/tools/discover_interactions.js.map +1 -1
- package/dist/tools/discover_screens.d.ts +2 -0
- package/dist/tools/discover_screens.d.ts.map +1 -1
- package/dist/tools/discover_screens.js +139 -1
- package/dist/tools/discover_screens.js.map +1 -1
- package/dist/tools/gate_check.d.ts.map +1 -1
- package/dist/tools/gate_check.js +16 -2
- package/dist/tools/gate_check.js.map +1 -1
- package/dist/tools/plan_change_journey.d.ts.map +1 -1
- package/dist/tools/plan_change_journey.js +15 -2
- package/dist/tools/plan_change_journey.js.map +1 -1
- package/dist/tools/plan_user_journey.d.ts.map +1 -1
- package/dist/tools/plan_user_journey.js +5 -2
- package/dist/tools/plan_user_journey.js.map +1 -1
- package/dist/tools/run_journey.d.ts +70 -0
- package/dist/tools/run_journey.d.ts.map +1 -1
- package/dist/tools/run_journey.js +209 -21
- package/dist/tools/run_journey.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +55 -11
- package/dist/tools/verify.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists which device a journey/recording is driving so follow-up
|
|
3
|
+
* `codeloop_interact` / screenshot / video calls hit the SAME device
|
|
4
|
+
* instead of adb's "whatever single device happens to be attached"
|
|
5
|
+
* (a hard error with 2+ devices) or simctl's "booted" (ambiguous with
|
|
6
|
+
* 2+ booted simulators).
|
|
7
|
+
*
|
|
8
|
+
* Stored at `.codeloop/active_target.json` in the project root —
|
|
9
|
+
* deliberately a file (not process memory) because the MCP server can
|
|
10
|
+
* be restarted between the journey and the agent's follow-up calls.
|
|
11
|
+
*/
|
|
12
|
+
export interface ActiveTarget {
|
|
13
|
+
target_type: string;
|
|
14
|
+
/** adb serial (emulator-5554) or simulator UDID. */
|
|
15
|
+
device_id?: string;
|
|
16
|
+
/** Human-readable device name when known (e.g. "iPhone 16 Pro"). */
|
|
17
|
+
device_name?: string;
|
|
18
|
+
/** App/bundle id when known. */
|
|
19
|
+
app_id?: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function saveActiveTarget(projectDir: string, target: Omit<ActiveTarget, "updated_at">): void;
|
|
23
|
+
export declare function loadActiveTarget(projectDir: string): ActiveTarget | null;
|
|
24
|
+
export declare function clearActiveTarget(projectDir: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the device id an interact/screenshot call should use:
|
|
27
|
+
* explicit param wins, then the persisted active target (only when its
|
|
28
|
+
* target_type matches the call's resolved target type).
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveDeviceId(explicit: string | undefined, projectDir: string, targetType: string): string | undefined;
|
|
31
|
+
//# sourceMappingURL=active_target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active_target.d.ts","sourceRoot":"","sources":["../../src/runners/active_target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,IAAI,CASnG;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAUxE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAK1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAOpB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists which device a journey/recording is driving so follow-up
|
|
3
|
+
* `codeloop_interact` / screenshot / video calls hit the SAME device
|
|
4
|
+
* instead of adb's "whatever single device happens to be attached"
|
|
5
|
+
* (a hard error with 2+ devices) or simctl's "booted" (ambiguous with
|
|
6
|
+
* 2+ booted simulators).
|
|
7
|
+
*
|
|
8
|
+
* Stored at `.codeloop/active_target.json` in the project root —
|
|
9
|
+
* deliberately a file (not process memory) because the MCP server can
|
|
10
|
+
* be restarted between the journey and the agent's follow-up calls.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
|
|
13
|
+
import { join } from "path";
|
|
14
|
+
function activeTargetPath(projectDir) {
|
|
15
|
+
return join(projectDir, ".codeloop", "active_target.json");
|
|
16
|
+
}
|
|
17
|
+
export function saveActiveTarget(projectDir, target) {
|
|
18
|
+
try {
|
|
19
|
+
const dir = join(projectDir, ".codeloop");
|
|
20
|
+
if (!existsSync(dir))
|
|
21
|
+
mkdirSync(dir, { recursive: true });
|
|
22
|
+
const payload = { ...target, updated_at: new Date().toISOString() };
|
|
23
|
+
writeFileSync(activeTargetPath(projectDir), JSON.stringify(payload, null, 2));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Best-effort — pinning still works for the in-process journey.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function loadActiveTarget(projectDir) {
|
|
30
|
+
try {
|
|
31
|
+
const p = activeTargetPath(projectDir);
|
|
32
|
+
if (!existsSync(p))
|
|
33
|
+
return null;
|
|
34
|
+
const parsed = JSON.parse(readFileSync(p, "utf-8"));
|
|
35
|
+
if (!parsed || typeof parsed !== "object" || !parsed.target_type)
|
|
36
|
+
return null;
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function clearActiveTarget(projectDir) {
|
|
44
|
+
try {
|
|
45
|
+
const p = activeTargetPath(projectDir);
|
|
46
|
+
if (existsSync(p))
|
|
47
|
+
unlinkSync(p);
|
|
48
|
+
}
|
|
49
|
+
catch { /* ignore */ }
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the device id an interact/screenshot call should use:
|
|
53
|
+
* explicit param wins, then the persisted active target (only when its
|
|
54
|
+
* target_type matches the call's resolved target type).
|
|
55
|
+
*/
|
|
56
|
+
export function resolveDeviceId(explicit, projectDir, targetType) {
|
|
57
|
+
if (explicit && explicit.trim().length > 0)
|
|
58
|
+
return explicit.trim();
|
|
59
|
+
const persisted = loadActiveTarget(projectDir);
|
|
60
|
+
if (persisted?.device_id && persisted.target_type === targetType) {
|
|
61
|
+
return persisted.device_id;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=active_target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active_target.js","sourceRoot":"","sources":["../../src/runners/active_target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACpF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,SAAS,gBAAgB,CAAC,UAAkB;IAC1C,OAAO,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,MAAwC;IAC3F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAiB,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAClF,aAAa,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAiB,CAAC;QACpE,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA4B,EAC5B,UAAkB,EAClB,UAAkB;IAElB,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnE,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,SAAS,EAAE,SAAS,IAAI,SAAS,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACjE,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Android SDK tool resolution (P2.1).
|
|
3
|
+
*
|
|
4
|
+
* Android Studio installs the SDK but does NOT put platform-tools on the
|
|
5
|
+
* shell PATH — `adb` works inside Studio's terminal and fails everywhere
|
|
6
|
+
* else (a top Windows support issue, but the same applies on macOS/Linux).
|
|
7
|
+
*
|
|
8
|
+
* Instead of threading an absolute adb path through the ~40 call sites
|
|
9
|
+
* (window_manager, screenshot, app_logger, device_probe, app_launcher,
|
|
10
|
+
* video_recorder, …) we resolve the SDK once at server startup and append
|
|
11
|
+
* its tool directories to process.env.PATH. Every child process — our own
|
|
12
|
+
* runCommand/spawn calls AND third-party tools like Maestro that shell out
|
|
13
|
+
* to adb themselves — inherits the fixed PATH.
|
|
14
|
+
*/
|
|
15
|
+
export interface AndroidSdkResolution {
|
|
16
|
+
/** Resolved SDK root, or null when no SDK was found. */
|
|
17
|
+
sdk_root: string | null;
|
|
18
|
+
/** Where the root came from. */
|
|
19
|
+
source: "ANDROID_HOME" | "ANDROID_SDK_ROOT" | "default_location" | null;
|
|
20
|
+
/** Tool directories appended to PATH by this call (empty when adb was already reachable or no SDK found). */
|
|
21
|
+
dirs_added: string[];
|
|
22
|
+
/** True when adb was already reachable through PATH before this call. */
|
|
23
|
+
adb_already_on_path: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Default per-OS SDK install locations used by Android Studio. */
|
|
26
|
+
export declare function defaultSdkLocations(os?: string, home?: string, env?: NodeJS.ProcessEnv): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Finds the Android SDK root: ANDROID_HOME, then ANDROID_SDK_ROOT, then
|
|
29
|
+
* the default Android Studio install location. A candidate only counts
|
|
30
|
+
* when it actually contains platform-tools/adb.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findAndroidSdkRoot(env?: NodeJS.ProcessEnv, os?: string, home?: string): {
|
|
33
|
+
root: string;
|
|
34
|
+
source: AndroidSdkResolution["source"];
|
|
35
|
+
} | null;
|
|
36
|
+
/** SDK subdirectories that hold CLI tools we (or Maestro) invoke. */
|
|
37
|
+
export declare function androidToolDirs(sdkRoot: string): string[];
|
|
38
|
+
/** True when some PATH entry contains the adb binary. */
|
|
39
|
+
export declare function adbOnPath(env?: NodeJS.ProcessEnv, os?: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Ensures adb/emulator are reachable via PATH, appending the resolved
|
|
42
|
+
* SDK tool dirs to `env.PATH` when they are not. Idempotent. Returns
|
|
43
|
+
* what happened so doctor / launch errors can explain the resolution.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ensureAndroidToolsOnPath(env?: NodeJS.ProcessEnv, os?: string, home?: string): AndroidSdkResolution;
|
|
46
|
+
/**
|
|
47
|
+
* One-line human summary for doctor output / launch failure hints.
|
|
48
|
+
*/
|
|
49
|
+
export declare function describeAndroidSdkResolution(r: AndroidSdkResolution, os?: string): string;
|
|
50
|
+
//# sourceMappingURL=android_sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"android_sdk.d.ts","sourceRoot":"","sources":["../../src/runners/android_sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gCAAgC;IAChC,MAAM,EAAE,cAAc,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,IAAI,CAAC;IACxE,6GAA6G;IAC7G,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yEAAyE;IACzE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAMD,mEAAmE;AACnE,wBAAgB,mBAAmB,CACjC,EAAE,GAAE,MAAmB,EACvB,IAAI,GAAE,MAAkB,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CASV;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,EAAE,GAAE,MAAmB,EACvB,IAAI,GAAE,MAAkB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAA;CAAE,GAAG,IAAI,CAiBjE;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAIzD;AAED,yDAAyD;AACzD,wBAAgB,SAAS,CACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,EAAE,GAAE,MAAmB,GACtB,OAAO,CAOT;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,EAAE,GAAE,MAAmB,EACvB,IAAI,GAAE,MAAkB,GACvB,oBAAoB,CA4BtB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,oBAAoB,EAAE,EAAE,GAAE,MAAmB,GAAG,MAAM,CAgBrG"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Android SDK tool resolution (P2.1).
|
|
3
|
+
*
|
|
4
|
+
* Android Studio installs the SDK but does NOT put platform-tools on the
|
|
5
|
+
* shell PATH — `adb` works inside Studio's terminal and fails everywhere
|
|
6
|
+
* else (a top Windows support issue, but the same applies on macOS/Linux).
|
|
7
|
+
*
|
|
8
|
+
* Instead of threading an absolute adb path through the ~40 call sites
|
|
9
|
+
* (window_manager, screenshot, app_logger, device_probe, app_launcher,
|
|
10
|
+
* video_recorder, …) we resolve the SDK once at server startup and append
|
|
11
|
+
* its tool directories to process.env.PATH. Every child process — our own
|
|
12
|
+
* runCommand/spawn calls AND third-party tools like Maestro that shell out
|
|
13
|
+
* to adb themselves — inherits the fixed PATH.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync } from "fs";
|
|
16
|
+
import { homedir, platform } from "os";
|
|
17
|
+
import { delimiter, join } from "path";
|
|
18
|
+
function adbBinaryName(os) {
|
|
19
|
+
return os === "win32" ? "adb.exe" : "adb";
|
|
20
|
+
}
|
|
21
|
+
/** Default per-OS SDK install locations used by Android Studio. */
|
|
22
|
+
export function defaultSdkLocations(os = platform(), home = homedir(), env = process.env) {
|
|
23
|
+
if (os === "win32") {
|
|
24
|
+
const local = env.LOCALAPPDATA || join(home, "AppData", "Local");
|
|
25
|
+
return [join(local, "Android", "Sdk")];
|
|
26
|
+
}
|
|
27
|
+
if (os === "darwin") {
|
|
28
|
+
return [join(home, "Library", "Android", "sdk")];
|
|
29
|
+
}
|
|
30
|
+
return [join(home, "Android", "Sdk"), join(home, "Android", "sdk")];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Finds the Android SDK root: ANDROID_HOME, then ANDROID_SDK_ROOT, then
|
|
34
|
+
* the default Android Studio install location. A candidate only counts
|
|
35
|
+
* when it actually contains platform-tools/adb.
|
|
36
|
+
*/
|
|
37
|
+
export function findAndroidSdkRoot(env = process.env, os = platform(), home = homedir()) {
|
|
38
|
+
const adb = adbBinaryName(os);
|
|
39
|
+
const candidates = [
|
|
40
|
+
{ root: env.ANDROID_HOME, source: "ANDROID_HOME" },
|
|
41
|
+
{ root: env.ANDROID_SDK_ROOT, source: "ANDROID_SDK_ROOT" },
|
|
42
|
+
...defaultSdkLocations(os, home, env).map((root) => ({
|
|
43
|
+
root,
|
|
44
|
+
source: "default_location",
|
|
45
|
+
})),
|
|
46
|
+
];
|
|
47
|
+
for (const c of candidates) {
|
|
48
|
+
if (!c.root)
|
|
49
|
+
continue;
|
|
50
|
+
if (existsSync(join(c.root, "platform-tools", adb))) {
|
|
51
|
+
return { root: c.root, source: c.source };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/** SDK subdirectories that hold CLI tools we (or Maestro) invoke. */
|
|
57
|
+
export function androidToolDirs(sdkRoot) {
|
|
58
|
+
return [join(sdkRoot, "platform-tools"), join(sdkRoot, "emulator")].filter((d) => existsSync(d));
|
|
59
|
+
}
|
|
60
|
+
/** True when some PATH entry contains the adb binary. */
|
|
61
|
+
export function adbOnPath(env = process.env, os = platform()) {
|
|
62
|
+
const adb = adbBinaryName(os);
|
|
63
|
+
const pathVar = env.PATH || env.Path || "";
|
|
64
|
+
for (const dir of pathVar.split(delimiter)) {
|
|
65
|
+
if (dir && existsSync(join(dir, adb)))
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Ensures adb/emulator are reachable via PATH, appending the resolved
|
|
72
|
+
* SDK tool dirs to `env.PATH` when they are not. Idempotent. Returns
|
|
73
|
+
* what happened so doctor / launch errors can explain the resolution.
|
|
74
|
+
*/
|
|
75
|
+
export function ensureAndroidToolsOnPath(env = process.env, os = platform(), home = homedir()) {
|
|
76
|
+
const found = findAndroidSdkRoot(env, os, home);
|
|
77
|
+
if (adbOnPath(env, os)) {
|
|
78
|
+
return {
|
|
79
|
+
sdk_root: found?.root ?? null,
|
|
80
|
+
source: found?.source ?? null,
|
|
81
|
+
dirs_added: [],
|
|
82
|
+
adb_already_on_path: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (!found) {
|
|
86
|
+
return { sdk_root: null, source: null, dirs_added: [], adb_already_on_path: false };
|
|
87
|
+
}
|
|
88
|
+
const current = (env.PATH || "").split(delimiter).filter(Boolean);
|
|
89
|
+
const added = [];
|
|
90
|
+
for (const dir of androidToolDirs(found.root)) {
|
|
91
|
+
if (!current.includes(dir)) {
|
|
92
|
+
current.push(dir);
|
|
93
|
+
added.push(dir);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
env.PATH = current.join(delimiter);
|
|
97
|
+
return {
|
|
98
|
+
sdk_root: found.root,
|
|
99
|
+
source: found.source,
|
|
100
|
+
dirs_added: added,
|
|
101
|
+
adb_already_on_path: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* One-line human summary for doctor output / launch failure hints.
|
|
106
|
+
*/
|
|
107
|
+
export function describeAndroidSdkResolution(r, os = platform()) {
|
|
108
|
+
if (r.adb_already_on_path) {
|
|
109
|
+
return r.sdk_root
|
|
110
|
+
? `adb found on PATH (SDK root: ${r.sdk_root}, via ${r.source})`
|
|
111
|
+
: "adb found on PATH";
|
|
112
|
+
}
|
|
113
|
+
if (r.dirs_added.length > 0) {
|
|
114
|
+
return `adb was not on PATH — appended ${r.dirs_added.join(", ")} from the ${r.source === "default_location" ? "default Android Studio SDK location" : String(r.source)} (${r.sdk_root})`;
|
|
115
|
+
}
|
|
116
|
+
const fix = os === "win32"
|
|
117
|
+
? 'set ANDROID_HOME to your SDK (usually %LOCALAPPDATA%\\Android\\Sdk) and add %ANDROID_HOME%\\platform-tools to PATH'
|
|
118
|
+
: os === "darwin"
|
|
119
|
+
? 'set ANDROID_HOME to your SDK (usually ~/Library/Android/sdk) and add $ANDROID_HOME/platform-tools to PATH'
|
|
120
|
+
: 'set ANDROID_HOME to your SDK (usually ~/Android/Sdk) and add $ANDROID_HOME/platform-tools to PATH';
|
|
121
|
+
return `adb not found: no Android SDK at ANDROID_HOME, ANDROID_SDK_ROOT, or the default install location. Install Android Studio (or sdkmanager platform-tools), then ${fix}.`;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=android_sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"android_sdk.js","sourceRoot":"","sources":["../../src/runners/android_sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,11 +27,69 @@ export interface LaunchAppOptions {
|
|
|
27
27
|
bootedDevice?: string;
|
|
28
28
|
/** Where to tee launcher stdout/stderr (best-effort). */
|
|
29
29
|
logPath?: string;
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* HARD CAP on the launch wait (`e2e.launch_timeout_seconds`). The wait is
|
|
32
|
+
* stall-aware — a build that keeps producing output keeps the wait alive —
|
|
33
|
+
* so this is the absolute bound, not the expected duration.
|
|
34
|
+
*/
|
|
31
35
|
readyTimeoutMs?: number;
|
|
36
|
+
/** Fail after this much launcher SILENCE (`e2e.launch_stall_seconds`). */
|
|
37
|
+
stallTimeoutMs?: number;
|
|
32
38
|
/** Optional extra args (flavor/target/dart-define). */
|
|
33
39
|
extraArgs?: string[];
|
|
40
|
+
/**
|
|
41
|
+
* P5.5 (0.1.92) — progress heartbeat while the launcher builds/installs.
|
|
42
|
+
* Called at most every ~10s with the elapsed wait and the launcher's latest
|
|
43
|
+
* output line, so a 12-minute cold build reads as visible progress instead
|
|
44
|
+
* of a hang. Best-effort: callback errors never affect the launch.
|
|
45
|
+
*/
|
|
46
|
+
onProgress?: (u: {
|
|
47
|
+
elapsedMs: number;
|
|
48
|
+
lastLine: string;
|
|
49
|
+
}) => void;
|
|
50
|
+
/** P3.1 (0.1.93) — pin the Xcode scheme for native-iOS builds (`e2e.ios_scheme`); skips scheme auto-detection. */
|
|
51
|
+
iosScheme?: string;
|
|
52
|
+
/** P3.1 (0.1.93) — Xcode build configuration for native-iOS builds, default "Debug" (`e2e.ios_configuration`). */
|
|
53
|
+
iosConfiguration?: string;
|
|
54
|
+
/** P3.2 (0.1.93) — Gradle install task for native-Android builds, e.g. ":app:installDevDebug" (`e2e.gradle_install_task`). */
|
|
55
|
+
gradleInstallTask?: string;
|
|
56
|
+
/** P3.2 (0.1.93) — explicit applicationId to launch after install, for flavor/suffix builds (`e2e.android_app_id`). */
|
|
57
|
+
androidAppId?: string;
|
|
34
58
|
}
|
|
59
|
+
/** Last non-empty output line of a launcher buffer (pure, for heartbeats). */
|
|
60
|
+
export declare function lastOutputLine(buffer: string): string;
|
|
61
|
+
/** Heartbeat throttle: emit when at least intervalMs passed (pure). */
|
|
62
|
+
export declare function shouldEmitHeartbeat(now: number, lastEmitAt: number, intervalMs?: number): boolean;
|
|
63
|
+
/** Why the launch wait stopped (pure helper, unit-testable). */
|
|
64
|
+
export type WaitVerdict = {
|
|
65
|
+
keep_waiting: true;
|
|
66
|
+
} | {
|
|
67
|
+
keep_waiting: false;
|
|
68
|
+
why: "stalled" | "hard_cap";
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Decide whether the ready-wait loop should keep waiting. Pure so the
|
|
72
|
+
* stall-vs-cap policy is testable without spawning real builds.
|
|
73
|
+
*/
|
|
74
|
+
export declare function shouldKeepWaiting(s: {
|
|
75
|
+
now: number;
|
|
76
|
+
startedAt: number;
|
|
77
|
+
lastOutputAt: number;
|
|
78
|
+
stallMs: number;
|
|
79
|
+
hardCapMs: number;
|
|
80
|
+
}): WaitVerdict;
|
|
81
|
+
/**
|
|
82
|
+
* 0.1.90 (P0.2) — reuse the verify-phase build. A full verify on a mobile
|
|
83
|
+
* Flutter project already built the app (`flutter build ios --simulator` /
|
|
84
|
+
* gradle); relaunching via plain `flutter run` then rebuilds from scratch —
|
|
85
|
+
* the second 12-minute build WedCheese hit. When a FRESH prebuilt binary
|
|
86
|
+
* exists (newer than the newest source edit, minus a 60s jitter buffer),
|
|
87
|
+
* launch with `flutter run --use-application-binary <path>` instead.
|
|
88
|
+
*
|
|
89
|
+
* iOS accepts a .app bundle directory; Android the debug APK (both verified
|
|
90
|
+
* against flutter_tools' IOSApp.fromPrebuiltApp / ApplicationPackageFactory).
|
|
91
|
+
*/
|
|
92
|
+
export declare function findFreshPrebuilt(cwd: string, target: JourneyTarget): string | null;
|
|
35
93
|
/**
|
|
36
94
|
* Launch the app for an interactive journey. Returns a handle whose `stop()`
|
|
37
95
|
* quits the app. Only the Flutter path actually builds+launches today; native
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_launcher.d.ts","sourceRoot":"","sources":["../../src/runners/app_launcher.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"app_launcher.d.ts","sourceRoot":"","sources":["../../src/runners/app_launcher.ts"],"names":[],"mappings":"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"}
|