agent-device 0.12.9 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -1
- package/dist/src/1974.js +2 -2
- package/dist/src/320.js +1 -1
- package/dist/src/3918.js +29 -28
- package/dist/src/7651.js +1 -1
- package/dist/src/8564.js +1 -1
- package/dist/src/8656.js +1 -0
- package/dist/src/9076.js +1 -1
- package/dist/src/9542.js +2 -2
- package/dist/src/backend.js +1 -1
- package/dist/src/bin.js +37 -37
- package/dist/src/contracts.d.ts +12 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon.js +18 -15
- package/dist/src/index.d.ts +34 -1
- package/dist/src/metro-companion.js +1 -1
- package/dist/src/metro.d.ts +21 -0
- package/dist/src/metro.js +1 -1
- package/package.json +12 -3
- package/skills/agent-device/SKILL.md +4 -1
- package/skills/agent-device/references/bootstrap-install.md +26 -6
- package/skills/agent-device/references/debugging.md +3 -1
- package/skills/agent-device/references/exploration.md +15 -2
- package/skills/agent-device/references/remote-tenancy.md +39 -19
- package/skills/agent-device/references/verification.md +3 -2
- package/skills/dogfood/SKILL.md +1 -0
- package/skills/react-devtools/SKILL.md +55 -0
- package/skills/react-devtools/references/commands.md +91 -0
- package/skills/react-devtools/references/profiling.md +74 -0
- package/dist/src/3883.js +0 -1
- package/dist/src/4993.js +0 -1
- package/dist/src/8164.js +0 -1
- package/dist/src/9323.js +0 -5
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# React Native Profiling
|
|
2
|
+
|
|
3
|
+
Use this workflow when the user reports slow interactions, excessive re-renders, unstable props, or unclear render causes.
|
|
4
|
+
|
|
5
|
+
## Baseline
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
agent-device react-devtools status
|
|
9
|
+
agent-device react-devtools count
|
|
10
|
+
agent-device react-devtools get tree --depth 3
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
If the app is not connected, run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
agent-device react-devtools start
|
|
17
|
+
agent-device react-devtools wait --connected
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then reload or relaunch the React Native app if needed.
|
|
21
|
+
|
|
22
|
+
## Capture One Interaction
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
agent-device react-devtools profile start "short label"
|
|
26
|
+
# Trigger exactly the interaction being investigated.
|
|
27
|
+
agent-device react-devtools profile stop
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Keep the profiling window narrow. Extra navigation, warm-up work, or unrelated gestures make the report harder to interpret.
|
|
31
|
+
|
|
32
|
+
## Identify Suspects
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
agent-device react-devtools profile slow --limit 5
|
|
36
|
+
agent-device react-devtools profile rerenders --limit 5
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- A component with high average render time is a slow-render suspect.
|
|
40
|
+
- A component with high render count is a re-render suspect.
|
|
41
|
+
- A component can be both.
|
|
42
|
+
|
|
43
|
+
## Drill In
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
agent-device react-devtools profile report @c12
|
|
47
|
+
agent-device react-devtools get component @c12
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Use `profile report` to identify render causes and changed keys. Use `get component` to inspect current props, state, and hooks.
|
|
51
|
+
|
|
52
|
+
Common interpretations:
|
|
53
|
+
|
|
54
|
+
| Signal | Meaning | Typical follow-up |
|
|
55
|
+
| ------------------------------------------ | ----------------------------------- | ---------------------------------------------- |
|
|
56
|
+
| `props-changed` with function props | Parent may pass unstable callbacks | Check whether the parent can use `useCallback` |
|
|
57
|
+
| `props-changed` with object or array props | Parent may pass unstable references | Check whether the parent can use `useMemo` |
|
|
58
|
+
| `parent-rendered` with many child renders | Child has no bailout | Check whether `React.memo` is appropriate |
|
|
59
|
+
| `state-changed` | Component state caused the render | Check whether the state update is necessary |
|
|
60
|
+
| `hooks-changed` | Hook value or dependency changed | Inspect hook values and dependencies |
|
|
61
|
+
|
|
62
|
+
## Verify
|
|
63
|
+
|
|
64
|
+
After making a change, repeat the same interaction:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
agent-device react-devtools profile start "after fix"
|
|
68
|
+
# Repeat the same interaction.
|
|
69
|
+
agent-device react-devtools profile stop
|
|
70
|
+
agent-device react-devtools profile slow --limit 5
|
|
71
|
+
agent-device react-devtools profile rerenders --limit 5
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Compare render counts, average durations, changed keys, and commit counts against the baseline.
|
package/dist/src/3883.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{runCmdSync as e}from"./9818.js";import{sleep as t}from"./4829.js";let r=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function n(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(e){return"EPERM"===e.code}}function i(t){if(!Number.isInteger(t)||t<=0)return null;try{let r=e("ps",["-p",String(t),"-o","lstart="],{allowFailure:!0,timeoutMs:1e3});if(0!==r.exitCode)return null;let n=r.stdout.trim();return n.length>0?n:null}catch{return null}}function o(t){if(!Number.isInteger(t)||t<=0)return null;try{let r=e("ps",["-p",String(t),"-o","command="],{allowFailure:!0,timeoutMs:1e3});if(0!==r.exitCode)return null;let n=r.stdout.trim();return n.length>0?n:null}catch{return null}}function l(e,t){let l;if(!n(e))return!1;if(t){let r=i(e);if(!r||r!==t)return!1}let s=o(e);return!!s&&!!(l=s.toLowerCase().replaceAll("\\","/")).includes("agent-device")&&r.some(e=>e.test(l))}function s(e,t){try{return process.kill(e,t),!0}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return!1;throw t}}async function u(e,r){if(!n(e))return!0;let i=Date.now();for(;Date.now()-i<r;)if(await t(50),!n(e))return!0;return!n(e)}async function c(e,t){!l(e,t.expectedStartTime)||!s(e,"SIGTERM")||await u(e,t.termTimeoutMs)||s(e,"SIGKILL")&&await u(e,t.killTimeoutMs)}export{l as isAgentDeviceDaemonProcess,n as isProcessAlive,o as readProcessCommand,i as readProcessStartTime,c as stopProcessForTakeover,u as waitForProcessExit};
|
package/dist/src/4993.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
let e=["android.shell","ios.runnerCommand","macos.desktopScreenshot"],n={"android.shell":"androidShell","ios.runnerCommand":"iosRunnerCommand","macos.desktopScreenshot":"macosDesktopScreenshot"};function o(e,n){return e.capabilities?.includes(n)??!1}function a(e,o){let a=n[o];return"function"==typeof e.escapeHatches?.[a]}export{n as BACKEND_CAPABILITY_ESCAPE_HATCH_METHODS,e as BACKEND_CAPABILITY_NAMES,o as hasBackendCapability,a as hasBackendEscapeHatch};
|
package/dist/src/8164.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{promises as t}from"node:fs";import o from"node:os";import e from"node:path";let r=["emulator","platform-tools",e.join("cmdline-tools","latest","bin"),e.join("cmdline-tools","tools","bin")];function n(t){let o=new Set,e=[];for(let r of t){let t=r.trim();!t||o.has(t)||(o.add(t),e.push(t))}return e}function i(t=process.env){let r=t.ANDROID_SDK_ROOT?.trim(),l=t.ANDROID_HOME?.trim(),s=t.HOME?.trim()||o.homedir();return n([r??"",l??"",s?e.join(s,"Android","Sdk"):""])}async function l(o){try{return await t.access(o,t.constants.X_OK),!0}catch{return!1}}async function s(t=process.env){let o,m=[];for(let n of i(t)){let t=[];for(let o of r){let r=e.join(n,o);await l(r)&&t.push(r)}0!==t.length&&(o||(o=n),m.push(...t))}if(o&&(t.ANDROID_SDK_ROOT=t.ANDROID_SDK_ROOT?.trim()||o,t.ANDROID_HOME=t.ANDROID_HOME?.trim()||o),0===m.length)return;let d=(t.PATH??"").split(e.delimiter).map(t=>t.trim()).filter(t=>t.length>0);t.PATH=n([...m,...d]).join(e.delimiter)}export{s as ensureAndroidSdkPathConfigured,i as resolveAndroidSdkRoots};
|
package/dist/src/9323.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{URL as t}from"node:url";import{whichCmd as e,runCmd as n}from"./9818.js";import{asAppError as a,AppError as r}from"./9152.js";import{ensureAndroidSdkPathConfigured as i}from"./8164.js";import"./4829.js";function o(t,e){return["-s",t.id,...e]}async function s(){if(await i(),!await e("adb"))throw new r("TOOL_MISSING","adb not found in PATH")}function l(t,e){let n=`${t}
|
|
2
|
-
${e}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}let u=/\.(?:apk|aab)$/i,d=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function c(t){var e,n;let a=t.trim();return 0===a.length?"other":u.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(e=a,!d.test(e))?"binary":"package":(n=a,d.test(n))?"package":"other"}function p(t){return`Android runtime hints require an installed package name, not "${t}". Install or reinstall the app first, then relaunch by package.`}let m=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],f=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function h(t){return t?.trim()||void 0}function w(t,e){for(let n of t){let t=h(e[n]);if(t)return t}}function _(t,e=process.env){return h(t)??w(m,e)}function A(t){return new Set(t.split(/[\s,]+/).map(t=>t.trim()).filter(Boolean))}function g(t,e=process.env){let n=h(t)??w(f,e);if(n)return A(n)}function b(t,e={}){let n=_(e.simulatorSetPath);return n?["simctl","--set",n,...t]:["simctl",...t]}function S(t,e){return"ios"!==t.platform||"simulator"!==t.kind?["simctl",...e]:b(e,{simulatorSetPath:t.simulatorSetPath})}let I="shared_prefs/ReactNativeDevPrefs.xml",v="debug_http_host",C="dev_server_https",$="RCT_jsLocation",E="RCT_packager_scheme",R="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",k='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function y(t){return void 0!==D(t)}function D(e){if(!e)return;let n=K(e.metroHost),a=q(e.metroPort),i="http",o=K(e.bundleUrl);if(o){var s;let e;try{e=new t(o)}catch(t){throw new r("INVALID_ARGS",`Invalid runtime bundle URL: ${o}`,{},t)}("http:"===e.protocol||"https:"===e.protocol)&&(n??=K(e.hostname),a??=q(e.port.length>0?Number(e.port):"https:"===(s=e.protocol)?443:"http:"===s?80:void 0),i="https:"===e.protocol?"https":"http")}if(n&&a)return{host:n,port:a,scheme:i}}async function N(t){let{device:e,appId:n,runtime:a}=t;if(!n)return;let r=D(a);if(r){if("android"===e.platform)return void await L(e,n,r);"ios"===e.platform&&"simulator"===e.kind&&await P(e,n,r)}}async function x(t){let{device:e,appId:n}=t;if(n){if("android"===e.platform)return void await T(e,n);"ios"===e.platform&&"simulator"===e.kind&&await F(e,n)}}async function L(t,e,n){var a,r,i,o,s,l;let u,d;G(e);let c=(a=await O(t,e),r=v,i=`${n.host}:${n.port}`,u=` <string name="${W(r)}">${W(i)}</string>`,V(U(a,r),u));o=c,s=C,l="https"===n.scheme,d=` <boolean name="${W(s)}" value="${l?"true":"false"}" />`,c=V(U(o,s),d),await M(t,e,c)}async function T(t,e){G(e);let n=await O(t,e),a=U(n,v),r=U(a,C);r!==n&&await M(t,e,r)}async function O(t,e){let a=await n("adb",o(t,["shell","run-as",e,"cat",I]),{allowFailure:!0});return 0!==a.exitCode?k:H(a.stdout)}async function M(t,e,i){let s=o(t,["shell","run-as",e,"id"]),l=await n("adb",s,{allowFailure:!0});if(0!==l.exitCode){let t=z(l.stdout,l.stderr);throw new r("COMMAND_FAILED",t?`Failed to access Android app sandbox for ${e}`:`Failed to probe Android app sandbox for ${e}`,{package:e,cmd:"adb",args:s,stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode,hint:t?R:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await n("adb",o(t,["shell","run-as",e,"mkdir","-p","shared_prefs"])),await n("adb",o(t,["shell","run-as",e,"tee",I]),{stdin:i.trimEnd()})}catch(i){let t=a(i);if("TOOL_MISSING"===t.code)throw t;let n=z("string"==typeof t.details?.stdout?t.details.stdout:"","string"==typeof t.details?.stderr?t.details.stderr:"");throw new r("COMMAND_FAILED",n?`Failed to access Android app sandbox for ${e}`:`Failed to write Android runtime hints for ${e}`,{...t.details??{},package:e,cmd:"adb",phase:"write-runtime-hints",hint:n?R:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},t)}}async function P(t,e,a){await n("xcrun",S(t,["spawn",t.id,"defaults","write",e,$,"-string",`${a.host}:${a.port}`])),await n("xcrun",S(t,["spawn",t.id,"defaults","write",e,E,"-string",a.scheme]))}async function F(t,e){await n("xcrun",S(t,["spawn",t.id,"defaults","delete",e,$]),{allowFailure:!0}),await n("xcrun",S(t,["spawn",t.id,"defaults","delete",e,E]),{allowFailure:!0})}function H(t){let e=t.trim();return e.includes("<map")&&e.includes("</map>")?`${e}
|
|
3
|
-
`:k}function V(t,e){return H(t).replace("</map>",`${e}
|
|
4
|
-
</map>`)}function U(t,e){let n=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return H(t).replace(RegExp(`^\\s*<string name="${n}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${n}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function K(t){let e=t?.trim();return e&&e.length>0?e:void 0}function G(t){if("binary"!==c(t))return;let e=p(t);throw new r("INVALID_ARGS",e,{package:t,hint:e})}function q(t){if(Number.isInteger(t)&&!(t<=0)&&!(t>65535))return t}function W(t){return t.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function z(t,e){let n=`${t}
|
|
5
|
-
${e}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(t=>n.includes(t))}export{o as adbArgs,N as applyRuntimeHintsToApp,b as buildSimctlArgs,S as buildSimctlArgsForDevice,c as classifyAndroidAppTarget,x as clearRuntimeHintsFromApp,s as ensureAdb,p as formatAndroidInstalledPackageRequiredMessage,y as hasRuntimeTransportHints,l as isClipboardShellUnsupported,A as parseSerialAllowlist,g as resolveAndroidSerialAllowlist,_ as resolveIosSimulatorDeviceSetPath,D as resolveRuntimeTransportHints,K as trimRuntimeValue};
|