@farmslot/recipe-harness 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ All notable changes to `@farmslot/recipe-harness` are tracked here.
6
6
 
7
7
  - Active-development baseline; add user-facing changes here before release or package publication.
8
8
 
9
+ ## 0.4.0 - 2026-07-07
10
+
11
+ - Add a standard outer `app.lifecycle` adapter for Android and iOS simulator launch/foreground/terminate/restart lifecycle control, with Android background support for performance recipes. Exported as `@farmslot/recipe-harness/adapters/app-lifecycle`.
12
+
9
13
  ## 0.3.3 - 2026-07-03
10
14
 
11
15
  - `resolved-flows.json` is emitted whenever a run had any library resolution activity (used, overridden, or shadowed flows) — previously a run that overrode every library flow with recipe-local declarations produced no artifact even though `summary.json` recorded the overrides
@@ -0,0 +1,41 @@
1
+ import type { ActionAdapter, ActionExecutionContext } from '../core/types.js';
2
+ export type AppLifecyclePlatform = 'android' | 'ios-simulator';
3
+ export type AppLifecycleCommand = 'launch' | 'foreground' | 'background' | 'terminate' | 'restart';
4
+ export interface AppLifecycleTarget {
5
+ platform: AppLifecyclePlatform;
6
+ /** Android adb serial or iOS simulator UDID/name. */
7
+ deviceId?: string;
8
+ /** Android package name or iOS bundle id. */
9
+ appId: string;
10
+ /** Optional deep link used for Expo/dev-client launch and foreground. */
11
+ launchUrl?: string;
12
+ /** Optional Metro port to reverse on Android before opening Expo/dev-client. */
13
+ metroPort?: string | number;
14
+ /** Optional host-side calls to run immediately before launch/foreground. */
15
+ prelaunchCalls?: AppLifecycleCall[];
16
+ }
17
+ export interface AppLifecycleExecResult {
18
+ stdout?: string;
19
+ stderr?: string;
20
+ }
21
+ export interface AppLifecycleCommandRunner {
22
+ execFile(file: string, args: string[], options?: {
23
+ timeoutMs?: number;
24
+ }): Promise<AppLifecycleExecResult>;
25
+ }
26
+ export interface AppLifecycleCall {
27
+ file: string;
28
+ args: string[];
29
+ ignoreFailureWhenOutputIncludes?: string[];
30
+ }
31
+ export interface AppLifecycleTargetProvider {
32
+ resolveTarget(node: Record<string, unknown>, context: ActionExecutionContext): Promise<AppLifecycleTarget> | AppLifecycleTarget;
33
+ }
34
+ export interface CreateAppLifecycleAdapterOptions {
35
+ actions?: Iterable<string>;
36
+ targetProvider: AppLifecycleTargetProvider;
37
+ commandRunner?: AppLifecycleCommandRunner;
38
+ }
39
+ export declare function createAppLifecycleAdapters(options: CreateAppLifecycleAdapterOptions): ActionAdapter[];
40
+ export declare function createAppLifecycleAdapter(options: CreateAppLifecycleAdapterOptions): ActionAdapter;
41
+ //# sourceMappingURL=app-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-lifecycle.d.ts","sourceRoot":"","sources":["../../src/adapters/app-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI9E,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAEnG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,CACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CACrD;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,cAAc,EAAE,0BAA0B,CAAC;IAC3C,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,gCAAgC,GACxC,aAAa,EAAE,CAGjB;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,aAAa,CA4Cf"}
@@ -0,0 +1,203 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { asNumber, asOptionalString } from '../core/json.js';
4
+ const execFileAsync = promisify(execFile);
5
+ export function createAppLifecycleAdapters(options) {
6
+ if (options.actions && !new Set(options.actions).has('app.lifecycle'))
7
+ return [];
8
+ return [createAppLifecycleAdapter(options)];
9
+ }
10
+ export function createAppLifecycleAdapter(options) {
11
+ const commandRunner = options.commandRunner ?? defaultCommandRunner();
12
+ return {
13
+ action: 'app.lifecycle',
14
+ async execute(node, context) {
15
+ // Validate every node input before resolving the target or running any
16
+ // command, so a bad knob can never fail the action after side effects.
17
+ const command = parseLifecycleCommand(node);
18
+ const timeoutMs = optionalIntegerInRange(node.timeout_ms, 'app.lifecycle.timeout_ms', 0, Number.MAX_SAFE_INTEGER);
19
+ const settleMs = optionalIntegerInRange(node.settle_ms, 'app.lifecycle.settle_ms', 0, 60_000);
20
+ const target = await options.targetProvider.resolveTarget(node, context);
21
+ const calls = lifecycleCalls(command, target);
22
+ const results = [];
23
+ for (const call of calls) {
24
+ const result = await execLifecycleCall(commandRunner, call, timeoutMs);
25
+ results.push({
26
+ file: call.file,
27
+ args: call.args,
28
+ stdout: result.stdout ?? '',
29
+ stderr: result.stderr ?? '',
30
+ ignoredFailure: result.ignoredFailure ?? false,
31
+ });
32
+ }
33
+ if (settleMs !== undefined) {
34
+ await new Promise((resolve) => setTimeout(resolve, settleMs));
35
+ }
36
+ return {
37
+ output: {
38
+ command,
39
+ platform: target.platform,
40
+ deviceId: target.deviceId ?? null,
41
+ appId: target.appId,
42
+ launchUrl: target.launchUrl ?? null,
43
+ calls: results,
44
+ settleMs: settleMs ?? 0,
45
+ },
46
+ };
47
+ },
48
+ };
49
+ }
50
+ function parseLifecycleCommand(node) {
51
+ // `event` and `state` are accepted as aliases for `command` so recipes can use
52
+ // the field name that reads best for their flow (e.g. state: background).
53
+ const raw = asOptionalString(node.command, 'app.lifecycle.command') ??
54
+ asOptionalString(node.event, 'app.lifecycle.event') ??
55
+ asOptionalString(node.state, 'app.lifecycle.state');
56
+ if (!raw) {
57
+ throw new Error('app.lifecycle.command must be explicit (aliases: event, state). Supported commands: launch, foreground, background, terminate, restart.');
58
+ }
59
+ const command = raw;
60
+ if (command === 'launch' ||
61
+ command === 'foreground' ||
62
+ command === 'background' ||
63
+ command === 'terminate' ||
64
+ command === 'restart') {
65
+ return command;
66
+ }
67
+ throw new Error(`Unsupported app.lifecycle command: ${command}. Supported commands: launch, foreground, background, terminate, restart.`);
68
+ }
69
+ function lifecycleCalls(command, target) {
70
+ if (!target.appId || !target.appId.trim()) {
71
+ throw new Error('app.lifecycle target requires appId.');
72
+ }
73
+ if (command === 'restart') {
74
+ return [
75
+ ...lifecycleCalls('terminate', target),
76
+ ...(target.prelaunchCalls ?? []),
77
+ ...lifecycleCalls('launch', target),
78
+ ];
79
+ }
80
+ if (command === 'launch' || command === 'foreground') {
81
+ return [...(target.prelaunchCalls ?? []), ...lifecyclePlatformCalls(command, target)];
82
+ }
83
+ return lifecyclePlatformCalls(command, target);
84
+ }
85
+ function lifecyclePlatformCalls(command, target) {
86
+ if (target.platform === 'android')
87
+ return androidLifecycleCalls(command, target);
88
+ if (target.platform === 'ios-simulator')
89
+ return iosSimulatorLifecycleCalls(command, target);
90
+ throw new Error(`Unsupported app.lifecycle platform: ${String(target.platform)}`);
91
+ }
92
+ function androidLifecycleCalls(command, target) {
93
+ const adb = 'adb';
94
+ const serialArgs = target.deviceId ? ['-s', target.deviceId] : [];
95
+ if (command === 'background') {
96
+ return [{ file: adb, args: [...serialArgs, 'shell', 'input', 'keyevent', 'HOME'] }];
97
+ }
98
+ if (command === 'terminate') {
99
+ return [{ file: adb, args: [...serialArgs, 'shell', 'am', 'force-stop', target.appId] }];
100
+ }
101
+ if (target.launchUrl) {
102
+ const calls = [];
103
+ if (target.metroPort !== undefined && target.metroPort !== '') {
104
+ const port = String(target.metroPort);
105
+ calls.push({
106
+ file: adb,
107
+ args: [...serialArgs, 'reverse', `tcp:${port}`, `tcp:${port}`],
108
+ });
109
+ }
110
+ calls.push({
111
+ file: adb,
112
+ args: [
113
+ ...serialArgs,
114
+ 'shell',
115
+ 'am',
116
+ 'start',
117
+ '-a',
118
+ 'android.intent.action.VIEW',
119
+ '-d',
120
+ target.launchUrl,
121
+ ],
122
+ });
123
+ return calls;
124
+ }
125
+ return [
126
+ {
127
+ file: adb,
128
+ args: [
129
+ ...serialArgs,
130
+ 'shell',
131
+ 'monkey',
132
+ '-p',
133
+ target.appId,
134
+ '-c',
135
+ 'android.intent.category.LAUNCHER',
136
+ '1',
137
+ ],
138
+ },
139
+ ];
140
+ }
141
+ function iosSimulatorLifecycleCalls(command, target) {
142
+ const device = target.deviceId ?? 'booted';
143
+ if (command === 'background') {
144
+ // iOS Simulator has no direct HOME equivalent; foreground Settings to background the app under test.
145
+ return [{ file: 'xcrun', args: ['simctl', 'launch', device, 'com.apple.Preferences'] }];
146
+ }
147
+ if (command === 'terminate') {
148
+ return [
149
+ {
150
+ file: 'xcrun',
151
+ args: ['simctl', 'terminate', device, target.appId],
152
+ // simctl terminate exits non-zero when the app is already stopped; restart should remain idempotent.
153
+ ignoreFailureWhenOutputIncludes: ['not running'],
154
+ },
155
+ ];
156
+ }
157
+ if (target.launchUrl) {
158
+ return [{ file: 'xcrun', args: ['simctl', 'openurl', device, target.launchUrl] }];
159
+ }
160
+ return [{ file: 'xcrun', args: ['simctl', 'launch', device, target.appId] }];
161
+ }
162
+ async function execLifecycleCall(commandRunner, call, timeoutMs) {
163
+ try {
164
+ return await commandRunner.execFile(call.file, call.args, { timeoutMs });
165
+ }
166
+ catch (error) {
167
+ const text = error instanceof Error ? error.message : String(error);
168
+ if (call.ignoreFailureWhenOutputIncludes?.some((needle) => text.includes(needle))) {
169
+ return { stderr: text, ignoredFailure: true };
170
+ }
171
+ throw error;
172
+ }
173
+ }
174
+ function optionalIntegerInRange(value, label, min, max) {
175
+ if (value == null)
176
+ return undefined;
177
+ const number = asNumber(value, label);
178
+ if (!Number.isInteger(number) || number < min || number > max) {
179
+ throw new Error(`${label} must be an integer from ${min} through ${max}.`);
180
+ }
181
+ return number;
182
+ }
183
+ function defaultCommandRunner() {
184
+ return {
185
+ async execFile(file, args, options) {
186
+ try {
187
+ return await execFileAsync(file, args, {
188
+ timeout: options?.timeoutMs,
189
+ encoding: 'utf8',
190
+ });
191
+ }
192
+ catch (error) {
193
+ if (error instanceof Error) {
194
+ const output = error;
195
+ const details = [output.message, output.stderr, output.stdout].filter(Boolean).join('\n');
196
+ throw new Error(`${file} ${args.join(' ')} failed: ${details}`);
197
+ }
198
+ throw error;
199
+ }
200
+ },
201
+ };
202
+ }
203
+ //# sourceMappingURL=app-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-lifecycle.js","sourceRoot":"","sources":["../../src/adapters/app-lifecycle.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export type { AppLifecycleCommand, AppLifecycleCommandRunner, AppLifecyclePlatform, AppLifecycleTarget, AppLifecycleTargetProvider, CreateAppLifecycleAdapterOptions, } from './adapters/app-lifecycle.js';
2
+ export { createAppLifecycleAdapter, createAppLifecycleAdapters } from './adapters/app-lifecycle.js';
1
3
  export { createStandardCoreAdapters } from './adapters/core.js';
2
4
  export type { StandardUiAction, UiActionTransport, UiTransportControl, UiTransportResult, } from './adapters/ui.js';
3
5
  export { createStandardUiAdapters, normalizeUiTransportResult, STANDARD_UI_ACTIONS, } from './adapters/ui.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,mBAAmB,iBAAiB,CAAC;AACrC,YAAY,EAAE,iCAAiC,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EACL,gCAAgC,EAChC,YAAY,EACZ,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,mBAAmB,iBAAiB,CAAC;AACrC,YAAY,EAAE,iCAAiC,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EACL,gCAAgC,EAChC,YAAY,EACZ,cAAc,GACf,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { createAppLifecycleAdapter, createAppLifecycleAdapters } from './adapters/app-lifecycle.js';
1
2
  export { createStandardCoreAdapters } from './adapters/core.js';
2
3
  export { createStandardUiAdapters, normalizeUiTransportResult, STANDARD_UI_ACTIONS, } from './adapters/ui.js';
3
4
  export { defaultRecipeLibrarySources, loadRecipeLibraries, parseRecipeLibraryPath, personalRecipeLibraryRoot, resolveRecipeLibrarySources, } from './core/library.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAOhE,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EACL,gCAAgC,EAChC,YAAY,EACZ,cAAc,GACf,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAOhE,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EACL,gCAAgC,EAChC,YAAY,EACZ,cAAc,GACf,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farmslot/recipe-harness",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,6 +43,11 @@
43
43
  "import": "./dist/adapters/core.js",
44
44
  "default": "./dist/adapters/core.js"
45
45
  },
46
+ "./adapters/app-lifecycle": {
47
+ "types": "./dist/adapters/app-lifecycle.d.ts",
48
+ "import": "./dist/adapters/app-lifecycle.js",
49
+ "default": "./dist/adapters/app-lifecycle.js"
50
+ },
46
51
  "./adapters/ui": {
47
52
  "types": "./dist/adapters/ui.d.ts",
48
53
  "import": "./dist/adapters/ui.js",