agent-scenario-loop 0.1.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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/app/profile-session.ts +812 -0
  4. package/core/config-template.json +41 -0
  5. package/dist/core/agent-summary.d.ts +15 -0
  6. package/dist/core/agent-summary.js +177 -0
  7. package/dist/core/artifact-contract.d.ts +151 -0
  8. package/dist/core/artifact-contract.js +897 -0
  9. package/dist/core/artifact-layout.d.ts +56 -0
  10. package/dist/core/artifact-layout.js +61 -0
  11. package/dist/core/artifact-writer.d.ts +44 -0
  12. package/dist/core/artifact-writer.js +55 -0
  13. package/dist/core/comparison.d.ts +133 -0
  14. package/dist/core/comparison.js +294 -0
  15. package/dist/core/evidence-interpreter.d.ts +28 -0
  16. package/dist/core/evidence-interpreter.js +69 -0
  17. package/dist/core/execution-plan.d.ts +44 -0
  18. package/dist/core/execution-plan.js +95 -0
  19. package/dist/core/planner.d.ts +132 -0
  20. package/dist/core/planner.js +812 -0
  21. package/dist/core/ports.d.ts +198 -0
  22. package/dist/core/ports.js +146 -0
  23. package/dist/core/run-index.d.ts +62 -0
  24. package/dist/core/run-index.js +143 -0
  25. package/dist/core/schema-validator.d.ts +86 -0
  26. package/dist/core/schema-validator.js +407 -0
  27. package/dist/index.d.ts +11 -0
  28. package/dist/index.js +27 -0
  29. package/dist/runner/agent-device-driver.d.ts +126 -0
  30. package/dist/runner/agent-device-driver.js +168 -0
  31. package/dist/runner/agent-device.d.ts +295 -0
  32. package/dist/runner/agent-device.js +1271 -0
  33. package/dist/runner/android-adb-driver.d.ts +175 -0
  34. package/dist/runner/android-adb-driver.js +399 -0
  35. package/dist/runner/android-adb.d.ts +254 -0
  36. package/dist/runner/android-adb.js +1618 -0
  37. package/dist/runner/argent-driver.d.ts +183 -0
  38. package/dist/runner/argent-driver.js +297 -0
  39. package/dist/runner/argent.d.ts +349 -0
  40. package/dist/runner/argent.js +1211 -0
  41. package/dist/runner/check-plan.d.ts +45 -0
  42. package/dist/runner/check-plan.js +210 -0
  43. package/dist/runner/cli.d.ts +20 -0
  44. package/dist/runner/cli.js +23 -0
  45. package/dist/runner/compare-latest.d.ts +99 -0
  46. package/dist/runner/compare-latest.js +233 -0
  47. package/dist/runner/compare.d.ts +58 -0
  48. package/dist/runner/compare.js +157 -0
  49. package/dist/runner/demo-loop.d.ts +45 -0
  50. package/dist/runner/demo-loop.js +170 -0
  51. package/dist/runner/example-android-live.d.ts +137 -0
  52. package/dist/runner/example-android-live.js +454 -0
  53. package/dist/runner/example-ios-live.d.ts +137 -0
  54. package/dist/runner/example-ios-live.js +471 -0
  55. package/dist/runner/host-doctor.d.ts +131 -0
  56. package/dist/runner/host-doctor.js +628 -0
  57. package/dist/runner/init-project.d.ts +88 -0
  58. package/dist/runner/init-project.js +263 -0
  59. package/dist/runner/ios-simctl-driver.d.ts +69 -0
  60. package/dist/runner/ios-simctl-driver.js +97 -0
  61. package/dist/runner/ios-simctl.d.ts +254 -0
  62. package/dist/runner/ios-simctl.js +1415 -0
  63. package/dist/runner/live-android.d.ts +137 -0
  64. package/dist/runner/live-android.js +539 -0
  65. package/dist/runner/live-comparison.d.ts +67 -0
  66. package/dist/runner/live-comparison.js +147 -0
  67. package/dist/runner/live-ios.d.ts +137 -0
  68. package/dist/runner/live-ios.js +460 -0
  69. package/dist/runner/live-proof-summary.d.ts +263 -0
  70. package/dist/runner/live-proof-summary.js +465 -0
  71. package/dist/runner/live-proof.d.ts +467 -0
  72. package/dist/runner/live-proof.js +920 -0
  73. package/dist/runner/local-env.d.ts +64 -0
  74. package/dist/runner/local-env.js +155 -0
  75. package/dist/runner/profile-android.d.ts +82 -0
  76. package/dist/runner/profile-android.js +671 -0
  77. package/dist/runner/profile-ios.d.ts +108 -0
  78. package/dist/runner/profile-ios.js +532 -0
  79. package/dist/runner/profile-mobile.d.ts +254 -0
  80. package/dist/runner/profile-mobile.js +1307 -0
  81. package/dist/runner/validate-project.d.ts +273 -0
  82. package/dist/runner/validate-project.js +1501 -0
  83. package/docs/adapters.md +145 -0
  84. package/docs/api.md +94 -0
  85. package/docs/authoring.md +196 -0
  86. package/docs/concepts.md +136 -0
  87. package/docs/consumer-rehearsal.md +115 -0
  88. package/docs/contracts.md +267 -0
  89. package/docs/live-proofs.md +270 -0
  90. package/docs/principles.md +46 -0
  91. package/examples/event-logs/app-startup-baseline.log +4 -0
  92. package/examples/event-logs/app-startup-current.log +4 -0
  93. package/examples/minimal-app/README.md +70 -0
  94. package/examples/mobile-app/README.md +302 -0
  95. package/examples/mobile-app/app.json +22 -0
  96. package/examples/mobile-app/asl/package-scripts.json +32 -0
  97. package/examples/mobile-app/asl.config.json +37 -0
  98. package/examples/mobile-app/event-logs/android-app-startup.log +4 -0
  99. package/examples/mobile-app/event-logs/android-open-close-cycle.log +12 -0
  100. package/examples/mobile-app/event-logs/android-scroll-settle.log +12 -0
  101. package/examples/mobile-app/event-logs/app-startup.log +4 -0
  102. package/examples/mobile-app/event-logs/open-close-cycle.log +12 -0
  103. package/examples/mobile-app/event-logs/scroll-settle.log +12 -0
  104. package/examples/mobile-app/index.ts +20 -0
  105. package/examples/mobile-app/metro.config.js +20 -0
  106. package/examples/mobile-app/package.json +62 -0
  107. package/examples/mobile-app/patches/expo-modules-jsi@56.0.10.patch +19 -0
  108. package/examples/mobile-app/plugins/with-ios-build-compat.js +271 -0
  109. package/examples/mobile-app/pnpm-lock.yaml +4440 -0
  110. package/examples/mobile-app/runner-manifests/evidence-provider.json +79 -0
  111. package/examples/mobile-app/runner-manifests/primary-runner.json +19 -0
  112. package/examples/mobile-app/scenarios/android/app-startup-video.json +73 -0
  113. package/examples/mobile-app/scenarios/android/app-startup.json +44 -0
  114. package/examples/mobile-app/scenarios/android/open-close-cycle.json +54 -0
  115. package/examples/mobile-app/scenarios/android/scroll-settle.json +49 -0
  116. package/examples/mobile-app/scenarios/ios/app-startup.json +44 -0
  117. package/examples/mobile-app/scenarios/ios/open-close-cycle.json +54 -0
  118. package/examples/mobile-app/scenarios/ios/scroll-settle.json +49 -0
  119. package/examples/mobile-app/scenarios/mobile/app-startup.json +91 -0
  120. package/examples/mobile-app/scenarios/mobile/open-close-cycle.json +160 -0
  121. package/examples/mobile-app/scenarios/mobile/scroll-settle.json +148 -0
  122. package/examples/mobile-app/scripts/asl-capture-accessibility-provider.mjs +112 -0
  123. package/examples/mobile-app/scripts/asl-capture-profiler-provider.mjs +127 -0
  124. package/examples/mobile-app/src/devtools/profile-session.ts +7 -0
  125. package/examples/mobile-app/src/example-screen.tsx +322 -0
  126. package/examples/mobile-app/tsconfig.json +16 -0
  127. package/examples/mobile-app/tsconfig.typecheck.json +13 -0
  128. package/examples/runners/README.md +44 -0
  129. package/examples/runners/adb-android.json +25 -0
  130. package/examples/runners/agent-device-android.json +27 -0
  131. package/examples/runners/agent-device-ios.json +27 -0
  132. package/examples/runners/argent-android.json +32 -0
  133. package/examples/runners/argent-ios.json +32 -0
  134. package/examples/runners/argent-react-profiler-provider.json +15 -0
  135. package/examples/runners/axe-accessibility-provider.json +24 -0
  136. package/examples/runners/manual-log-ingest.json +9 -0
  137. package/examples/runners/rozenite-profiler-provider.json +9 -0
  138. package/examples/runners/script-accessibility-provider.json +24 -0
  139. package/examples/runners/script-memory-provider.json +24 -0
  140. package/examples/runners/script-network-provider.json +24 -0
  141. package/examples/runners/script-profiler-provider.json +30 -0
  142. package/examples/runners/xcodebuildmcp-ios.json +29 -0
  143. package/examples/scenarios/ios/app-startup.json +28 -0
  144. package/examples/scenarios/ios/open-close-cycle.json +35 -0
  145. package/examples/scenarios/mobile/app-startup.json +72 -0
  146. package/examples/scenarios/mobile/media-open-close.json +141 -0
  147. package/examples/scenarios/mobile/open-close-cycle.json +135 -0
  148. package/examples/scenarios/mobile/scroll-settle.json +106 -0
  149. package/package.json +240 -0
  150. package/schemas/budget-verdict.schema.json +115 -0
  151. package/schemas/causal-run.schema.json +279 -0
  152. package/schemas/comparison.schema.json +196 -0
  153. package/schemas/health.schema.json +108 -0
  154. package/schemas/live-proof-set.schema.json +195 -0
  155. package/schemas/live-proof.schema.json +413 -0
  156. package/schemas/manifest.schema.json +204 -0
  157. package/schemas/metrics.schema.json +137 -0
  158. package/schemas/project-validation.schema.json +343 -0
  159. package/schemas/runner-capabilities.schema.json +217 -0
  160. package/schemas/scenario.schema.json +400 -0
  161. package/schemas/verdict.schema.json +88 -0
  162. package/templates/evidence-provider.json +83 -0
  163. package/templates/gitignore-snippet +9 -0
  164. package/templates/integration-readme.md +125 -0
  165. package/templates/mobile-scenario.json +133 -0
  166. package/templates/package-scripts.json +32 -0
  167. package/templates/primary-runner.json +19 -0
  168. package/templates/project.config.json +37 -0
  169. package/templates/scripts/asl-capture-accessibility-provider.mjs +112 -0
  170. package/templates/scripts/asl-capture-profiler-provider.mjs +127 -0
@@ -0,0 +1,19 @@
1
+ diff --git a/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift b/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift
2
+ index 38f7305..c8156cd 100644
3
+ --- a/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift
4
+ +++ b/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift
5
+ @@ -216,6 +216,12 @@ public final class JavaScriptRuntime: @unchecked Sendable {
6
+ .toOpaque()
7
+ // Pass a null setter to C++ when the Swift setter is nil so that JS assignment
8
+ // raises a `jsi::JSError` directly, without crossing the Swift boundary.
9
+ - let callbacks = expo.HostObjectCallbacks(
10
+ - context, getter, set == nil ? nil : setter, propertyNamesGetter, deallocate)
11
+ + let callbacks: expo.HostObjectCallbacks
12
+ + if set == nil {
13
+ + callbacks = expo.HostObjectCallbacks(
14
+ + context, getter, nil, propertyNamesGetter, deallocate)
15
+ + } else {
16
+ + callbacks = expo.HostObjectCallbacks(
17
+ + context, getter, setter, propertyNamesGetter, deallocate)
18
+ + }
19
+ let hostObject = expo.HostObject.makeObject(pointee, consume callbacks)
@@ -0,0 +1,271 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ const sceneDelegateContents = `import UIKit
5
+
6
+ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
7
+ var window: UIWindow?
8
+
9
+ func scene(
10
+ _ scene: UIScene,
11
+ willConnectTo session: UISceneSession,
12
+ options connectionOptions: UIScene.ConnectionOptions
13
+ ) {
14
+ guard let windowScene = scene as? UIWindowScene else {
15
+ return
16
+ }
17
+
18
+ let window = UIWindow(windowScene: windowScene)
19
+ self.window = window
20
+
21
+ if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
22
+ appDelegate.window = window
23
+ appDelegate.startReactNative(in: window)
24
+ }
25
+ }
26
+ }
27
+ `;
28
+
29
+ const deploymentTargetPatch = `
30
+ installer.pods_project.targets.each do |target|
31
+ target.build_configurations.each do |config|
32
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = podfile_properties['ios.deploymentTarget'] || '16.4'
33
+ end
34
+ end
35
+ `;
36
+
37
+ const reactNativeFactorySetup = ` let delegate = ReactNativeDelegate()
38
+ let factory = ExpoReactNativeFactory(delegate: delegate)
39
+ delegate.dependencyProvider = RCTAppDependencyProvider()
40
+
41
+ reactNativeDelegate = delegate
42
+ reactNativeFactory = factory`;
43
+
44
+ const prepareReactNativeFactoryFunction = ` func prepareReactNativeFactory() {
45
+ if reactNativeFactory != nil {
46
+ return
47
+ }
48
+
49
+ let delegate = ReactNativeDelegate()
50
+ let factory = ExpoReactNativeFactory(delegate: delegate)
51
+ delegate.dependencyProvider = RCTAppDependencyProvider()
52
+
53
+ reactNativeDelegate = delegate
54
+ reactNativeFactory = factory
55
+ }`;
56
+
57
+ const recursivePrepareReactNativeFactoryFunction = ` func prepareReactNativeFactory() {
58
+ if reactNativeFactory != nil {
59
+ return
60
+ }
61
+
62
+ prepareReactNativeFactory()
63
+ }`;
64
+
65
+ /**
66
+ * Applies the generated iOS compatibility patches needed by the Expo example app.
67
+ */
68
+ function withIosBuildCompat(config) {
69
+ config = withPodsDeploymentTarget(config);
70
+ config = withSceneInfoPlist(config);
71
+ config = loadExpoConfigPlugins().IOSConfig.XcodeProjectFile.withBuildSourceFile(config, {
72
+ filePath: 'SceneDelegate.swift',
73
+ contents: sceneDelegateContents,
74
+ overwrite: true,
75
+ });
76
+ config = withSceneAppDelegate(config);
77
+
78
+ return config;
79
+ }
80
+
81
+ /**
82
+ * Loads Expo config plugins only when Expo executes the app-local plugin.
83
+ */
84
+ function loadExpoConfigPlugins() {
85
+ return require('expo/config-plugins');
86
+ }
87
+
88
+ /**
89
+ * Pins all generated Pods deployment targets to the app target to avoid Xcode beta drift.
90
+ */
91
+ function withPodsDeploymentTarget(config) {
92
+ const { withDangerousMod } = loadExpoConfigPlugins();
93
+ return withDangerousMod(config, [
94
+ 'ios',
95
+ async (modConfig) => {
96
+ const podfilePath = path.join(modConfig.modRequest.platformProjectRoot, 'Podfile');
97
+ let podfile = fs.readFileSync(podfilePath, 'utf8');
98
+
99
+ if (podfile.includes("config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']")) {
100
+ return modConfig;
101
+ }
102
+
103
+ const anchor = ` )
104
+ end
105
+ end`;
106
+ const replacement = ` )
107
+ ${deploymentTargetPatch} end
108
+ end`;
109
+
110
+ if (!podfile.includes(anchor)) {
111
+ throw new Error('Unable to insert iOS build compatibility settings into generated Podfile.');
112
+ }
113
+
114
+ podfile = podfile.replace(anchor, replacement);
115
+ fs.writeFileSync(podfilePath, podfile);
116
+
117
+ return modConfig;
118
+ },
119
+ ]);
120
+ }
121
+
122
+ /**
123
+ * Declares a scene delegate so UIKit owns the window lifecycle on modern iOS.
124
+ */
125
+ function withSceneInfoPlist(config) {
126
+ const { withInfoPlist } = loadExpoConfigPlugins();
127
+ return withInfoPlist(config, (modConfig) => {
128
+ modConfig.modResults.UIApplicationSceneManifest = {
129
+ UIApplicationSupportsMultipleScenes: false,
130
+ UISceneConfigurations: {
131
+ UIWindowSceneSessionRoleApplication: [
132
+ {
133
+ UISceneConfigurationName: 'Default Configuration',
134
+ UISceneDelegateClassName: '$(PRODUCT_MODULE_NAME).SceneDelegate',
135
+ },
136
+ ],
137
+ },
138
+ };
139
+
140
+ return modConfig;
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Rewrites the generated Swift AppDelegate to defer React Native startup to SceneDelegate.
146
+ */
147
+ function withSceneAppDelegate(config) {
148
+ const { withAppDelegate } = loadExpoConfigPlugins();
149
+ return withAppDelegate(config, (modConfig) => {
150
+ if (modConfig.modResults.language !== 'swift') {
151
+ throw new Error('Expected a Swift AppDelegate for the ASL example iOS app.');
152
+ }
153
+
154
+ modConfig.modResults.contents = patchAppDelegate(modConfig.modResults.contents);
155
+ return modConfig;
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Produces an idempotent AppDelegate patch that works across repeated Expo prebuilds.
161
+ */
162
+ function patchAppDelegate(contents) {
163
+ let next = contents;
164
+
165
+ if (next.includes(recursivePrepareReactNativeFactoryFunction)) {
166
+ next = next.replace(recursivePrepareReactNativeFactoryFunction, prepareReactNativeFactoryFunction);
167
+ }
168
+
169
+ next = replaceBeforeAnchor(
170
+ next,
171
+ reactNativeFactorySetup,
172
+ ' prepareReactNativeFactory()',
173
+ '#if os(iOS) || os(tvOS)',
174
+ 'Unable to replace React Native factory setup in AppDelegate.swift.'
175
+ );
176
+
177
+ next = replaceOnce(
178
+ next,
179
+ `#if os(iOS) || os(tvOS)
180
+ window = UIWindow(frame: UIScreen.main.bounds)
181
+ factory.startReactNative(
182
+ withModuleName: "main",
183
+ in: window,
184
+ launchOptions: launchOptions)
185
+ #endif`,
186
+ `#if os(iOS) || os(tvOS)
187
+ if #unavailable(iOS 13.0) {
188
+ window = UIWindow(frame: UIScreen.main.bounds)
189
+ if let window {
190
+ startReactNative(in: window, launchOptions: launchOptions)
191
+ }
192
+ }
193
+ #endif`,
194
+ 'Unable to replace React Native startup window setup in AppDelegate.swift.'
195
+ );
196
+
197
+ if (!next.includes('func prepareReactNativeFactory()')) {
198
+ next = replaceOnce(
199
+ next,
200
+ ` // Linking API`,
201
+ `${prepareReactNativeFactoryFunction}
202
+
203
+ func startReactNative(
204
+ in window: UIWindow,
205
+ launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
206
+ ) {
207
+ prepareReactNativeFactory()
208
+ reactNativeFactory?.startReactNative(
209
+ withModuleName: "main",
210
+ in: window,
211
+ launchOptions: launchOptions)
212
+ }
213
+
214
+ public func application(
215
+ _ application: UIApplication,
216
+ configurationForConnecting connectingSceneSession: UISceneSession,
217
+ options: UIScene.ConnectionOptions
218
+ ) -> UISceneConfiguration {
219
+ return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
220
+ }
221
+
222
+ // Linking API`,
223
+ 'Unable to insert scene lifecycle helpers into AppDelegate.swift.'
224
+ );
225
+ }
226
+
227
+ return next;
228
+ }
229
+
230
+ /**
231
+ * Replaces one generated Swift fragment and fails loudly when the template shape changes.
232
+ */
233
+ function replaceOnce(contents, search, replacement, message) {
234
+ const first = contents.indexOf(search);
235
+ if (first === -1) {
236
+ if (contents.includes(replacement)) {
237
+ return contents;
238
+ }
239
+ throw new Error(message);
240
+ }
241
+
242
+ const second = contents.indexOf(search, first + search.length);
243
+ if (second !== -1) {
244
+ throw new Error(`${message} Found multiple matches.`);
245
+ }
246
+
247
+ return contents.slice(0, first) + replacement + contents.slice(first + search.length);
248
+ }
249
+
250
+ /**
251
+ * Replaces a generated Swift fragment only when it appears before a known anchor.
252
+ */
253
+ function replaceBeforeAnchor(contents, search, replacement, anchor, message) {
254
+ const anchorIndex = contents.indexOf(anchor);
255
+ if (anchorIndex === -1) {
256
+ throw new Error(message);
257
+ }
258
+
259
+ const first = contents.indexOf(search);
260
+ if (first === -1 || first > anchorIndex) {
261
+ if (contents.slice(0, anchorIndex).includes(replacement)) {
262
+ return contents;
263
+ }
264
+ throw new Error(message);
265
+ }
266
+
267
+ return contents.slice(0, first) + replacement + contents.slice(first + search.length);
268
+ }
269
+
270
+ module.exports = withIosBuildCompat;
271
+ module.exports.patchAppDelegate = patchAppDelegate;