agent-device 0.20.1 → 0.20.2

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 (103) hide show
  1. package/README.md +0 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.apk → agent-device-android-ime-helper-0.20.2.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.2.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.manifest.json → agent-device-android-ime-helper-0.20.2.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.apk → agent-device-android-snapshot-helper-0.20.2.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.2.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.manifest.json → agent-device-android-snapshot-helper-0.20.2.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +2 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1 -35
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -32
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Orientation.swift +92 -0
  12. package/dist/src/agent-device-client.js +2 -2
  13. package/dist/src/android.js +1 -1
  14. package/dist/src/app-lifecycle.js +5 -5
  15. package/dist/src/app-log-request-scope.js +1 -1
  16. package/dist/src/app-resolution.js +1 -1
  17. package/dist/src/apps.js +5 -5
  18. package/dist/src/cli-config.js +1 -1
  19. package/dist/src/cli-help.js +6 -6
  20. package/dist/src/cli-runner.js +1 -1
  21. package/dist/src/cli.js +14 -14
  22. package/dist/src/click-button.d.ts +5 -0
  23. package/dist/src/client-metro.js +1 -0
  24. package/dist/src/command-schema.js +3 -3
  25. package/dist/src/context.js +1 -1
  26. package/dist/src/contracts.d.ts +1 -1
  27. package/dist/src/device-input-state.js +1 -1
  28. package/dist/src/device.js +9 -0
  29. package/dist/src/devices2.js +1 -1
  30. package/dist/src/find.js +1 -1
  31. package/dist/src/generic.js +1 -1
  32. package/dist/src/gesture-plan-types.js +1 -0
  33. package/dist/src/gesture-plan.js +1 -0
  34. package/dist/src/index.d.ts +1174 -1413
  35. package/dist/src/input-actions.js +4 -4
  36. package/dist/src/install-artifact.js +5 -1
  37. package/dist/src/install-artifact2.js +1 -0
  38. package/dist/src/interaction-snapshot.js +1 -1
  39. package/dist/src/interaction.d.ts +3 -6
  40. package/dist/src/interaction.js +1 -1
  41. package/dist/src/interactor.js +2 -2
  42. package/dist/src/interactor2.js +1 -1
  43. package/dist/src/internal/bin.js +1 -1
  44. package/dist/src/internal/daemon.js +14 -22
  45. package/dist/src/lease-context.js +1 -1
  46. package/dist/src/lease.js +1 -1
  47. package/dist/src/limrun.d.ts +361 -0
  48. package/dist/src/limrun.js +1 -0
  49. package/dist/src/linux.js +1 -1
  50. package/dist/src/logcat.js +1 -5
  51. package/dist/src/metro.d.ts +71 -2
  52. package/dist/src/metro.js +1 -1
  53. package/dist/src/metro2.js +1 -1
  54. package/dist/src/notifications.js +1 -1
  55. package/dist/src/physical-device-control.js +1 -0
  56. package/dist/src/plist.js +1 -0
  57. package/dist/src/react-native.js +1 -1
  58. package/dist/src/recording-export-quality.js +13 -13
  59. package/dist/src/register-builtins.js +1 -1
  60. package/dist/src/registry.js +18 -18
  61. package/dist/src/remote-config.d.ts +5 -2
  62. package/dist/src/remote-config.js +1 -1
  63. package/dist/src/remote-config2.js +1 -0
  64. package/dist/src/reporting.js +8 -8
  65. package/dist/src/runner-client.js +1 -1
  66. package/dist/src/runner-disposal.js +1 -2
  67. package/dist/src/runner-lease.js +1 -1
  68. package/dist/src/runtime-transport.js +1 -1
  69. package/dist/src/runtime.js +3 -3
  70. package/dist/src/runtime2.js +1 -1
  71. package/dist/src/sdk-android-adb.d.ts +4 -2
  72. package/dist/src/sdk-batch-runner.d.ts +13 -3
  73. package/dist/src/sdk-batch-runner.js +1 -1
  74. package/dist/src/sdk-contracts.d.ts +28 -2
  75. package/dist/src/sdk-contracts.js +2 -2
  76. package/dist/src/sdk-finders.d.ts +1 -1
  77. package/dist/src/sdk-remote-config.d.ts +119 -4
  78. package/dist/src/selector-runtime.js +1 -1
  79. package/dist/src/selector-vocabulary.js +1 -1
  80. package/dist/src/selectors.d.ts +1 -1
  81. package/dist/src/server.js +2 -2
  82. package/dist/src/session-target-evidence.js +1 -1
  83. package/dist/src/session.js +8 -8
  84. package/dist/src/simulator.js +1 -1
  85. package/dist/src/snapshot-diagnostics.js +4 -4
  86. package/dist/src/snapshot2.js +1 -1
  87. package/dist/src/tool-provider.js +3 -3
  88. package/dist/src/tool-provider2.js +1 -1
  89. package/dist/src/tool-provider3.js +1 -1
  90. package/dist/src/tv-remote.d.ts +213 -0
  91. package/dist/src/xml.js +2 -0
  92. package/package.json +37 -17
  93. package/server.json +2 -2
  94. package/smithery.yaml +1 -1
  95. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +0 -1
  96. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk.sha256 +0 -1
  97. package/dist/src/android-system-chrome.js +0 -1
  98. package/dist/src/client-metro-companion.js +0 -1
  99. package/dist/src/metro-types.d.ts +0 -52
  100. package/dist/src/project-runtime.js +0 -1
  101. package/dist/src/scoped-provider.js +0 -1
  102. package/dist/src/simctl.js +0 -1
  103. package/dist/src/snapshot-quality.js +0 -1
@@ -0,0 +1,2 @@
1
+ const e=new Set(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.:-`),t=new Set([` `,` `,`
2
+ `,`\r`]),n=new Set([`__defineGetter__`,`__defineSetter__`,`__proto__`,`constructor`,`prototype`]);function r(e,t={}){let n=t.maxDocumentChars??134217728;if(e.length>n)throw Error(`XML document exceeds maximum supported size of ${n} characters.`);return new a(e).parse()}function i(e,t){for(let n of e){if(n.name===`dict`)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],i=n.children[e+1];r?.name===`key`&&r.text&&i&&t(r.text,i)}i(n.children,t)}}var a=class{roots=[];stack=[];index=0;xml;constructor(e){this.xml=e}parse(){for(this.skipByteOrderMark();this.index<this.xml.length;)this.readNextToken();return this.assertFullyClosed(),this.roots}readNextToken(){if(this.xml[this.index]!==`<`){this.readText();return}this.resolveMarkupReader()()}resolveMarkupReader(){return this.startsWith(`<!--`)?()=>this.skipUntil(`-->`,`Comment is not closed.`):this.startsWith(`<?`)?()=>this.skipUntil(`?>`,`Processing instruction is not closed.`):this.startsWith(`<![CDATA[`)?()=>this.readCdata():this.startsWith(`<!`)?()=>this.skipDeclaration():this.startsWith(`</`)?()=>this.readClosingTag():()=>this.readOpeningTag()}assertFullyClosed(){if(this.stack.length>0){let e=this.stack[this.stack.length-1];throw Error(`Unclosed XML tag <${e?.name??`unknown`}>.`)}}skipByteOrderMark(){this.xml.charCodeAt(0)===65279&&(this.index=1)}readOpeningTag(){this.index+=1,this.skipWhitespace();let e=this.readRequiredName(`Missing XML tag name at offset ${this.index}.`),{attributes:t,selfClosing:n}=this.readOpeningTagBody(),r={name:e,attributes:t,text:null,children:[]};this.addNode(r),n||this.pushOpenNode(r)}readOpeningTagBody(){let e={};for(;;){this.skipWhitespace();let t=this.readOpeningTagEnd();if(t)return{attributes:e,selfClosing:t===`self-closing`};let n=this.readAttribute();e[n.name]=n.value}}readOpeningTagEnd(){if(this.index>=this.xml.length)throw Error(`Opening XML tag is not closed.`);return this.xml[this.index]===`>`?(this.index+=1,`open`):this.xml[this.index]===`/`&&this.xml[this.index+1]===`>`?(this.index+=2,`self-closing`):null}readAttribute(){let e=this.readRequiredName(`Invalid XML attribute at offset ${this.index}.`);if(f(e),this.skipWhitespace(),this.xml[this.index]!==`=`)throw Error(`Missing value for XML attribute "${e}".`);return this.index+=1,this.skipWhitespace(),{name:e,value:this.readAttributeValue(e)}}pushOpenNode(e){if(this.stack.length>=256)throw Error(`Maximum XML nesting depth of 256 exceeded.`);this.stack.push(e)}readClosingTag(){this.index+=2,this.skipWhitespace();let e=this.readName();if(this.skipWhitespace(),this.xml[this.index]!==`>`)throw Error(`Closing XML tag </${e}> is not closed.`);this.index+=1;let t=this.stack.pop();if(!t)throw Error(`Unexpected closing XML tag </${e}>.`);if(t.name!==e)throw Error(`Expected </${t.name}> before </${e}>.`)}readText(){let e=this.xml.indexOf(`<`,this.index),t=e===-1?this.xml.length:e;this.appendText(this.xml.slice(this.index,t),!0),this.index=t}readCdata(){let e=this.index+9,t=this.xml.indexOf(`]]>`,e);if(t===-1)throw Error(`CDATA section is not closed.`);this.appendText(this.xml.slice(e,t),!1),this.index=t+3}appendText(e,t){let n=e.trim();if(!n)return;let r=this.stack[this.stack.length-1];r&&(r.text=`${r.text??``}${t?p(n):n}`)}addNode(e){let t=this.stack[this.stack.length-1];t?t.children.push(e):this.roots.push(e)}readName(){let e=this.index;for(;this.index<this.xml.length&&o(this.xml[this.index]);)this.index+=1;return this.xml.slice(e,this.index)}readRequiredName(e){let t=this.readName();if(!t)throw Error(e);return t}readAttributeValue(e){let t=this.xml[this.index];if(t!==`"`&&t!==`'`)throw Error(`XML attribute "${e}" must use a quoted value.`);this.index+=1;let n=this.index,r=this.xml.indexOf(t,n);if(r===-1)throw Error(`XML attribute "${e}" is not closed.`);return this.index=r+1,p(this.xml.slice(n,r).trim())}skipDeclaration(){let e={quote:null,bracketDepth:0};for(let t=this.index+2;t<this.xml.length;t+=1)if(c(e,this.xml[t])){this.index=t+1;return}throw Error(`XML declaration is not closed.`)}skipUntil(e,t){let n=this.xml.indexOf(e,this.index+e.length);if(n===-1)throw Error(t);this.index=n+e.length}skipWhitespace(){for(;this.index<this.xml.length&&s(this.xml[this.index]);)this.index+=1}startsWith(e){return this.xml.startsWith(e,this.index)}};function o(t){return t!==void 0&&e.has(t)}function s(e){return e!==void 0&&t.has(e)}function c(e,t){return t===void 0||l(e,t)?!1:(u(e,t),d(e,t))}function l(e,t){return e.quote?(t===e.quote&&(e.quote=null),!0):t===`"`||t===`'`?(e.quote=t,!0):!1}function u(e,t){if(t===`[`){e.bracketDepth+=1;return}t===`]`&&e.bracketDepth>0&&--e.bracketDepth}function d(e,t){return t===`>`&&e.bracketDepth===0}function f(e){if(n.has(e))throw Error(`Unsupported XML attribute name "${e}".`)}function p(e){return e.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|amp|lt|gt|quot|apos);/g,(e,t)=>{switch(t){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return m(e,t)}})}function m(e,t){let n=t.startsWith(`#x`)?Number.parseInt(t.slice(2),16):Number(t.slice(1));if(!Number.isInteger(n)||n<0||n>1114111)return e;try{return String.fromCodePoint(n)}catch{return e}}export{i as n,r as t};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "description": "Agent-native CLI for AI app automation across iOS, Android, tvOS, Android TV, macOS, Linux, and web.",
5
5
  "mcpName": "io.github.callstackincubator/agent-device",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@
14
14
  "url": "https://github.com/callstack/agent-device/issues"
15
15
  },
16
16
  "type": "module",
17
- "packageManager": "pnpm@11.1.2",
17
+ "packageManager": "pnpm@11.17.0",
18
18
  "main": "dist/src/index.js",
19
19
  "types": "dist/src/index.d.ts",
20
20
  "exports": {
@@ -50,6 +50,10 @@
50
50
  "import": "./dist/src/android-adb.js",
51
51
  "types": "./dist/src/android-adb.d.ts"
52
52
  },
53
+ "./limrun": {
54
+ "import": "./dist/src/limrun.js",
55
+ "types": "./dist/src/limrun.d.ts"
56
+ },
53
57
  "./contracts": {
54
58
  "import": "./dist/src/contracts.js",
55
59
  "types": "./dist/src/contracts.d.ts"
@@ -88,14 +92,14 @@
88
92
  "build:xcuitest:tvos:clean": "pnpm clean:xcuitest:tvos && pnpm build:xcuitest:tvos",
89
93
  "build:xcuitest:visionos": "AGENT_DEVICE_XCUITEST_PLATFORM=visionos sh ./scripts/build-xcuitest-apple.sh",
90
94
  "build:xcuitest:visionos:clean": "pnpm clean:xcuitest:visionos && pnpm build:xcuitest:visionos",
91
- "build:android-snapshot-helper": "sh ./scripts/build-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
92
- "package:android-snapshot-helper": "sh ./scripts/package-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
93
- "package:android-snapshot-helper:npm": "rm -rf android/snapshot-helper/dist && sh ./scripts/package-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") android/snapshot-helper/dist",
95
+ "build:android-snapshot-helper": "AGENT_DEVICE_ANDROID_HELPER=snapshot sh ./scripts/build-android-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
96
+ "package:android-snapshot-helper": "AGENT_DEVICE_ANDROID_HELPER=snapshot sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
97
+ "package:android-snapshot-helper:npm": "rm -rf android/snapshot-helper/dist && AGENT_DEVICE_ANDROID_HELPER=snapshot sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") android/snapshot-helper/dist",
94
98
  "package:apple-runner:npm": "node scripts/package-apple-runner-source.mjs",
95
99
  "build:android": "pnpm package:android-snapshot-helper:npm && pnpm package:android-ime-helper:npm",
96
- "build:android-ime-helper": "sh ./scripts/build-android-ime-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper",
97
- "package:android-ime-helper": "sh ./scripts/package-android-ime-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper",
98
- "package:android-ime-helper:npm": "rm -rf android/ime-helper/dist && sh ./scripts/package-android-ime-helper.sh $(node -p \"require('./package.json').version\") android/ime-helper/dist",
100
+ "build:android-ime-helper": "AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/build-android-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper",
101
+ "package:android-ime-helper": "AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper",
102
+ "package:android-ime-helper:npm": "rm -rf android/ime-helper/dist && AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") android/ime-helper/dist",
99
103
  "build:macos-helper": "swift build -c release --package-path apple/macos-helper",
100
104
  "build:all": "pnpm build:node && pnpm build:xcuitest",
101
105
  "ad": "node bin/agent-device.mjs",
@@ -103,35 +107,47 @@
103
107
  "maestro:conformance": "node --experimental-strip-types --test scripts/maestro-conformance/verify.test.ts scripts/maestro-conformance/differential/run.test.ts scripts/maestro-conformance/differential/invariants.test.ts",
104
108
  "maestro:conformance:regenerate": "node scripts/maestro-conformance/regenerate.mjs",
105
109
  "maestro:conformance:differential": "node --experimental-strip-types scripts/maestro-conformance/differential/run.ts",
110
+ "prototype:program-boundary": "node --experimental-strip-types scripts/prototypes/daemon-boundaries/program-boundary.ts",
111
+ "prototype:session-boundary": "node --experimental-strip-types scripts/prototypes/daemon-boundaries/session-boundary.ts",
106
112
  "size": "node scripts/size-report.mjs",
107
113
  "size:markdown": "node scripts/size-report.mjs --json .tmp/size-report.json --markdown .tmp/size-report.md",
108
114
  "perf": "node --experimental-strip-types scripts/perf/run.ts",
109
115
  "perf:ios": "node --experimental-strip-types scripts/perf/run.ts --platform ios",
110
116
  "perf:android": "node --experimental-strip-types scripts/perf/run.ts --platform android",
117
+ "mutation:run": "node --experimental-strip-types scripts/mutation/run.ts",
118
+ "mutation:baseline": "node --experimental-strip-types scripts/mutation/run.ts --update",
119
+ "mutation:check": "node --experimental-strip-types scripts/mutation/run.ts --no-run",
120
+ "mutation:affected": "node --experimental-strip-types scripts/mutation/run.ts --affected",
121
+ "mutation:test": "node --experimental-strip-types --test scripts/mutation/*.test.ts",
111
122
  "lint": "oxlint . --deny-warnings",
112
- "format": "node ./node_modules/oxfmt/bin/oxfmt --write src test skills scripts/help-conformance-bench.mjs scripts/help-conformance-case-checks.mjs scripts/help-conformance-command-validator.ts scripts/help-conformance-expectations.mjs scripts/help-conformance-plan-validator.mjs scripts/help-conformance-runner-output.mjs scripts/help-conformance-summary.mjs scripts/help-conformance-cases.mjs scripts/help-conformance-sample-outputs.mjs scripts/__tests__/help-conformance-bench.test.ts scripts/__tests__/help-conformance-sample-outputs.test.ts scripts/__tests__/help-conformance-topic-coverage.test.ts package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
113
- "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check src test skills scripts/help-conformance-bench.mjs scripts/help-conformance-case-checks.mjs scripts/help-conformance-command-validator.ts scripts/help-conformance-expectations.mjs scripts/help-conformance-plan-validator.mjs scripts/help-conformance-runner-output.mjs scripts/help-conformance-summary.mjs scripts/help-conformance-cases.mjs scripts/help-conformance-sample-outputs.mjs scripts/__tests__/help-conformance-bench.test.ts scripts/__tests__/help-conformance-sample-outputs.test.ts scripts/__tests__/help-conformance-topic-coverage.test.ts package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
123
+ "format": "node ./node_modules/oxfmt/bin/oxfmt --write",
124
+ "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check",
125
+ "fuzz:parsers": "node --experimental-strip-types scripts/fuzz/run.ts",
114
126
  "fallow": "fallow audit --base origin/main",
115
127
  "fallow:all": "fallow --summary",
116
128
  "fallow:baseline": "(fallow dead-code --save-baseline fallow-baselines/dead-code.json --summary || true) && (fallow health --save-baseline fallow-baselines/health.json --summary || true)",
117
129
  "check:fallow": "fallow audit",
118
130
  "check:affected": "node --experimental-strip-types scripts/check-affected/run.ts",
119
131
  "check:affected:test": "node --experimental-strip-types --test scripts/check-affected/model.test.ts scripts/check-affected/run.test.ts",
120
- "check:layering": "node --experimental-strip-types --test scripts/layering/model.test.ts && node --experimental-strip-types scripts/layering/check.ts",
132
+ "check:coverage-changed": "node --experimental-strip-types scripts/coverage-changed/run.ts",
133
+ "check:coverage-changed:test": "node --experimental-strip-types --test scripts/coverage-changed/model.test.ts scripts/coverage-changed/run.test.ts",
134
+ "check:layering": "node --experimental-strip-types --test scripts/layering/model.test.ts scripts/layering/zone-policy.test.ts && node --experimental-strip-types scripts/layering/check.ts",
121
135
  "depgraph": "node --experimental-strip-types scripts/depgraph/build.ts",
122
- "depgraph:test": "node --experimental-strip-types --test scripts/depgraph/model.test.ts",
136
+ "depgraph:test": "node --experimental-strip-types --test scripts/depgraph/model.test.ts scripts/depgraph/affected.test.ts",
123
137
  "check:production-exports": "fallow dead-code --config fallow-production-exports.json --production --unused-exports --fail-on-issues",
124
138
  "check:bundle-owner-files": "node --experimental-strip-types scripts/check-bundle-owner-files.ts",
139
+ "check:command-docs": "vitest run --project unit-core src/__tests__/command-doc-coverage.test.ts",
140
+ "check:replay-compat": "node --experimental-strip-types scripts/check-replay-compat-provenance.ts",
125
141
  "check:freerange": "fr",
126
142
  "check:quick": "pnpm lint && pnpm typecheck",
127
143
  "sync:mcp-metadata": "node scripts/sync-mcp-metadata.mjs",
128
144
  "check:mcp-metadata": "node scripts/sync-mcp-metadata.mjs --check",
129
145
  "version": "node scripts/sync-mcp-metadata.mjs && git add server.json",
130
146
  "check:tooling": "pnpm lint && pnpm typecheck && pnpm check:layering && pnpm depgraph:test && pnpm check:production-exports && pnpm check:mcp-metadata && pnpm build && pnpm check:bundle-owner-files",
131
- "check:unit": "pnpm test:unit && pnpm test:smoke",
147
+ "check:unit": "pnpm check:contention-retry && pnpm test:unit && pnpm test:smoke",
132
148
  "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit",
133
149
  "prepack": "pnpm check:mcp-metadata && pnpm build:all && pnpm package:apple-runner:npm && pnpm package:android-snapshot-helper:npm && pnpm package:android-ime-helper:npm",
134
- "typecheck": "tsc -p tsconfig.json",
150
+ "typecheck": "tsc -p tsconfig.json && tsc -p examples/sdk/tsconfig.json",
135
151
  "test-app:install": "pnpm install --dir examples/test-app",
136
152
  "test-app:start": "pnpm --dir examples/test-app start",
137
153
  "test-app:ios": "pnpm --dir examples/test-app ios",
@@ -145,16 +161,18 @@
145
161
  "test": "vitest run --project unit-core --project subprocess-stub",
146
162
  "test:unit": "vitest run --project unit-core --project subprocess-stub",
147
163
  "test:coverage": "vitest run --coverage",
164
+ "test:coverage:ci": "node --experimental-strip-types scripts/lib/contention-retry-run.ts --coverage",
165
+ "check:contention-retry": "node --experimental-strip-types --test scripts/lib/contention-retry-policy.test.ts",
148
166
  "test:integration:provider": "vitest run --project provider-integration",
149
167
  "test:integration:progress": "node --experimental-strip-types scripts/integration-progress.ts",
150
168
  "test:integration:progress:check": "node --experimental-strip-types scripts/integration-progress.ts --check",
169
+ "test:fixture-cache": "node --test test/ci/trusted-fixture-artifact.test.mjs",
151
170
  "test:output-economy": "vitest run --project output-economy",
152
171
  "test:smoke:web": "pnpm build && node --test test/integration/smoke-web-platform.test.ts",
153
- "test:skillgym": "node test/skillgym/runner-environment.ts && pnpm build && skillgym run ./test/skillgym/suites/agent-device-smoke-suite.ts --config ./test/skillgym/skillgym.config.ts",
154
- "test:skillgym:case": "node test/skillgym/runner-environment.ts && pnpm build && skillgym run ./test/skillgym/suites/agent-device-smoke-suite.ts --config ./test/skillgym/skillgym.config.ts --case",
155
172
  "test:smoke": "node --test test/integration/smoke-*.test.ts",
156
173
  "test:integration:node": "node --test test/integration/*.test.ts",
157
174
  "test:integration": "pnpm test:integration:node && pnpm test:integration:provider",
175
+ "test:concurrency-torture": "node --test test/integration/nightly/concurrency-torture.test.ts",
158
176
  "test:replay:ios": "node --experimental-strip-types src/bin.ts test test/integration/replays/ios/simulator",
159
177
  "test:replay:ios-device": "node --experimental-strip-types src/bin.ts test test/integration/replays/ios/device",
160
178
  "test:replay:android": "node --experimental-strip-types src/bin.ts test test/integration/replays/android",
@@ -228,13 +246,15 @@
228
246
  },
229
247
  "devDependencies": {
230
248
  "@chenglou/freerange": "^0.0.1",
249
+ "@stryker-mutator/core": "9.6.1",
250
+ "@stryker-mutator/vitest-runner": "9.6.1",
231
251
  "@types/node": "^22.19.21",
232
252
  "@vitest/coverage-v8": "4.1.8",
233
253
  "fallow": "^2.95.0",
254
+ "fast-check": "^4.9.0",
234
255
  "oxc-parser": "^0.138.0",
235
256
  "oxfmt": "^0.42.0",
236
257
  "oxlint": "^1.69.0",
237
- "skillgym": "^0.9.1",
238
258
  "tsdown": "^0.22.4",
239
259
  "typescript": "^7.0.2",
240
260
  "vite": "^8.0.16",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/callstack/agent-device",
8
8
  "source": "github"
9
9
  },
10
- "version": "0.20.1",
10
+ "version": "0.20.2",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.20.1",
15
+ "version": "0.20.2",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
package/smithery.yaml CHANGED
@@ -1 +1 @@
1
- runtime: "typescript"
1
+ runtime: 'typescript'
@@ -1 +0,0 @@
1
- 8dc8135211465ef283d1c5175024638becb783b6975ecfd0b9a3ea38637eaa1c agent-device-android-ime-helper-0.20.1.apk
@@ -1 +0,0 @@
1
- 26ae795374725ac91a513dc2943521fdc16bf67c25e91cb1f49d0fa62f61c85e agent-device-android-snapshot-helper-0.20.1.apk
@@ -1 +0,0 @@
1
- const e=`com.android.systemui`;function t(t){let n=t??``;if(!n.startsWith(`com.android.systemui:id/`))return!1;let r=n.slice(`${e}:id/`.length);return/(^|_)(status_bar|navigation_bar)(_|$)/.test(r)}function n(e){return`systemChrome`in e&&e.systemChrome===!0}function r(e){if(!n(e))return e;let{systemChrome:t,...r}=e;return r}function i(e){return e.some(n)?e.map(r):e}export{r as a,i,n,t as r,e as t};
@@ -1 +0,0 @@
1
- import{b as e}from"./sdk-android-adb.js";import{a as t,n,o as r,u as i}from"./host-process.js";import{a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,s as _,u as v}from"./url.js";import{createHash as y}from"node:crypto";import b from"node:fs";import x from"node:path";import{fileURLToPath as S}from"node:url";const C=`companion-tunnel`;function w(e){return y(`sha256`).update(e).digest(`hex`)}function T(e){return e?.trim()?e.trim():void 0}function E(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e;if(!(typeof t.tenantId!=`string`||typeof t.runId!=`string`||typeof t.leaseId!=`string`))return{tenantId:t.tenantId,runId:t.runId,leaseId:t.leaseId}}function D(e,t){return e.tenantId===t.tenantId&&e.runId===t.runId&&e.leaseId===t.leaseId}function O(e,t,n,r){let i=r??x.join(e,`.agent-device`);if(!n)return{statePath:x.join(i,`${t.slug}.json`),logPath:x.join(i,`${t.slug}.log`)};let a=w(n).slice(0,12),o=x.join(i,t.slug);return{statePath:x.join(o,`${t.slug}-${a}.json`),logPath:x.join(o,`${t.slug}-${a}.log`)}}function k(e){try{let t=JSON.parse(b.readFileSync(e,`utf8`));if(!Number.isInteger(t.pid)||Number(t.pid)<=0||typeof t.serverBaseUrl!=`string`||typeof t.localBaseUrl!=`string`||typeof t.tokenHash!=`string`||t.tokenHash.length===0)return null;let n=Array.isArray(t.consumers)?t.consumers.filter(e=>typeof e==`string`&&e.length>0):[];return{pid:Number(t.pid),startTime:typeof t.startTime==`string`?t.startTime:void 0,command:typeof t.command==`string`?t.command:void 0,serverBaseUrl:t.serverBaseUrl,localBaseUrl:t.localBaseUrl,launchUrl:T(typeof t.launchUrl==`string`?t.launchUrl:void 0),registerPath:T(typeof t.registerPath==`string`?t.registerPath:void 0),unregisterPath:T(typeof t.unregisterPath==`string`?t.unregisterPath:void 0),devicePort:Number.isInteger(t.devicePort)?Number(t.devicePort):void 0,session:T(typeof t.session==`string`?t.session:void 0),bridgeScope:E(t.bridgeScope),tokenHash:t.tokenHash,consumers:n}}catch{return null}}function A(e,t){b.mkdirSync(x.dirname(e),{recursive:!0}),b.writeFileSync(e,`${JSON.stringify(t,null,2)}\n`,`utf8`)}function j(e){b.mkdirSync(x.dirname(e),{recursive:!0}),b.closeSync(b.openSync(e,`a`))}function M(e){try{b.unlinkSync(e)}catch{}}function N(e){try{b.unlinkSync(e)}catch{}}function P(e){try{b.readdirSync(e).length===0&&b.rmdirSync(e)}catch{}}function F(e,t){let n=x.dirname(e.statePath),r=x.dirname(e.logPath);M(e.statePath),N(e.logPath),P(n),r!==n&&P(r),x.basename(n)===t.slug&&P(x.dirname(n))}function I(e,t){return e.includes(t.runArg)}function L(e,i){if(!n(e.pid))return!1;if(e.startTime){let t=r(e.pid);if(!t||t!==e.startTime)return!1}let a=t(e.pid);return!a||!I(a,i.definition)||!e.bridgeScope?!1:e.serverBaseUrl===m(i.serverBaseUrl)&&e.localBaseUrl===m(i.localBaseUrl)&&e.launchUrl===T(i.launchUrl)&&e.registerPath===T(i.registerPath)&&e.unregisterPath===T(i.unregisterPath)&&e.devicePort===i.devicePort&&e.session===T(i.session)&&D(e.bridgeScope,i.bridgeScope)&&e.tokenHash===w(i.bearerToken)}function R(e){return T(e.consumerKey)??T(e.profileKey)??null}function z(e,t){return!t||e.consumers.includes(t)?e:{...e,consumers:[...e.consumers,t]}}function B(e,t){return t?{...e,consumers:e.consumers.filter(e=>e!==t)}:{...e,consumers:[]}}async function V(e,r){if(!n(e.pid))return;let a=t(e.pid);if(!(!a||!I(a,r))){try{process.kill(e.pid,`SIGTERM`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}if(!await i(e.pid,1e3)){try{process.kill(e.pid,`SIGKILL`)}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return;throw e}await i(e.pid,1e3)}}}function H(e,t){let n={...t};return n[c]=m(e.serverBaseUrl),n[d]=e.bearerToken,n[_]=m(e.localBaseUrl),n[p]=O(e.projectRoot,e.definition,e.profileKey,e.stateDir).statePath,n[s]=e.bridgeScope.tenantId,n[v]=e.bridgeScope.runId,n[f]=e.bridgeScope.leaseId,e.launchUrl?.trim()?n[h]=e.launchUrl.trim():delete n[h],e.registerPath?.trim()?n[o]=e.registerPath.trim():delete n[o],e.unregisterPath?.trim()?n[u]=e.unregisterPath.trim():delete n[u],e.devicePort===void 0?delete n[a]:n[a]=String(e.devicePort),e.session?.trim()?n[g]=e.session.trim():delete n[g],n}function U(e){let t=S(import.meta.url),n=x.extname(t)||`.js`,r=[x.join(x.dirname(t),`${C}${n}`),x.join(x.dirname(t),`internal`,`${C}${n}`)].find(e=>b.existsSync(e));if(!r)throw Error(`${e.displayName} entrypoint not found. Rebuild the package to include the companion worker entry.`);return r}function W(n,i){let a=U(n.definition),o=a.endsWith(`.ts`)?[`--experimental-strip-types`]:[];b.mkdirSync(x.dirname(i),{recursive:!0});let s=b.openSync(i,`a`),c=0;try{c=e(process.execPath,[...o,a,n.definition.runArg],{env:H(n,n.env??process.env),stdio:[`ignore`,s,s]})}finally{b.closeSync(s)}if(!Number.isInteger(c)||c<=0)throw Error(`Failed to start ${n.definition.displayName} process.`);return{pid:c,startTime:r(c)??void 0,command:t(c)??void 0,serverBaseUrl:m(n.serverBaseUrl),localBaseUrl:m(n.localBaseUrl),launchUrl:T(n.launchUrl),registerPath:T(n.registerPath),unregisterPath:T(n.unregisterPath),devicePort:n.devicePort,session:T(n.session),bridgeScope:n.bridgeScope,tokenHash:w(n.bearerToken),consumers:[]}}async function G(e){let t=R(e),n=O(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=k(n.statePath);if(r&&L(r,e)){let e=z(r,t);return e!==r&&A(n.statePath,e),{pid:r.pid,spawned:!1,statePath:n.statePath,logPath:n.logPath}}r&&(await V(r,e.definition),F(n,e.definition)),j(n.statePath);let i;try{i=W(e,n.logPath),A(n.statePath,z(i,t))}catch(t){throw i&&await V(i,e.definition).catch(()=>{}),F(n,e.definition),t}return{pid:i.pid,spawned:!0,statePath:n.statePath,logPath:n.logPath}}async function K(e){let t=R(e),n=O(e.projectRoot,e.definition,e.profileKey,e.stateDir),r=k(n.statePath);if(!r)return F(n,e.definition),{stopped:!1,statePath:n.statePath};let i=B(r,t);return i.consumers.length>0?(A(n.statePath,i),{stopped:!1,statePath:n.statePath}):(await V(r,e.definition),F(n,e.definition),{stopped:!0,statePath:n.statePath})}const q={slug:`metro-companion`,runArg:l,displayName:`Metro companion`};async function J(e){return await G({...e,definition:q,registerPath:e.registerPath??`/api/metro/companion/register`})}async function Y(e){return await K({...e,definition:q})}export{K as i,Y as n,G as r,J as t};
@@ -1,52 +0,0 @@
1
- import { v as SessionRuntimeHints } from "./sdk-contracts.js";
2
- //#region src/metro/metro-types.d.ts
3
- /** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
4
- type MetroRuntimeHints = SessionRuntimeHints;
5
- type MetroBridgeResult = {
6
- enabled: boolean;
7
- baseUrl: string;
8
- statusUrl: string;
9
- bundleUrl: string;
10
- iosRuntime: MetroRuntimeHints;
11
- androidRuntime: MetroRuntimeHints;
12
- upstream: {
13
- bundleUrl: string;
14
- host: string;
15
- port: number;
16
- statusUrl: string;
17
- };
18
- probe: {
19
- reachable: boolean;
20
- statusCode: number;
21
- latencyMs: number;
22
- detail: string;
23
- };
24
- };
25
- type MetroBridgeRuntimePayload = {
26
- metro_host?: string;
27
- metro_port?: number;
28
- metro_bundle_url?: string;
29
- launch_url?: string;
30
- };
31
- type MetroBridgeDescriptor = {
32
- enabled: boolean;
33
- base_url: string;
34
- status_url?: string;
35
- bundle_url?: string;
36
- ios_runtime: MetroBridgeRuntimePayload;
37
- android_runtime: MetroBridgeRuntimePayload;
38
- upstream: {
39
- bundle_url?: string;
40
- host?: string;
41
- port?: number;
42
- status_url?: string;
43
- };
44
- probe: {
45
- reachable: boolean;
46
- status_code: number;
47
- latency_ms: number;
48
- detail: string;
49
- };
50
- };
51
- //#endregion
52
- export { MetroBridgeResult as n, MetroRuntimeHints as r, MetroBridgeDescriptor as t };
@@ -1 +0,0 @@
1
- import e from"node:fs";import t from"node:path";function n(e){let t=i(e);return t?r(t):`auto`}function r(e){let t={...e.dependencies??{},...e.devDependencies??{}};return typeof t[`@callstack/repack`]==`string`?`repack`:typeof t.expo==`string`?`expo`:typeof t[`react-native`]==`string`?`react-native`:`auto`}function i(n){if(!n)return;let r=t.join(n,`package.json`);try{return JSON.parse(e.readFileSync(r,`utf8`))}catch{return}}export{r as n,i as r,n as t};
@@ -1 +0,0 @@
1
- import{AsyncLocalStorage as e}from"node:async_hooks";function t(t,n=e=>e){let r=new e;return{resolve(e){return e?n(e):r.getStore()??t},async run(e,t){return e?await r.run(n(e),t):await t()},hasScope(){return!!r.getStore()}}}export{t};
@@ -1 +0,0 @@
1
- import{s as e}from"./sdk-device.js";import{o as t}from"./boot-diagnostics.js";import{a as n}from"./tool-provider.js";function r(e,n={}){let r=t(n.simulatorSetPath);return r?[`simctl`,`--set`,r,...e]:[`simctl`,...e]}function i(t,n){return!e(t)||t.kind!==`simulator`?[`simctl`,...n]:r(n,{simulatorSetPath:t.simulatorSetPath})}function a(e,t,r){return n(i(e,t),r)}export{i as n,a as r,r as t};
@@ -1 +0,0 @@
1
- const e=new Set([`healthy`,`recovered`,`sparse`]),t=new Set([`tree`,`queries`,`private-ax`]),n=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`]);function r(r){if(!r||typeof r!=`object`)return;let i=r;if(!(typeof i.state!=`string`||!e.has(i.state))&&!(typeof i.backend!=`string`||!t.has(i.backend)))return{state:i.state,backend:i.backend,reason:typeof i.reason==`string`?i.reason:void 0,reasonCode:typeof i.reasonCode==`string`&&n.has(i.reasonCode)?i.reasonCode:void 0,effectiveDepth:typeof i.effectiveDepth==`number`?i.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(i.collapsedLeafIndexes)?i.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0}}function i(e){return e?.state===`sparse`}function a(e,t){return[...o(e),...s(e),...c(e,t)]}function o(e){return e.state===`recovered`?[`Detected an overly complex or slow accessibility tree. Fell back to the ${e.backend} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`]:[]}function s(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; this tree is capped at depth ${e.effectiveDepth}. Re-run with --depth ${e.effectiveDepth} --scope <container> only if you need deeper content.`]}function c(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}const l=new Set([`empty-helper-output`,`system-window-only`,`content-poor-app-window`]);function u(e){if(!e||typeof e!=`object`)return!1;let t=e.details?.androidSnapshotHelperFailureReason;return typeof t==`string`&&l.has(t)}export{a as i,u as n,r,i as t};