agent-device 0.13.2 → 0.14.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 (65) hide show
  1. package/README.md +68 -63
  2. package/android-snapshot-helper/README.md +75 -0
  3. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.0.apk +0 -0
  4. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.0.apk.sha256 +1 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.0.manifest.json +17 -0
  6. package/bin/agent-device.mjs +6 -2
  7. package/dist/src/113.js +1 -1
  8. package/dist/src/1974.js +2 -2
  9. package/dist/src/221.js +4 -0
  10. package/dist/src/2301.js +1 -1
  11. package/dist/src/3918.js +29 -29
  12. package/dist/src/7847.js +1 -1
  13. package/dist/src/8161.js +3 -0
  14. package/dist/src/8656.js +1 -1
  15. package/dist/src/9152.js +1 -1
  16. package/dist/src/940.js +1 -0
  17. package/dist/src/9542.js +2 -2
  18. package/dist/src/9818.js +1 -1
  19. package/dist/src/989.js +1 -1
  20. package/dist/src/android-snapshot-helper.d.ts +181 -0
  21. package/dist/src/android-snapshot-helper.js +1 -0
  22. package/dist/src/index.d.ts +204 -1942
  23. package/dist/src/index.js +1 -1
  24. package/dist/src/internal/bin.js +440 -0
  25. package/dist/src/internal/companion-tunnel.js +1 -0
  26. package/dist/src/internal/daemon.js +45 -0
  27. package/dist/src/internal/update-check-entry.js +1 -0
  28. package/dist/src/metro.d.ts +5 -3
  29. package/dist/src/selectors.js +1 -1
  30. package/package.json +28 -24
  31. package/skills/agent-device/SKILL.md +20 -62
  32. package/skills/dogfood/SKILL.md +9 -168
  33. package/skills/react-devtools/SKILL.md +15 -31
  34. package/dist/src/4993.js +0 -1
  35. package/dist/src/5721.js +0 -1
  36. package/dist/src/7166.js +0 -1
  37. package/dist/src/8564.js +0 -3
  38. package/dist/src/9076.js +0 -1
  39. package/dist/src/backend.d.ts +0 -527
  40. package/dist/src/backend.js +0 -1
  41. package/dist/src/bin.js +0 -105
  42. package/dist/src/commands/index.d.ts +0 -1883
  43. package/dist/src/commands/index.js +0 -1
  44. package/dist/src/daemon.js +0 -43
  45. package/dist/src/metro-companion.js +0 -1
  46. package/dist/src/observability.d.ts +0 -91
  47. package/dist/src/observability.js +0 -1
  48. package/dist/src/testing/conformance.d.ts +0 -753
  49. package/dist/src/testing/conformance.js +0 -1
  50. package/dist/src/update-check-entry.js +0 -1
  51. package/skills/agent-device/references/bootstrap-install.md +0 -244
  52. package/skills/agent-device/references/coordinate-system.md +0 -28
  53. package/skills/agent-device/references/debugging.md +0 -138
  54. package/skills/agent-device/references/exploration.md +0 -362
  55. package/skills/agent-device/references/macos-desktop.md +0 -88
  56. package/skills/agent-device/references/remote-tenancy.md +0 -188
  57. package/skills/agent-device/references/verification.md +0 -134
  58. package/skills/dogfood/references/issue-taxonomy.md +0 -83
  59. package/skills/dogfood/templates/dogfood-report-template.md +0 -52
  60. package/skills/react-devtools/references/commands.md +0 -91
  61. package/skills/react-devtools/references/profiling.md +0 -74
  62. /package/dist/src/{bin.d.ts → internal/bin.d.ts} +0 -0
  63. /package/dist/src/{daemon.d.ts → internal/companion-tunnel.d.ts} +0 -0
  64. /package/dist/src/{metro-companion.d.ts → internal/daemon.d.ts} +0 -0
  65. /package/dist/src/{update-check-entry.d.ts → internal/update-check-entry.d.ts} +0 -0
@@ -4,7 +4,7 @@ export declare function buildBundleUrl(baseUrl: string, platform: 'ios' | 'andro
4
4
 
5
5
  export declare function buildIosRuntimeHints(baseUrl: string): MetroRuntimeHints;
6
6
 
7
- declare type CompanionTunnelScope = {
7
+ export declare type CompanionTunnelScope = {
8
8
  tenantId: string;
9
9
  runId: string;
10
10
  leaseId: string;
@@ -17,7 +17,7 @@ export declare type EnsureMetroTunnelOptions = {
17
17
  serverBaseUrl: string;
18
18
  bearerToken: string;
19
19
  localBaseUrl: string;
20
- bridgeScope: CompanionTunnelScope;
20
+ bridgeScope: MetroBridgeScope;
21
21
  launchUrl?: string;
22
22
  profileKey?: string;
23
23
  consumerKey?: string;
@@ -81,6 +81,8 @@ export declare type MetroBridgeRuntimePayload = {
81
81
  launch_url?: string;
82
82
  };
83
83
 
84
+ export declare type MetroBridgeScope = CompanionTunnelScope;
85
+
84
86
  /** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
85
87
  export declare type MetroRuntimeHints = SessionRuntimeHints;
86
88
 
@@ -162,7 +164,7 @@ export declare type PrepareRemoteMetroOptions = {
162
164
  publicBaseUrl?: string;
163
165
  proxyBaseUrl?: string;
164
166
  proxyBearerToken?: string;
165
- bridgeScope?: CompanionTunnelScope;
167
+ bridgeScope?: MetroBridgeScope;
166
168
  launchUrl?: string;
167
169
  profileKey?: string;
168
170
  consumerKey?: string;
@@ -1 +1 @@
1
- export{findSelectorChainMatch,formatSelectorFailure,isNodeEditable,isNodeVisible,isSelectorToken,parseSelectorChain,resolveSelectorChain,tryParseSelectorChain}from"./7847.js";
1
+ import"./7847.js";export{findSelectorChainMatch,formatSelectorFailure,isNodeEditable,isNodeVisible,isSelectorToken,parseSelectorChain,resolveSelectorChain,tryParseSelectorChain}from"./940.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
4
4
  "description": "Agent-driven CLI for mobile UI automation, network inspection, and performance diagnostics across iOS, Android, tvOS, and macOS.",
5
5
  "license": "MIT",
6
6
  "author": "Callstack",
@@ -13,6 +13,7 @@
13
13
  "url": "https://github.com/callstackincubator/agent-device/issues"
14
14
  },
15
15
  "type": "module",
16
+ "packageManager": "pnpm@10.33.2",
16
17
  "main": "dist/src/index.js",
17
18
  "types": "dist/src/index.d.ts",
18
19
  "exports": {
@@ -20,30 +21,14 @@
20
21
  "import": "./dist/src/index.js",
21
22
  "types": "./dist/src/index.d.ts"
22
23
  },
23
- "./commands": {
24
- "import": "./dist/src/commands/index.js",
25
- "types": "./dist/src/commands/index.d.ts"
26
- },
27
- "./backend": {
28
- "import": "./dist/src/backend.js",
29
- "types": "./dist/src/backend.d.ts"
30
- },
31
24
  "./io": {
32
25
  "import": "./dist/src/io.js",
33
26
  "types": "./dist/src/io.d.ts"
34
27
  },
35
- "./testing/conformance": {
36
- "import": "./dist/src/testing/conformance.js",
37
- "types": "./dist/src/testing/conformance.d.ts"
38
- },
39
28
  "./artifacts": {
40
29
  "import": "./dist/src/artifacts.js",
41
30
  "types": "./dist/src/artifacts.d.ts"
42
31
  },
43
- "./observability": {
44
- "import": "./dist/src/observability.js",
45
- "types": "./dist/src/observability.d.ts"
46
- },
47
32
  "./metro": {
48
33
  "import": "./dist/src/metro.js",
49
34
  "types": "./dist/src/metro.d.ts"
@@ -60,6 +45,10 @@
60
45
  "import": "./dist/src/android-apps.js",
61
46
  "types": "./dist/src/android-apps.d.ts"
62
47
  },
48
+ "./android-snapshot-helper": {
49
+ "import": "./dist/src/android-snapshot-helper.js",
50
+ "types": "./dist/src/android-snapshot-helper.d.ts"
51
+ },
63
52
  "./contracts": {
64
53
  "import": "./dist/src/contracts.js",
65
54
  "types": "./dist/src/contracts.d.ts"
@@ -74,7 +63,7 @@
74
63
  }
75
64
  },
76
65
  "engines": {
77
- "node": ">=22"
66
+ "node": ">=22.19"
78
67
  },
79
68
  "bin": {
80
69
  "agent-device": "bin/agent-device.mjs"
@@ -87,19 +76,31 @@
87
76
  "build:xcuitest:ios": "AGENT_DEVICE_XCUITEST_PLATFORM=ios AGENT_DEVICE_IOS_CLEAN_DERIVED=1 sh ./scripts/build-xcuitest-apple.sh",
88
77
  "build:xcuitest:macos": "AGENT_DEVICE_XCUITEST_PLATFORM=macos sh ./scripts/build-xcuitest-apple.sh",
89
78
  "build:xcuitest:tvos": "AGENT_DEVICE_XCUITEST_PLATFORM=tvos AGENT_DEVICE_IOS_CLEAN_DERIVED=1 sh ./scripts/build-xcuitest-apple.sh",
79
+ "build:android-snapshot-helper": "sh ./scripts/build-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
80
+ "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",
81
+ "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",
90
82
  "build:macos-helper": "swift build -c release --package-path macos-helper",
91
83
  "build:all": "pnpm build:node && pnpm build:xcuitest",
92
84
  "ad": "node bin/agent-device.mjs",
93
85
  "lint": "oxlint . --deny-warnings",
94
- "format": "oxfmt --write src test skills package.json tsconfig.json .oxlintrc.json .oxfmtrc.json",
86
+ "format": "oxfmt --write src test skills package.json tsconfig.json tsconfig.lib.json rslib.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
87
+ "fallow": "fallow --summary",
88
+ "fallow:baseline": "(fallow dead-code --save-baseline fallow-baselines/dead-code.json --summary || true) && (fallow dupes --save-baseline fallow-baselines/dupes.json --summary || true) && (fallow health --save-baseline fallow-baselines/health.json --summary || true)",
89
+ "check:fallow": "fallow audit",
95
90
  "check:quick": "pnpm lint && pnpm typecheck",
96
91
  "check:tooling": "pnpm lint && pnpm typecheck && pnpm build",
97
92
  "check:unit": "pnpm test:unit && pnpm test:smoke",
98
- "check": "pnpm check:tooling && pnpm check:unit",
99
- "prepack": "pnpm build:all",
93
+ "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit",
94
+ "prepack": "pnpm build:all && pnpm package:android-snapshot-helper:npm",
100
95
  "typecheck": "tsc -p tsconfig.json",
96
+ "test-app:install": "pnpm install --dir examples/test-app --ignore-workspace",
97
+ "test-app:start": "pnpm --dir examples/test-app start",
98
+ "test-app:ios": "pnpm --dir examples/test-app ios",
99
+ "test-app:android": "pnpm --dir examples/test-app android",
100
+ "test-app:typecheck": "pnpm --dir examples/test-app typecheck",
101
101
  "test": "vitest run",
102
102
  "test:unit": "vitest run",
103
+ "test:skillgym": "pnpm build && skillgym run ./test/skillgym/suites/agent-device-smoke-suite.ts --config ./test/skillgym/skillgym.config.ts",
103
104
  "test:smoke": "node --test test/integration/smoke-*.test.ts",
104
105
  "test:integration": "node --test test/integration/*.test.ts",
105
106
  "test:replay:ios": "node --experimental-strip-types src/bin.ts test test/integration/replays/ios/simulator",
@@ -118,6 +119,8 @@
118
119
  "!ios-runner/**/*.xcuserstate",
119
120
  "macos-helper",
120
121
  "!macos-helper/**/.build",
122
+ "android-snapshot-helper/dist",
123
+ "!android-snapshot-helper/dist/*.idsig",
121
124
  "src/platforms/linux/atspi-dump.py",
122
125
  "skills",
123
126
  "README.md",
@@ -152,14 +155,15 @@
152
155
  "pngjs": "^7.0.0"
153
156
  },
154
157
  "devDependencies": {
155
- "@microsoft/api-extractor": "^7.58.1",
158
+ "vitest": "^4.1.2",
156
159
  "@rslib/core": "0.20.1",
157
160
  "@types/node": "^22.0.0",
158
161
  "@types/pngjs": "^6.0.5",
162
+ "fallow": "^2.52.0",
159
163
  "oxfmt": "^0.42.0",
160
164
  "oxlint": "^1.57.0",
165
+ "skillgym": "^0.5.0",
161
166
  "typescript": "^6.0.2",
162
- "vite": "^8.0.7",
163
- "vitest": "^4.1.2"
167
+ "vite": "^8.0.7"
164
168
  }
165
169
  }
@@ -1,76 +1,34 @@
1
1
  ---
2
2
  name: agent-device
3
- description: Automates interactions for Apple-platform apps (iOS, tvOS, macOS) and Android devices. Use when navigating apps, taking snapshots/screenshots, tapping, typing, scrolling, extracting UI info, or collecting logs, network inspection, and perf snapshots across mobile, TV, and desktop targets.
3
+ description: Automates Apple-platform apps (iOS, tvOS, macOS) and Android devices. Use when navigating apps, taking snapshots/screenshots, tapping, typing, scrolling, extracting UI info, collecting logs/network/perf evidence, or planning agent-device CLI commands.
4
4
  ---
5
5
 
6
6
  # agent-device
7
7
 
8
- Use this skill as a router with mandatory defaults. Read this file first. For normal device tasks, always load `references/bootstrap-install.md` and `references/exploration.md` before acting. Use bootstrap to confirm or establish deterministic setup. Use exploration for UI inspection, interaction, and verification once the app session is open.
8
+ Router only. Private setup before using this skill:
9
9
 
10
- ## Default operating rules
10
+ ```bash
11
+ agent-device --version
12
+ ```
11
13
 
12
- - Start conservative. Prefer read-only inspection before mutating the UI.
13
- - Start deterministic. If the app name, package, device, or session is uncertain, load bootstrap and discover them before interacting.
14
- - Use plain `snapshot` when the task is to verify what text or structure is currently visible on screen.
15
- - Use `snapshot -i` only when you need interactive refs such as `@e3` for a requested action or targeted query. On iOS and Android, default snapshot output uses the same visible-first model: off-screen interactive content is exposed as discovery hints, not tappable refs.
16
- - Prefer `diff snapshot` after a nearby mutation when you only need to know what changed.
17
- - Avoid speculative mutations. You may take the smallest reversible UI action needed to unblock inspection or complete the requested task, such as dismissing a popup, closing an alert, or clearing an unintended surface.
18
- - In React Native dev or debug builds, check early for visible warning or error overlays, tooltips, and toasts that can steal focus or intercept taps. If they are not part of the requested behavior, dismiss them and continue. If you saw them, report them in the final summary.
19
- - In Metro-backed React Native dev loops, use `agent-device metro reload` for a JS app reload before falling back to `open <app> --relaunch`. It mirrors pressing `r` in the Metro terminal and preserves the native app process.
20
- - Do not browse the web or use external sources unless the user explicitly asks.
21
- - Re-snapshot after meaningful UI changes instead of reusing stale refs.
22
- - Treat refs in default snapshot output as actionable-now, not durable identities. If a target appears only in an off-screen summary, use `scroll <direction>` and re-snapshot until the target is visible.
23
- - Prefer `@ref` or selector targeting over raw coordinates.
24
- - Ensure the correct target is pinned and an app session is open before interacting.
25
- - Keep the loop short: `open` -> inspect/act -> verify if needed -> `close`.
14
+ Require `agent-device >= 0.13.4`; older CLIs lack these help topics. If older, run `npm install -g agent-device@latest`, recheck, then continue. If you cannot upgrade, stop and tell the user. Do not include version/upgrade commands in final plans.
26
15
 
27
- ## Default flow
16
+ Before your first agent-device command or plan, read the version-matched CLI guide:
28
17
 
29
- 1. Load [references/bootstrap-install.md](references/bootstrap-install.md) and [references/exploration.md](references/exploration.md) before acting on a normal device task.
30
- 2. Use bootstrap first to confirm or establish the correct target, app install, and open app session.
31
- 3. Once the app session is open and stable, use exploration for inspection, interaction, and verification.
32
- 4. Start with plain `snapshot` if the goal is to read or verify what is visible.
33
- 5. Escalate to `snapshot -i` only if you need refs for interactive exploration or a requested action.
34
- 6. Use `get`, `is`, or `find` before mutating the UI when a read-only command can answer the question.
35
- 7. End by capturing proof if needed, then `close`.
18
+ ```bash
19
+ agent-device help workflow
20
+ ```
36
21
 
37
- ## QA modes
22
+ Escalate only when relevant:
38
23
 
39
- - Open-ended bug hunt with reporting: use [../dogfood/SKILL.md](../dogfood/SKILL.md).
40
- - Pass/fail QA from acceptance criteria: stay in this skill, start with [references/bootstrap-install.md](references/bootstrap-install.md), then use the QA loop in [references/exploration.md](references/exploration.md).
24
+ ```bash
25
+ agent-device help debugging
26
+ agent-device help react-devtools
27
+ agent-device help remote
28
+ agent-device help macos
29
+ agent-device help dogfood
30
+ ```
41
31
 
42
- ## Required references
32
+ Default loop: `open -> snapshot/-i -> get/is/find or press/fill/scroll/wait -> verify -> close`.
43
33
 
44
- - For every normal device task, after reading this file, load [references/bootstrap-install.md](references/bootstrap-install.md) first, then [references/exploration.md](references/exploration.md), before acting.
45
- - Use bootstrap to confirm or establish deterministic setup, especially in sandbox or cloud environments.
46
- - Use exploration once the app session is open and stable.
47
- - Load additional references only when their scope is needed.
48
-
49
- ## Decision rules
50
-
51
- - Use plain `snapshot` when you need to verify whether text is visible.
52
- - Use `snapshot -i` mainly for interactive exploration and choosing refs.
53
- - Use `diff snapshot` for compact post-action verification; use `snapshot --diff` when that alias is easier to discover from snapshot help.
54
- - Use `get`, `is`, or `find` when they can answer the question without changing UI state.
55
- - Use `fill` to replace text.
56
- - Use `type` to append text.
57
- - Do not write `type @eN "text"`. Use `fill @eN "text"` to target a field directly, or `press @eN` then `type "text"` when the field already has focus and you want append semantics.
58
- - If the on-screen keyboard blocks the next step, prefer `keyboard dismiss` over navigation. On iOS, keep an app session open first; `keyboard status|get` remains Android-only.
59
- - When a task asks to "go back", use plain `back` for predictable app-owned navigation and reserve `back --system` for platform back gestures or button semantics.
60
- - Use `type --delay-ms` or `fill --delay-ms` for debounced search fields that drop characters when typed too quickly.
61
- - If there is no simulator, no app install, or no open app session yet, switch to `bootstrap-install.md` instead of improvising setup steps.
62
- - Use the smallest unblock action first when transient UI blocks inspection, but do not navigate, search, or enter new text just to make the UI reveal data unless the user asked for that interaction.
63
- - In React Native dev or debug apps, treat visible warning or error overlays as transient blockers unless the user is explicitly asking you to diagnose them. Dismiss them when safe, then continue the requested flow.
64
- - For React Native code changes where the app is already connected to Metro, prefer `agent-device metro reload`, then wait and re-snapshot. Use `open <app> --relaunch` only when Metro reload does not reconnect or native startup state must reset.
65
- - Do not use external lookups to compensate for missing on-screen data unless the user asked for them.
66
- - If the needed information is not exposed on screen, say that plainly instead of compensating with extra navigation, text entry, or web search.
67
- - Prefer `@ref` or selector targeting over raw coordinates.
68
-
69
- ## Additional references
70
-
71
- - Need logs, network, alerts, permissions, or failure triage: [references/debugging.md](references/debugging.md)
72
- - Need screenshots, diff, recording, replay maintenance, or perf data: [references/verification.md](references/verification.md)
73
- - Need desktop surfaces, menu bar behavior, or macOS-specific interaction rules: [references/macos-desktop.md](references/macos-desktop.md)
74
- - Need remote HTTP transport, `connect --remote-config`, or tenant leases on a remote macOS host: [references/remote-tenancy.md](references/remote-tenancy.md)
75
- This includes remote React Native runs where `agent-device` now prepares Metro locally and manages the local Metro companion tunnel automatically.
76
- - Need the React Native component tree, props, state, hooks, or render profiling: use `agent-device react-devtools ...` and the [react-devtools skill](../react-devtools/SKILL.md).
34
+ Keep refs current, prefer selectors/refs over coordinates, use `fill` to replace text, and use `back` for app-owned navigation. Let `help workflow` provide the exact command shapes.
@@ -1,184 +1,25 @@
1
1
  ---
2
2
  name: dogfood
3
- description: 'Systematically explore and test a mobile app on iOS/Android with agent-device to find bugs, UX issues, and other problems. Use when asked to "dogfood", "QA", "exploratory test", "find issues", "bug hunt", or "test this app" on mobile. Produces a structured report with reproducible evidence: screenshots, optional repro videos, and detailed steps for every issue.'
3
+ description: Systematically explore and test a mobile app on iOS/Android with agent-device to find bugs, UX issues, and other problems. Use when asked to dogfood, QA, exploratory test, find issues, bug hunt, or test this app on mobile.
4
4
  allowed-tools: Bash(agent-device:*), Bash(npx agent-device:*)
5
5
  ---
6
6
 
7
- # Dogfood (agent-device)
7
+ # Dogfood
8
8
 
9
- Systematically explore a mobile app, find issues, and produce a report with full reproduction evidence for every finding.
10
-
11
- ## Setup
12
-
13
- Only the **Target app** is required. Everything else has sensible defaults.
14
-
15
- | Parameter | Default | Example override |
16
- | -------------------- | ----------------------------------------------------------- | -------------------------------------------- |
17
- | **Target app** | _(required)_ | `Settings`, `com.example.app`, deep link URL |
18
- | **Platform** | Infer from user context; otherwise ask (`ios` or `android`) | `--platform ios` |
19
- | **Session name** | Slugified app/platform (for example `settings-ios`) | `--session my-session` |
20
- | **Output directory** | `./dogfood-output/` | `Output directory: /tmp/mobile-qa` |
21
- | **Scope** | Full app | `Focus on onboarding and profile` |
22
- | **Authentication** | None | `Sign in to user@example.com` |
23
-
24
- If the user gives enough context to start, begin immediately with defaults. Ask follow-up only when a required detail is missing (for example platform or credentials).
25
-
26
- Prefer direct `agent-device` binary when available.
27
-
28
- ## Workflow
29
-
30
- ```
31
- 1. Initialize Set up session, output dirs, report file
32
- 2. Launch/Auth Open app and sign in if needed
33
- 3. Orient Capture initial snapshot and map navigation
34
- 4. Explore Systematically test flows and states
35
- 5. Document Record reproducible evidence per issue
36
- 6. Wrap up Reconcile summary, close session
37
- ```
38
-
39
- ### 1. Initialize
40
-
41
- ```bash
42
- mkdir -p {OUTPUT_DIR}/screenshots {OUTPUT_DIR}/videos
43
- cp {SKILL_DIR}/templates/dogfood-report-template.md {OUTPUT_DIR}/report.md
44
- ```
45
-
46
- ### 2. Launch/Auth
47
-
48
- Start a named session and launch target app:
49
-
50
- ```bash
51
- agent-device --session {SESSION} open {TARGET_APP} --platform {PLATFORM}
52
- agent-device --session {SESSION} snapshot -i
53
- ```
54
-
55
- If login is required:
9
+ Router for exploratory QA. Private setup before using this skill:
56
10
 
57
11
  ```bash
58
- agent-device --session {SESSION} snapshot -i
59
- agent-device --session {SESSION} fill @e1 "{EMAIL}"
60
- agent-device --session {SESSION} fill @e2 "{PASSWORD}"
61
- agent-device --session {SESSION} press @e3
62
- agent-device --session {SESSION} wait 1000
63
- agent-device --session {SESSION} snapshot -i
12
+ agent-device --version
64
13
  ```
65
14
 
66
- For OTP/email codes: ask the user, wait for input, then continue.
67
-
68
- ### 3. Orient
15
+ Require `agent-device >= 0.13.4`; older CLIs lack these help topics. If older, run `npm install -g agent-device@latest`, recheck, then continue. If you cannot upgrade, stop and tell the user. Do not include version/upgrade commands in final plans.
69
16
 
70
- Capture initial evidence and navigation anchors:
17
+ Read current CLI guidance:
71
18
 
72
19
  ```bash
73
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/initial.png
74
- agent-device --session {SESSION} snapshot -i
20
+ agent-device help dogfood
75
21
  ```
76
22
 
77
- Map top-level navigation, tabs, and key workflows before deep testing.
78
-
79
- ### 4. Explore
80
-
81
- Read [references/issue-taxonomy.md](references/issue-taxonomy.md) for severity/category calibration.
82
-
83
- Strategy:
84
-
85
- - Move through each major app area (tabs, drawers, settings pages).
86
- - Test core journeys end-to-end (create, edit, delete, submit, recover).
87
- - Validate edge states (empty/error/loading/offline/permissions denied).
88
- - Use `diff snapshot -i` after UI transitions to avoid stale refs.
89
- - Periodically capture `logs path` and inspect the app log when behavior looks suspicious.
90
-
91
- Useful commands per screen:
92
-
93
- ```bash
94
- agent-device --session {SESSION} snapshot -i
95
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/{screen-name}.png
96
- agent-device --session {SESSION} appstate
97
- agent-device --session {SESSION} logs path
98
- ```
99
-
100
- ### 5. Document Issues (Repro-First)
101
-
102
- Explore and document in one pass. When you find an issue, stop and fully capture evidence before continuing.
103
-
104
- #### Interactive/behavioral issues
105
-
106
- Use video + step screenshots:
107
-
108
- 1. Start recording:
109
-
110
- ```bash
111
- agent-device --session {SESSION} record start {OUTPUT_DIR}/videos/issue-{NNN}-repro.mp4
112
- ```
113
-
114
- 2. Reproduce with visible pacing. Capture each step:
115
-
116
- ```bash
117
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/issue-{NNN}-step-1.png
118
- sleep 1
119
- # perform action
120
- sleep 1
121
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/issue-{NNN}-step-2.png
122
- ```
123
-
124
- 3. Capture final broken state:
125
-
126
- ```bash
127
- sleep 2
128
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/issue-{NNN}-result.png
129
- ```
130
-
131
- 4. Stop recording:
132
-
133
- ```bash
134
- agent-device --session {SESSION} record stop
135
- ```
136
-
137
- 5. Append issue immediately to report with numbered steps and screenshot references.
138
-
139
- #### Static/on-load issues
140
-
141
- Single screenshot is sufficient; no video required:
142
-
143
- ```bash
144
- agent-device --session {SESSION} screenshot {OUTPUT_DIR}/screenshots/issue-{NNN}.png
145
- ```
146
-
147
- Set **Repro Video** to `N/A` in the report.
148
-
149
- ### 6. Wrap Up
150
-
151
- Target 5-10 well-evidenced issues, then finish:
152
-
153
- 1. Reconcile summary severity counts in `report.md`.
154
- 2. Close session:
155
-
156
- ```bash
157
- agent-device --session {SESSION} close
158
- ```
159
-
160
- 3. Report total issues, severity breakdown, and highest-risk findings.
161
-
162
- ## Guidance
163
-
164
- - Repro quality matters more than issue count.
165
- - Use refs (`@eN`) for fast exploration, selectors for deterministic replay assertions when needed.
166
- - Re-snapshot after any mutation (navigation, modal, list update, form submit).
167
- - Use `fill` for clear-then-type semantics; use `type` for incremental typing behavior checks.
168
- - Keep logs optional and targeted: enable/read app logs only when useful for diagnosis.
169
- - If the issue appears rooted in React Native internals rather than device/app runtime behavior, use `agent-device react-devtools ...` and the `skills/react-devtools` workflow for component-tree or render-profiling inspection.
170
- - Never read source code of the app under test; findings must come from observed runtime behavior.
171
- - Write each issue immediately to avoid losing evidence.
172
- - Never delete screenshots/videos/report artifacts during a session.
173
-
174
- ## References
175
-
176
- | Reference | When to Read |
177
- | ------------------------------------------------------------ | ----------------------------------------------- |
178
- | [references/issue-taxonomy.md](references/issue-taxonomy.md) | Start of session; severity/categories/checklist |
179
-
180
- ## Templates
23
+ Loop: open named session -> snapshot -i + screenshot -> explore flows -> capture evidence per issue -> close.
181
24
 
182
- | Template | Purpose |
183
- | ---------------------------------------------------------------------------- | --------------------------------------------- |
184
- | [templates/dogfood-report-template.md](templates/dogfood-report-template.md) | Copy into output directory as the report file |
25
+ Target app is required; infer platform or ask. Default output is `./dogfood-output/`. Findings must come from runtime behavior, not source reads. Re-snapshot after mutations. Use logs, network, trace, perf, overlay screenshots, or react-devtools only when they add evidence.
@@ -1,55 +1,39 @@
1
1
  ---
2
2
  name: react-devtools
3
- description: Inspect and profile React Native component trees from agent-device. Use when debugging React Native props, state, hooks, render causes, slow components, excessive re-renders, or questions like why a component re-rendered.
3
+ description: Inspect and profile React Native component trees from agent-device. Use for React Native performance, profiling, props, state, hooks, render causes, slow components, excessive rerenders, or questions like why a component rerendered.
4
4
  ---
5
5
 
6
6
  # react-devtools
7
7
 
8
- Use this skill when the task needs React Native internals that are not visible in the accessibility tree: component hierarchy, props, state, hooks, render causes, or profiling data.
8
+ Router for React Native internals. Private setup before using this skill:
9
9
 
10
- Run commands through `agent-device react-devtools`. The command dynamically runs pinned `agent-react-devtools@0.4.0` and passes arguments through 1:1.
10
+ ```bash
11
+ agent-device --version
12
+ ```
11
13
 
12
- The first run may download the pinned package from npm. `agent-device` global flags work before or after `react-devtools`; use `--` before downstream flags only when they intentionally share an `agent-device` global flag name.
14
+ Require `agent-device >= 0.13.4`; older CLIs lack these help topics. If older, run `npm install -g agent-device@latest`, recheck, then continue. If you cannot upgrade, stop and tell the user. Do not include version/upgrade commands in final plans.
13
15
 
14
- ## Default flow
16
+ Read current CLI guidance:
15
17
 
16
- 1. Use `agent-device` to open the React Native app and verify the visible state when needed.
17
- 2. Check `agent-device react-devtools status`.
18
- 3. If no app is connected, start or wait for the devtools daemon, then reload or relaunch the app.
19
- 4. Inspect with `get tree`, `find`, and `get component`.
20
- 5. Profile only around the interaction being investigated.
21
- 6. Verify the fix with the same command sequence and interaction.
18
+ ```bash
19
+ agent-device help react-devtools
20
+ ```
22
21
 
23
- For cross-platform validation with explicit `--device`, `--udid`, or `--serial` selectors, prefer an isolated `--state-dir` over separate named sessions. Named sessions enable bound-session locks during setup. Restart `agent-device react-devtools` between iOS and Android runs so `status`, `get tree`, and profiling clearly refer to the currently launched app.
22
+ Use `agent-device react-devtools ...` for component tree, props, state, hooks, render ownership, performance profiling, slow components, or rerenders. It dynamically runs pinned `agent-react-devtools@0.4.0`. Use normal `agent-device` commands for visible UI, refs, screenshots, logs, network, or device-level perf.
24
23
 
25
- ## Main commands
24
+ Core loop:
26
25
 
27
26
  ```bash
28
27
  agent-device react-devtools status
29
28
  agent-device react-devtools wait --connected
30
29
  agent-device react-devtools get tree --depth 3
31
- agent-device react-devtools find <ComponentName>
32
- agent-device react-devtools get component @c5
33
30
  agent-device react-devtools profile start
31
+ # perform the interaction with normal agent-device commands
34
32
  agent-device react-devtools profile stop
35
33
  agent-device react-devtools profile slow --limit 5
36
34
  agent-device react-devtools profile rerenders --limit 5
37
35
  ```
38
36
 
39
- ## Decision rules
40
-
41
- - Need current UI text, refs, screenshots, logs, network, or device metrics: use the `agent-device` skill.
42
- - Need props, state, hooks, component ownership, render causes, or React profiler data: use this skill.
43
- - Start component-tree reads with `get tree --depth 3` or `find <name>` to keep output bounded.
44
- - Labels like `@c5` reset when the app reloads or components remount. After reload, run `wait --connected` and inspect again.
45
- - Profiling only captures renders between `profile start` and `profile stop`.
46
- - On Android, set `adb reverse tcp:8097 tcp:8097` for React DevTools. If Metro is local, also set `adb reverse tcp:8081 tcp:8081`.
47
- - For Android sessions connected through `agent-device connect --remote-config`, run `agent-device react-devtools ...` normally. The CLI registers a bridge companion tunnel to the local DevTools daemon on `127.0.0.1:8097` and unregisters it when the command exits.
48
- - Remote Android React DevTools assumes the React Native-bundled DevTools behavior in React Native 0.83+. Do not assume older browser/Chromium DevTools workflows exist in remote sandboxes. For Expo apps, verify the SDK's bundled React Native version and runtime behavior first; no Expo SDK version is separately verified by this skill.
49
-
50
- ## References
37
+ Rules:
51
38
 
52
- | File | When to read |
53
- | --------------------------------------- | --------------------------------------------- |
54
- | [commands.md](references/commands.md) | Command reference and common inspection flows |
55
- | [profiling.md](references/profiling.md) | Render profiling workflow and interpretation |
39
+ Keep reads bounded with `--depth`/`find`, treat `@c` refs as reload-local, profile only the investigated interaction, and run the same command in remote Android sessions; the CLI manages the needed local service tunnel.
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/5721.js DELETED
@@ -1 +0,0 @@
1
- import e from"node:fs";let t=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),r=/https?:\/\/[^\s"'<>\])]+/i,n=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i],i="<memory>";function s(e,t,r=e.limits.maxEntries){let n=[...e.entries],i=new Set(n.map(e=>o(e)));for(let e of t.entries){let t=o(e);if(!i.has(t)&&(i.add(t),n.push(e),n.length>=r))break}return{...e,matchedLines:n.length,entries:n}}function u(t,r){let n=y(r?.maxEntries,25,1,200),i=r?.include??"summary",s=y(r?.maxPayloadChars,2048,64,16384),u=y(r?.maxScanLines,4e3,100,2e4);return e.existsSync(t)?l(e.readFileSync(t,"utf8"),{...r,path:t}):{path:t,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:i,limits:{maxEntries:n,maxPayloadChars:s,maxScanLines:u}}}function l(e,n){let s=y(n?.maxEntries,25,1,200),u=n?.backend,l=n?.include??"summary",o=y(n?.maxPayloadChars,2048,64,16384),g=y(n?.maxScanLines,4e3,100,2e4),N=e.split("\n"),T=Math.max(0,N.length-g),E=N.slice(T),I=[];for(let e=E.length-1;e>=0&&I.length<s;e-=1){let n=E[e];if(!n?.trim())continue;let i=function(e,n,i,s,u,l){let o=e[n]?.trim();if(!o)return null;let y=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let n=e.slice(t,r+1);try{let e=JSON.parse(n);return e&&"object"==typeof e?e:null}catch{return null}}(o),g=p(y,["method","httpMethod"]),N=p(y,["url","requestUrl"]),T=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(y,["status","statusCode","responseCode"]),E=t.exec(o),I=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),M=(g??I?.[1]??E?.[1])?.toUpperCase(),$=r.exec(o),L=N??$?.[0];if(!L)return null;let O=T??d(o)??void 0;if(!(g||I?.[1]||E?.[1]||void 0!==O||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let S={method:M,url:L,status:O,timestamp:f(o),packetId:m(o)??void 0,durationMs:c(o)??void 0,raw:x(o,l),line:i};if("android"===s&&function(e,t,r){let n=a(t,r,5),i=e.packetId??n.map(e=>m(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let s=i?a(t,r,12).filter(e=>m(e)===i):n;e.timestamp||(e.timestamp=s.map(e=>f(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=s.map(e=>d(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=s.map(e=>c(e)).find(e=>"number"==typeof e))}(S,e,n),"headers"===u||"all"===u){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return b(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,y);e&&(S.headers=x(e,l))}if("body"===u||"all"===u){let e=h(o,y,["requestBody","body","payload","request"]),t=h(o,y,["responseBody","response"]);e&&(S.requestBody=x(e,l)),t&&(S.responseBody=x(t,l))}return S}(E,e,T+e+1,u,l,o);i&&I.push(i)}return{path:n?.path??i,exists:!0,scannedLines:E.length,matchedLines:I.length,entries:I,include:l,limits:{maxEntries:s,maxPayloadChars:o,maxScanLines:g}}}function o(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function a(e,t,r){let n=[],i=Math.max(0,t-r),s=Math.min(e.length-1,t+r);for(let t=i;t<=s;t+=1){let r=e[t]?.trim();r&&n.push(r)}return n}function d(e){for(let t of n){let r=t.exec(e);if(!r)continue;let n=Number.parseInt(r[1]??"",10);if(Number.isInteger(n))return n}return null}function f(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function m(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function c(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function p(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function h(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return b(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(n?.[1])return n[1].trim()}}function b(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function x(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function y(e,t,r,n){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(n,e)):t}export{i as NETWORK_LOG_MEMORY_PATH,s as mergeNetworkDumps,u as readRecentNetworkTraffic,l as readRecentNetworkTrafficFromText};
package/dist/src/7166.js DELETED
@@ -1 +0,0 @@
1
- let e=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,r=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function t(e){var t,s;let o=!1,i=e;return{value:(t=i=(i=(i=(i=(i=i.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,r)=>(o=!0,`${String(r)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,r,t,a)=>(o=!0,`${String(r)}[REDACTED]${String(a)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,r)=>(o=!0,`${String(r)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,r)=>(o=!0,`${String(r)}[REDACTED]`))).replaceAll(r,()=>(o=!0,"[REDACTED]")),s=()=>{o=!0},i=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let r=a(e);return r?(r.redacted&&s(),r.value):e}):t),redacted:o}}function a(r){try{let t=new URL(r),a=function(r){let t=!1;for(let a of Array.from(r.searchParams.keys()))e.test(a)&&(r.searchParams.set(a,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",a=!0),{value:t.toString(),redacted:a}}catch{return}}export{t as redactNetworkLogText,a as redactNetworkUrl};
package/dist/src/8564.js DELETED
@@ -1,3 +0,0 @@
1
- import e from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";import{AsyncLocalStorage as a}from"node:async_hooks";import i from"node:crypto";import r from"node:os";import{redactDiagnosticData as o,AppError as s}from"./9152.js";import{withSuccessText as l,bindCommands as d,successText as u}from"./9076.js";import{hasBackendEscapeHatch as c,hasBackendCapability as p}from"./4993.js";import{resolveUserPath as m,expandUserHomePath as f}from"./3267.js";function g(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??h(),policy:e.policy??v(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...d(t)}}function h(e=[]){let t=new Map(e.map(e=>[e.name,I(e)]));return{get:e=>I(t.get(e)),set:e=>{t.set(e.name,I(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>I(e))}}function I(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function S(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function v(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function w(e,t){if(!p(e.backend,t))throw new s("UNSUPPORTED_OPERATION",`Backend capability ${t} is not supported by this backend`,{capability:t});if(!e.policy.allowNamedBackendCapabilities.includes(t))throw new s("UNSUPPORTED_OPERATION",`Backend capability ${t} is not allowed by command policy`,{capability:t});if(!c(e.backend,t))throw new s("UNSUPPORTED_OPERATION",`Backend capability ${t} does not implement its escape hatch method`,{capability:t})}function b(){try{let n=y();return JSON.parse(e.readFileSync(t.join(n,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function y(){let a=t.dirname(n(import.meta.url)),i=a;for(let n=0;n<6;n+=1){let n=t.join(i,"package.json");if(e.existsSync(n))return i;i=t.dirname(i)}return a}let P=new a;function k(){return i.randomBytes(8).toString("hex")}async function _(e,t){let n={...e,diagnosticId:`${Date.now().toString(36)}-${i.randomBytes(4).toString("hex")}`,events:[]};return await P.run(n,t)}function N(){let e=P.getStore();return e?{diagnosticId:e.diagnosticId,requestId:e.requestId,session:e.session,command:e.command,debug:e.debug}:{}}function D(t){let n=P.getStore();if(!n)return;let a={ts:new Date().toISOString(),level:t.level??"info",phase:t.phase,session:n.session,requestId:n.requestId,command:n.command,durationMs:t.durationMs,data:t.data?o(t.data):void 0};if(n.events.push(a),!n.debug)return;let i=`[agent-device][diag] ${JSON.stringify(a)}
2
- `;try{n.logPath&&e.appendFile(n.logPath,i,()=>{}),n.traceLogPath&&e.appendFile(n.traceLogPath,i,()=>{}),n.logPath||n.traceLogPath||process.stderr.write(i)}catch{}}async function $(e,t,n){let a=Date.now();try{let i=await t();return D({level:"info",phase:e,durationMs:Date.now()-a,data:n}),i}catch(t){throw D({level:"error",phase:e,durationMs:Date.now()-a,data:{...n??{},error:t instanceof Error?t.message:String(t)}}),t}}function C(n={}){let a=P.getStore();if(!a||!n.force&&!a.debug||0===a.events.length)return null;try{let n=(a.session??"default").replace(/[^a-zA-Z0-9._-]/g,"_"),i=new Date().toISOString().slice(0,10),s=t.join(r.homedir(),".agent-device","logs",n,i);e.mkdirSync(s,{recursive:!0});let l=new Date().toISOString().replace(/[:.]/g,"-"),d=t.join(s,`${l}-${a.diagnosticId}.ndjson`),u=a.events.map(e=>JSON.stringify(o(e)));return e.writeFileSync(d,`${u.join("\n")}
3
- `),a.events=[],d}catch{return null}}function j(e){let n,a=(n=(e??"").trim())?m(n):t.join(f("~"),".agent-device");return{baseDir:a,infoPath:t.join(a,"daemon.json"),lockPath:t.join(a,"daemon.lock"),logPath:t.join(a,"daemon.log"),sessionsDir:t.join(a,"sessions")}}function R(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function A(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function O(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function x(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let z=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,B=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,E=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function M(){let e=process.argv[1];return e?T(e):"unknown"}function T(n,a=y()){try{let r=t.resolve(a),o=[t.resolve(n)],s=new Set,l=[];for(;o.length>0;){let n=o.pop();if(!n||s.has(n))continue;s.add(n);let a=e.statSync(n);if(!a.isFile())continue;let i=t.relative(r,n)||n;l.push(`${i}:${a.size}:${Math.trunc(a.mtimeMs)}`);let d=e.readFileSync(n,"utf8");for(let e of function(e){let t=new Set;return L(e,z,t),L(e,B,t),[...t]}(d)){let a=function(e,n){let a=t.resolve(t.dirname(e),n),i=F(a);if(i)return i;for(let e of E){let t=F(`${a}${e}`);if(t)return t}for(let e of E){let n=F(t.join(a,`index${e}`));if(n)return n}return null}(n,e);a&&o.push(a)}}let d=l.sort().join("|"),u=i.createHash("sha1").update(d).digest("hex");return`graph:${l.length}:${u}`}catch{return"unknown"}}function L(e,t,n){t.lastIndex=0;let a=null;for(;null!==(a=t.exec(e));){let e=a[1]?.trim();e?.startsWith(".")&&n.add(e)}}function F(t){try{return e.statSync(t).isFile()?t:null}catch{return null}}function U(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function K(e,t,n){return{deviceId:t,deviceName:n,..."android"===e?{serial:t}:"ios"===e?{udid:t}:{}}}function q(e,t={}){let n=t.includeAndroidSerial??!0;return{platform:e.platform,target:e.target,device:e.name,id:e.id,..."ios"===e.platform?{device_udid:e.ios?.udid??e.id,ios_simulator_device_set:e.ios?.simulatorSetPath??null}:{},..."android"===e.platform&&n?{serial:e.android?.serial??e.id}:{}}}function H(e){return{name:e.name,...q(e.device,{includeAndroidSerial:!1}),createdAt:e.createdAt}}function J(e){return{platform:e.platform,id:e.id,name:e.name,kind:e.kind,target:e.target,..."boolean"==typeof e.booted?{booted:e.booted}:{}}}function Z(e){let t=e.created?"Created":"Reused",n=e.booted?" (booted)":"";return l({udid:e.udid,device:e.device,runtime:e.runtime,ios_simulator_device_set:e.iosSimulatorDeviceSet??null,created:e.created,booted:e.booted},`${t}: ${e.device} ${e.udid}${n}`)}function V(e){return e.bundleId??e.package??e.app}function W(e){return l({app:e.app,appPath:e.appPath,platform:e.platform,...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.package?{package:e.package}:{}},`Installed: ${V(e)}`)}function G(e){return e.appName??e.bundleId??e.packageName??e.launchTarget}function Q(e){return l({launchTarget:e.launchTarget,...e.appName?{appName:e.appName}:{},...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.packageName?{package:e.packageName}:{},...e.installablePath?{installablePath:e.installablePath}:{},...e.archivePath?{archivePath:e.archivePath}:{},...e.materializationId?{materializationId:e.materializationId}:{},...e.materializationExpiresAt?{materializationExpiresAt:e.materializationExpiresAt}:{}},`Installed: ${G(e)}`)}function X(e){let t=e.appName??e.appBundleId??e.session;return l({session:e.session,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.startup?{startup:e.startup}:{},...e.runtime?{runtime:e.runtime}:{},...e.device?q(e.device):{}},t?`Opened: ${t}`:"Opened")}function Y(e){return{session:e.session,...e.shutdown?{shutdown:e.shutdown}:{},...u(e.session?`Closed: ${e.session}`:"Closed")}}function ee(e){return{nodes:e.nodes,truncated:e.truncated,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.visibility?{visibility:e.visibility}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}export{w as assertBackendCapabilityAllowed,U as buildAppIdentifiers,K as buildDeviceIdentifiers,T as computeDaemonCodeSignature,g as createAgentDevice,h as createMemorySessionStore,k as createRequestId,D as emitDiagnostic,y as findProjectRoot,C as flushDiagnosticsToSessionFile,N as getDiagnosticsMeta,S as localCommandPolicy,x as normalizeTenantId,b as readVersion,M as resolveDaemonCodeSignature,j as resolveDaemonPaths,R as resolveDaemonServerMode,A as resolveDaemonTransportPreference,V as resolveDeployResultTarget,G as resolveInstallFromSourceResultTarget,O as resolveSessionIsolationMode,v as restrictedCommandPolicy,Y as serializeCloseResult,W as serializeDeployResult,J as serializeDevice,Z as serializeEnsureSimulatorResult,Q as serializeInstallFromSourceResult,X as serializeOpenResult,H as serializeSessionListEntry,ee as serializeSnapshotResult,$ as withDiagnosticTimer,_ as withDiagnosticsScope};