wiretap-mcp 2.0.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 (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +68 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/monitors/crash-android.d.ts +20 -0
  8. package/dist/monitors/crash-android.d.ts.map +1 -0
  9. package/dist/monitors/crash-android.js +134 -0
  10. package/dist/monitors/crash-android.js.map +1 -0
  11. package/dist/monitors/crash-ios.d.ts +17 -0
  12. package/dist/monitors/crash-ios.d.ts.map +1 -0
  13. package/dist/monitors/crash-ios.js +116 -0
  14. package/dist/monitors/crash-ios.js.map +1 -0
  15. package/dist/monitors/hermes.d.ts +26 -0
  16. package/dist/monitors/hermes.d.ts.map +1 -0
  17. package/dist/monitors/hermes.js +175 -0
  18. package/dist/monitors/hermes.js.map +1 -0
  19. package/dist/monitors/reactotron.d.ts +18 -0
  20. package/dist/monitors/reactotron.d.ts.map +1 -0
  21. package/dist/monitors/reactotron.js +106 -0
  22. package/dist/monitors/reactotron.js.map +1 -0
  23. package/dist/monitors/terminal.d.ts +25 -0
  24. package/dist/monitors/terminal.d.ts.map +1 -0
  25. package/dist/monitors/terminal.js +154 -0
  26. package/dist/monitors/terminal.js.map +1 -0
  27. package/dist/parsers/cdp-parser.d.ts +64 -0
  28. package/dist/parsers/cdp-parser.d.ts.map +1 -0
  29. package/dist/parsers/cdp-parser.js +115 -0
  30. package/dist/parsers/cdp-parser.js.map +1 -0
  31. package/dist/parsers/crash-parser.d.ts +5 -0
  32. package/dist/parsers/crash-parser.d.ts.map +1 -0
  33. package/dist/parsers/crash-parser.js +112 -0
  34. package/dist/parsers/crash-parser.js.map +1 -0
  35. package/dist/parsers/log-parser.d.ts +5 -0
  36. package/dist/parsers/log-parser.d.ts.map +1 -0
  37. package/dist/parsers/log-parser.js +141 -0
  38. package/dist/parsers/log-parser.js.map +1 -0
  39. package/dist/parsers/reactotron-parser.d.ts +17 -0
  40. package/dist/parsers/reactotron-parser.d.ts.map +1 -0
  41. package/dist/parsers/reactotron-parser.js +83 -0
  42. package/dist/parsers/reactotron-parser.js.map +1 -0
  43. package/dist/server.d.ts +19 -0
  44. package/dist/server.d.ts.map +1 -0
  45. package/dist/server.js +224 -0
  46. package/dist/server.js.map +1 -0
  47. package/dist/storage/log-store.d.ts +41 -0
  48. package/dist/storage/log-store.d.ts.map +1 -0
  49. package/dist/storage/log-store.js +118 -0
  50. package/dist/storage/log-store.js.map +1 -0
  51. package/dist/storage/persistence.d.ts +26 -0
  52. package/dist/storage/persistence.d.ts.map +1 -0
  53. package/dist/storage/persistence.js +123 -0
  54. package/dist/storage/persistence.js.map +1 -0
  55. package/dist/tools/clear-logs.d.ts +8 -0
  56. package/dist/tools/clear-logs.d.ts.map +1 -0
  57. package/dist/tools/clear-logs.js +15 -0
  58. package/dist/tools/clear-logs.js.map +1 -0
  59. package/dist/tools/get-api-calls.d.ts +11 -0
  60. package/dist/tools/get-api-calls.d.ts.map +1 -0
  61. package/dist/tools/get-api-calls.js +26 -0
  62. package/dist/tools/get-api-calls.js.map +1 -0
  63. package/dist/tools/get-crashes.d.ts +11 -0
  64. package/dist/tools/get-crashes.d.ts.map +1 -0
  65. package/dist/tools/get-crashes.js +42 -0
  66. package/dist/tools/get-crashes.js.map +1 -0
  67. package/dist/tools/get-errors.d.ts +12 -0
  68. package/dist/tools/get-errors.d.ts.map +1 -0
  69. package/dist/tools/get-errors.js +52 -0
  70. package/dist/tools/get-errors.js.map +1 -0
  71. package/dist/tools/get-hermes-logs.d.ts +12 -0
  72. package/dist/tools/get-hermes-logs.d.ts.map +1 -0
  73. package/dist/tools/get-hermes-logs.js +33 -0
  74. package/dist/tools/get-hermes-logs.js.map +1 -0
  75. package/dist/tools/get-logs.d.ts +21 -0
  76. package/dist/tools/get-logs.d.ts.map +1 -0
  77. package/dist/tools/get-logs.js +50 -0
  78. package/dist/tools/get-logs.js.map +1 -0
  79. package/dist/tools/get-network.d.ts +12 -0
  80. package/dist/tools/get-network.d.ts.map +1 -0
  81. package/dist/tools/get-network.js +35 -0
  82. package/dist/tools/get-network.js.map +1 -0
  83. package/dist/tools/get-performance.d.ts +10 -0
  84. package/dist/tools/get-performance.d.ts.map +1 -0
  85. package/dist/tools/get-performance.js +32 -0
  86. package/dist/tools/get-performance.js.map +1 -0
  87. package/dist/tools/get-state.d.ts +11 -0
  88. package/dist/tools/get-state.d.ts.map +1 -0
  89. package/dist/tools/get-state.js +26 -0
  90. package/dist/tools/get-state.js.map +1 -0
  91. package/dist/tools/get-status.d.ts +20 -0
  92. package/dist/tools/get-status.d.ts.map +1 -0
  93. package/dist/tools/get-status.js +52 -0
  94. package/dist/tools/get-status.js.map +1 -0
  95. package/dist/tools/search-logs.d.ts +11 -0
  96. package/dist/tools/search-logs.d.ts.map +1 -0
  97. package/dist/tools/search-logs.js +68 -0
  98. package/dist/tools/search-logs.js.map +1 -0
  99. package/dist/types.d.ts +123 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +3 -0
  102. package/dist/types.js.map +1 -0
  103. package/package.json +65 -0
  104. package/scripts/install.sh +33 -0
  105. package/wiretap.config.json +8 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jaqueline Gonzaga
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ <p align="center">
2
+ <img src="assets/wiretap-logo.webp" alt="Wiretap" width="280" />
3
+ </p>
4
+
5
+ <h1 align="center">Wiretap</h1>
6
+
7
+ <p align="center">
8
+ <strong>Real-time visibility into your React Native app for Claude Code.</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/wiretap-mcp"><img src="https://img.shields.io/npm/v/wiretap-mcp?style=flat-square&color=cb3837" alt="npm version" /></a>
13
+ <a href="https://www.npmjs.com/package/wiretap-mcp"><img src="https://img.shields.io/npm/dm/wiretap-mcp?style=flat-square&color=blue" alt="npm downloads" /></a>
14
+ <a href="https://github.com/gonzagajaque/wiretap-mcp/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license" /></a>
15
+ <a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen?style=flat-square" alt="node version" /></a>
16
+ <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-compatible-8A2BE2?style=flat-square" alt="MCP compatible" /></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="#installation">Installation</a> &nbsp;&bull;&nbsp;
21
+ <a href="#how-it-works">How It Works</a> &nbsp;&bull;&nbsp;
22
+ <a href="#tools">Tools</a> &nbsp;&bull;&nbsp;
23
+ <a href="#usage">Usage</a> &nbsp;&bull;&nbsp;
24
+ <a href="#configuration">Configuration</a>
25
+ </p>
26
+
27
+ ---
28
+
29
+ ## The Problem
30
+
31
+ When debugging React Native with Claude Code, you constantly copy-paste logs, describe errors manually, and lose context switching between terminal, Reactotron, and your editor. Claude is powerful, but blind to what your app is actually doing.
32
+
33
+ ## The Solution
34
+
35
+ Wiretap is an MCP server that taps directly into every signal your app emits. Terminal logs, JS runtime output, network traffic, state changes, native crashes. Claude Code sees it all in real time, and you interact with it through natural language.
36
+
37
+ No copy-paste. No context switching. Just ask.
38
+
39
+ ## Features
40
+
41
+ **Zero copy-paste.** Claude reads your Metro and Expo logs directly.
42
+
43
+ **JS runtime logs.** `console.log`, `console.warn`, and `console.error` captured from Hermes via Chrome DevTools Protocol.
44
+
45
+ **Network inspector.** HTTP requests captured via CDP with no proxy or in-app setup needed.
46
+
47
+ **Reactotron integration.** API calls, Redux and Zustand state, and benchmarks flow into Claude's context automatically.
48
+
49
+ **Native crash reports.** iOS crash reports and Android crashes captured with full stack traces.
50
+
51
+ **Persistent logs.** Optionally persist logs to disk so they survive server restarts.
52
+
53
+ **Always watching.** Auto-detects Metro and Expo processes, reconnects to Reactotron and Hermes on its own.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ claude mcp add wiretap -- npx wiretap-mcp
59
+ ```
60
+
61
+ After restarting Claude Code, ask:
62
+
63
+ > "What's the app status?"
64
+
65
+ You should see connection info for all active monitors.
66
+
67
+ ## How It Works
68
+
69
+ ```
70
+ ┌─────────────────────────────────────────────────────────┐
71
+ │ Your RN App │
72
+ │ │
73
+ │ Metro/Expo Hermes Runtime Reactotron Native │
74
+ │ │ │ │ │ │
75
+ └───────┼──────────────┼───────────────┼────────────┼─────┘
76
+ │ │ │ │
77
+ ▼ ▼ ▼ ▼
78
+ ┌─────────────────────────────────────────────────────────┐
79
+ │ │
80
+ │ ⚡ Wiretap MCP │
81
+ │ │
82
+ │ Terminal Hermes/CDP Reactotron Crash │
83
+ │ Monitor Monitor Monitor Monitor │
84
+ │ │
85
+ └────────────────────────┬────────────────────────────────┘
86
+
87
+
88
+ ┌──────────────┐
89
+ │ Claude Code │
90
+ │ │
91
+ │ "What went │
92
+ │ wrong?" │
93
+ └──────────────┘
94
+ ```
95
+
96
+ ## Tools
97
+
98
+ | Tool | Description |
99
+ |------|-------------|
100
+ | `get_terminal_logs` | Metro/Expo terminal output with severity filtering |
101
+ | `get_hermes_logs` | JS runtime logs (`console.log/warn/error`) from Hermes via CDP |
102
+ | `get_network_calls` | HTTP network calls via CDP, filterable by URL and status code |
103
+ | `get_reactotron_logs` | Reactotron logs filtered by type (api, state, log, benchmark) |
104
+ | `get_errors` | Consolidated errors from terminal, Reactotron, and Hermes |
105
+ | `get_api_calls` | HTTP requests from Reactotron, filterable by endpoint |
106
+ | `get_state_changes` | Redux/MobX/Zustand dispatches with before/after diffs |
107
+ | `get_native_crashes` | Native crash reports from iOS and Android |
108
+ | `get_app_status` | Dashboard with all monitor statuses, error counts, and uptime |
109
+ | `get_performance` | Benchmark and render time metrics from Reactotron |
110
+ | `search_logs` | Regex search across all log sources |
111
+ | `clear_logs` | Reset all buffers |
112
+
113
+ ## Usage
114
+
115
+ Once installed, just talk to Claude naturally:
116
+
117
+ ```
118
+ "What errors happened in the last few minutes?"
119
+ "Show me the failing API calls"
120
+ "What's the JS console output?"
121
+ "Show me the network requests to /api/auth"
122
+ "Did the app crash natively?"
123
+ "What state changes happened after the login action?"
124
+ "Search the logs for 'timeout'"
125
+ ```
126
+
127
+ ## Configuration
128
+
129
+ Create a `wiretap.config.json` in your project root. All fields are optional. Defaults work out of the box.
130
+
131
+ ```json
132
+ {
133
+ "reactotronPort": 9090,
134
+ "metroPort": 8081,
135
+ "autoDetectTerminal": true
136
+ }
137
+ ```
138
+
139
+ ### All Options
140
+
141
+ | Option | Default | Description |
142
+ |--------|---------|-------------|
143
+ | `reactotronPort` | `9090` | WebSocket port for Reactotron |
144
+ | `terminalLogBufferSize` | `500` | Max terminal log entries in memory |
145
+ | `reactotronLogBufferSize` | `500` | Max Reactotron entries in memory |
146
+ | `autoDetectTerminal` | `true` | Auto-detect Metro/Expo processes |
147
+ | `filterPatterns` | `[]` | Regex patterns to exclude from logs |
148
+ | `hermesEnabled` | `true` | Capture JS runtime logs via Hermes/CDP |
149
+ | `metroPort` | `8081` | Metro bundler port for CDP discovery |
150
+ | `cdpCaptureNetwork` | `true` | Capture HTTP network calls via CDP |
151
+ | `persistLogs` | `false` | Persist logs to disk (JSONL) |
152
+ | `persistPath` | `~/.wiretap` | Directory for persisted logs |
153
+ | `persistFlushIntervalMs` | `5000` | Flush interval in ms |
154
+ | `persistMaxEntriesOnLoad` | `200` | Max entries to reload on startup |
155
+ | `iosCrashMonitorEnabled` | `true` | Watch iOS crash reports (macOS only) |
156
+ | `iosCrashReportPath` | `~/Library/Logs/DiagnosticReports` | iOS crash report directory |
157
+ | `androidCrashMonitorEnabled` | `true` | Monitor Android crashes via adb |
158
+ | `adbPath` | `adb` | Path to adb binary |
159
+
160
+ ## Requirements
161
+
162
+ - Node.js >= 18
163
+ - Claude Code
164
+ - React Native project with Metro or Expo
165
+ - Reactotron (optional)
166
+ - adb (optional, for Android crash monitoring)
167
+
168
+ ## Contributing
169
+
170
+ Contributions are welcome. Please open an issue first to discuss what you would like to change.
171
+
172
+ ## License
173
+
174
+ [MIT](LICENSE)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
5
+ const server_js_1 = require("./server.js");
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ function loadConfig() {
9
+ const defaults = {
10
+ reactotronPort: 9090,
11
+ terminalLogBufferSize: 500,
12
+ reactotronLogBufferSize: 500,
13
+ autoDetectTerminal: true,
14
+ watchPaths: [],
15
+ filterPatterns: [],
16
+ // Persistence
17
+ persistLogs: false,
18
+ persistPath: "~/.wiretap",
19
+ persistFlushIntervalMs: 5000,
20
+ persistMaxEntriesOnLoad: 200,
21
+ // Hermes/CDP
22
+ hermesEnabled: true,
23
+ metroPort: 8081,
24
+ cdpCaptureNetwork: true,
25
+ // iOS crash monitor
26
+ iosCrashMonitorEnabled: true,
27
+ iosCrashReportPath: "~/Library/Logs/DiagnosticReports",
28
+ // Android crash monitor
29
+ androidCrashMonitorEnabled: true,
30
+ adbPath: "adb",
31
+ };
32
+ // Try wiretap.config.json first, fallback to legacy rn-companion.config.json
33
+ for (const filename of ["wiretap.config.json", "rn-companion.config.json"]) {
34
+ try {
35
+ const configPath = (0, path_1.resolve)(process.cwd(), filename);
36
+ const raw = (0, fs_1.readFileSync)(configPath, "utf-8");
37
+ const userConfig = JSON.parse(raw);
38
+ return { ...defaults, ...userConfig };
39
+ }
40
+ catch {
41
+ // Config file not found, try next
42
+ }
43
+ }
44
+ return defaults;
45
+ }
46
+ async function main() {
47
+ const config = loadConfig();
48
+ const { server, shutdown } = (0, server_js_1.createCompanionServer)(config);
49
+ const transport = new stdio_js_1.StdioServerTransport();
50
+ await server.connect(transport);
51
+ const handleShutdown = () => {
52
+ process.stderr.write("[wiretap] Shutting down...\n");
53
+ shutdown();
54
+ process.exit(0);
55
+ };
56
+ process.on("SIGINT", handleShutdown);
57
+ process.on("SIGTERM", handleShutdown);
58
+ process.stderr.write("[wiretap] MCP server started\n");
59
+ process.stderr.write(`[wiretap] Reactotron port: ${config.reactotronPort}\n`);
60
+ process.stderr.write(`[wiretap] Auto-detect terminal: ${config.autoDetectTerminal}\n`);
61
+ process.stderr.write(`[wiretap] Hermes/CDP: ${config.hermesEnabled ? "enabled" : "disabled"}\n`);
62
+ process.stderr.write(`[wiretap] Persistence: ${config.persistLogs ? "enabled" : "disabled"}\n`);
63
+ }
64
+ main().catch((err) => {
65
+ process.stderr.write(`[wiretap] Fatal error: ${err}\n`);
66
+ process.exit(1);
67
+ });
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,wEAAiF;AACjF,2CAAoD;AAEpD,2BAAkC;AAClC,+BAA+B;AAE/B,SAAS,UAAU;IACjB,MAAM,QAAQ,GAAoB;QAChC,cAAc,EAAE,IAAI;QACpB,qBAAqB,EAAE,GAAG;QAC1B,uBAAuB,EAAE,GAAG;QAC5B,kBAAkB,EAAE,IAAI;QACxB,UAAU,EAAE,EAAE;QACd,cAAc,EAAE,EAAE;QAClB,cAAc;QACd,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,YAAY;QACzB,sBAAsB,EAAE,IAAI;QAC5B,uBAAuB,EAAE,GAAG;QAC5B,aAAa;QACb,aAAa,EAAE,IAAI;QACnB,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,IAAI;QACvB,oBAAoB;QACpB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,kCAAkC;QACtD,wBAAwB;QACxB,0BAA0B,EAAE,IAAI;QAChC,OAAO,EAAE,KAAK;KACf,CAAC;IAEF,6EAA6E;IAC7E,KAAK,MAAM,QAAQ,IAAI,CAAC,qBAAqB,EAAE,0BAA0B,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC;YAC/D,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,EAAE,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,iCAAqB,EAAC,MAAM,CAAC,CAAC;IAE3D,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACrD,QAAQ,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAEtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8BAA8B,MAAM,CAAC,cAAc,IAAI,CACxD,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mCAAmC,MAAM,CAAC,kBAAkB,IAAI,CACjE,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yBAAyB,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,IAAI,CAC3E,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,IAAI,CAC1E,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { EventEmitter } from "events";
2
+ import { LogStore } from "../storage/log-store.js";
3
+ export declare class AndroidCrashMonitor extends EventEmitter {
4
+ private store;
5
+ private adbPath;
6
+ private logcatProcess;
7
+ private _active;
8
+ private fatalBuffer;
9
+ private collectingFatal;
10
+ constructor(store: LogStore, adbPath?: string);
11
+ get isActive(): boolean;
12
+ start(): void;
13
+ stop(): void;
14
+ private isAdbAvailable;
15
+ private processLine;
16
+ private flushFatalBuffer;
17
+ /** Extract the message portion from a logcat line, stripping timestamp/pid/tag prefix */
18
+ private extractMessage;
19
+ }
20
+ //# sourceMappingURL=crash-android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-android.d.ts","sourceRoot":"","sources":["../../src/monitors/crash-android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMnD,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,eAAe,CAAS;gBAEpB,KAAK,EAAE,QAAQ,EAAE,OAAO,SAAQ;IAM5C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,KAAK,IAAI,IAAI;IAyCb,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,gBAAgB;IAiBxB,yFAAyF;IACzF,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AndroidCrashMonitor = void 0;
4
+ const events_1 = require("events");
5
+ const child_process_1 = require("child_process");
6
+ const crash_parser_js_1 = require("../parsers/crash-parser.js");
7
+ class AndroidCrashMonitor extends events_1.EventEmitter {
8
+ store;
9
+ adbPath;
10
+ logcatProcess = null;
11
+ _active = false;
12
+ fatalBuffer = [];
13
+ collectingFatal = false;
14
+ constructor(store, adbPath = "adb") {
15
+ super();
16
+ this.store = store;
17
+ this.adbPath = adbPath;
18
+ }
19
+ get isActive() {
20
+ return this._active;
21
+ }
22
+ start() {
23
+ if (!this.isAdbAvailable()) {
24
+ return;
25
+ }
26
+ try {
27
+ // Use logcat with error-level filter
28
+ this.logcatProcess = (0, child_process_1.spawn)(this.adbPath, [
29
+ "logcat",
30
+ "*:E",
31
+ "-v",
32
+ "threadtime",
33
+ ]);
34
+ this.logcatProcess.stdout?.on("data", (data) => {
35
+ const lines = data.toString().split("\n").filter(Boolean);
36
+ for (const line of lines) {
37
+ this.processLine(line);
38
+ }
39
+ });
40
+ this.logcatProcess.stderr?.on("data", () => {
41
+ // adb errors — ignore
42
+ });
43
+ this.logcatProcess.on("error", () => {
44
+ this._active = false;
45
+ });
46
+ this.logcatProcess.on("exit", () => {
47
+ this._active = false;
48
+ this.logcatProcess = null;
49
+ });
50
+ this._active = true;
51
+ this.emit("started");
52
+ }
53
+ catch {
54
+ this._active = false;
55
+ }
56
+ }
57
+ stop() {
58
+ if (this.logcatProcess) {
59
+ this.logcatProcess.kill();
60
+ this.logcatProcess = null;
61
+ }
62
+ this._active = false;
63
+ this.flushFatalBuffer();
64
+ }
65
+ isAdbAvailable() {
66
+ try {
67
+ (0, child_process_1.execSync)(`${this.adbPath} devices`, {
68
+ encoding: "utf-8",
69
+ timeout: 5000,
70
+ stdio: "pipe",
71
+ });
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ processLine(line) {
79
+ // Detect FATAL EXCEPTION from AndroidRuntime
80
+ if (/AndroidRuntime.*FATAL EXCEPTION/.test(line) || /FATAL EXCEPTION:/.test(line)) {
81
+ // Flush any previous fatal buffer
82
+ this.flushFatalBuffer();
83
+ this.collectingFatal = true;
84
+ this.fatalBuffer = [this.extractMessage(line)];
85
+ return;
86
+ }
87
+ // Continue collecting fatal exception lines
88
+ if (this.collectingFatal) {
89
+ const msg = this.extractMessage(line);
90
+ // Fatal exception block ends when we see a non-continuation line
91
+ if (msg.startsWith("\t") ||
92
+ msg.startsWith(" ") ||
93
+ /^\s*(at |Caused by|\.\.\.)\s/.test(msg) ||
94
+ /^\s*[\w.]+(?:Exception|Error)/.test(msg)) {
95
+ this.fatalBuffer.push(msg);
96
+ return;
97
+ }
98
+ else {
99
+ this.flushFatalBuffer();
100
+ // Continue processing this line below
101
+ }
102
+ }
103
+ // Detect native signals (SIGSEGV, SIGABRT, etc.)
104
+ if (/Fatal signal|libc\s*:\s*Fatal signal/.test(line)) {
105
+ const parsed = (0, crash_parser_js_1.parseAndroidNativeSignal)(this.extractMessage(line));
106
+ if (parsed) {
107
+ const entry = this.store.crashLogs.add(parsed);
108
+ this.emit("crash", entry);
109
+ }
110
+ }
111
+ }
112
+ flushFatalBuffer() {
113
+ if (!this.collectingFatal || this.fatalBuffer.length === 0) {
114
+ this.collectingFatal = false;
115
+ this.fatalBuffer = [];
116
+ return;
117
+ }
118
+ const parsed = (0, crash_parser_js_1.parseAndroidFatalException)(this.fatalBuffer);
119
+ if (parsed) {
120
+ const entry = this.store.crashLogs.add(parsed);
121
+ this.emit("crash", entry);
122
+ }
123
+ this.collectingFatal = false;
124
+ this.fatalBuffer = [];
125
+ }
126
+ /** Extract the message portion from a logcat line, stripping timestamp/pid/tag prefix */
127
+ extractMessage(line) {
128
+ // Logcat threadtime format: MM-DD HH:MM:SS.mmm PID TID level tag: message
129
+ const match = line.match(/^\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3}\s+\d+\s+\d+\s+\w\s+[\w./-]+\s*:\s*(.*)/);
130
+ return match?.[1] ?? line;
131
+ }
132
+ }
133
+ exports.AndroidCrashMonitor = AndroidCrashMonitor;
134
+ //# sourceMappingURL=crash-android.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-android.js","sourceRoot":"","sources":["../../src/monitors/crash-android.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { EventEmitter } from "events";
2
+ import { LogStore } from "../storage/log-store.js";
3
+ export declare class IOSCrashMonitor extends EventEmitter {
4
+ private store;
5
+ private watchPath;
6
+ private watcher;
7
+ private _active;
8
+ private processedFiles;
9
+ constructor(store: LogStore, crashReportPath: string);
10
+ get isActive(): boolean;
11
+ start(): void;
12
+ stop(): void;
13
+ private isCrashFile;
14
+ private scanExisting;
15
+ private processCrashFile;
16
+ }
17
+ //# sourceMappingURL=crash-ios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-ios.d.ts","sourceRoot":"","sources":["../../src/monitors/crash-ios.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAqB;gBAE/B,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM;IAcpD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,KAAK,IAAI,IAAI;IAkCb,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IOSCrashMonitor = void 0;
4
+ const events_1 = require("events");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const crash_parser_js_1 = require("../parsers/crash-parser.js");
8
+ class IOSCrashMonitor extends events_1.EventEmitter {
9
+ store;
10
+ watchPath;
11
+ watcher = null;
12
+ _active = false;
13
+ processedFiles = new Set();
14
+ constructor(store, crashReportPath) {
15
+ super();
16
+ this.store = store;
17
+ // Resolve ~ to home dir
18
+ if (crashReportPath.startsWith("~")) {
19
+ this.watchPath = (0, path_1.join)(process.env.HOME || "/tmp", crashReportPath.slice(1));
20
+ }
21
+ else {
22
+ this.watchPath = crashReportPath;
23
+ }
24
+ }
25
+ get isActive() {
26
+ return this._active;
27
+ }
28
+ start() {
29
+ // Only run on macOS
30
+ if (process.platform !== "darwin") {
31
+ return;
32
+ }
33
+ try {
34
+ // Scan recent crash files on startup
35
+ this.scanExisting();
36
+ // Watch for new crash files
37
+ this.watcher = (0, fs_1.watch)(this.watchPath, (eventType, filename) => {
38
+ if (!filename)
39
+ return;
40
+ if (eventType === "rename" && this.isCrashFile(filename)) {
41
+ // Small delay to let the OS finish writing
42
+ setTimeout(() => {
43
+ this.processCrashFile((0, path_1.join)(this.watchPath, filename));
44
+ }, 500);
45
+ }
46
+ });
47
+ this.watcher.on("error", () => {
48
+ // Directory might not exist or permission denied
49
+ this._active = false;
50
+ });
51
+ this._active = true;
52
+ this.emit("started");
53
+ }
54
+ catch {
55
+ // Watch failed — directory might not exist
56
+ this._active = false;
57
+ }
58
+ }
59
+ stop() {
60
+ if (this.watcher) {
61
+ this.watcher.close();
62
+ this.watcher = null;
63
+ }
64
+ this._active = false;
65
+ }
66
+ isCrashFile(filename) {
67
+ return filename.endsWith(".crash") || filename.endsWith(".ips");
68
+ }
69
+ scanExisting() {
70
+ try {
71
+ const files = (0, fs_1.readdirSync)(this.watchPath)
72
+ .filter((f) => this.isCrashFile(f))
73
+ .map((f) => {
74
+ const fullPath = (0, path_1.join)(this.watchPath, f);
75
+ try {
76
+ const stat = (0, fs_1.statSync)(fullPath);
77
+ return { path: fullPath, mtime: stat.mtimeMs };
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ })
83
+ .filter((f) => f !== null)
84
+ .sort((a, b) => b.mtime - a.mtime);
85
+ // Only process crashes from last 24 hours, max 10
86
+ const cutoff = Date.now() - 24 * 60 * 60 * 1000;
87
+ const recent = files
88
+ .filter((f) => f.mtime > cutoff)
89
+ .slice(0, 10);
90
+ for (const file of recent) {
91
+ this.processCrashFile(file.path);
92
+ }
93
+ }
94
+ catch {
95
+ // Can't read directory
96
+ }
97
+ }
98
+ processCrashFile(filePath) {
99
+ if (this.processedFiles.has(filePath))
100
+ return;
101
+ this.processedFiles.add(filePath);
102
+ try {
103
+ const content = (0, fs_1.readFileSync)(filePath, "utf-8");
104
+ const parsed = (0, crash_parser_js_1.parseIOSCrashReport)(content, filePath);
105
+ if (parsed) {
106
+ const entry = this.store.crashLogs.add(parsed);
107
+ this.emit("crash", entry);
108
+ }
109
+ }
110
+ catch {
111
+ // Can't read file
112
+ }
113
+ }
114
+ }
115
+ exports.IOSCrashMonitor = IOSCrashMonitor;
116
+ //# sourceMappingURL=crash-ios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-ios.js","sourceRoot":"","sources":["../../src/monitors/crash-ios.ts"],"names":[],"mappings":";;;AAAA,mCAAsC;AACtC,2BAA2E;AAC3E,+BAA4B;AAE5B,gEAAiE;AAEjE,MAAa,eAAgB,SAAQ,qBAAY;IACvC,KAAK,CAAW;IAChB,SAAS,CAAS;IAClB,OAAO,GAAqB,IAAI,CAAC;IACjC,OAAO,GAAG,KAAK,CAAC;IAChB,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,YAAY,KAAe,EAAE,eAAuB;QAClD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,wBAAwB;QACxB,IAAI,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,SAAS,GAAG,IAAA,WAAI,EACnB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAC1B,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CACzB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC;QACnC,CAAC;IACH,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,KAAK;QACH,oBAAoB;QACpB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,qCAAqC;YACrC,IAAI,CAAC,YAAY,EAAE,CAAC;YAEpB,4BAA4B;YAC5B,IAAI,CAAC,OAAO,GAAG,IAAA,UAAK,EAAC,IAAI,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;gBAC3D,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBACtB,IAAI,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzD,2CAA2C;oBAC3C,UAAU,CAAC,GAAG,EAAE;wBACd,IAAI,CAAC,gBAAgB,CAAC,IAAA,WAAI,EAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;oBACxD,CAAC,EAAE,GAAG,CAAC,CAAC;gBACV,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC5B,iDAAiD;gBACjD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;YAC3C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAEO,WAAW,CAAC,QAAgB;QAClC,OAAO,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClE,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAA,gBAAW,EAAC,IAAI,CAAC,SAAS,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;iBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBACzC,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC;oBAChC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC,CAAC;iBACD,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;iBAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YAErC,kDAAkD;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAChD,MAAM,MAAM,GAAG,KAAK;iBACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;iBAC/B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAEhB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,QAAgB;QACvC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO;QAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,IAAA,qCAAmB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEtD,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;CACF;AArHD,0CAqHC"}
@@ -0,0 +1,26 @@
1
+ import { EventEmitter } from "events";
2
+ import { LogStore } from "../storage/log-store.js";
3
+ export declare class HermesMonitor extends EventEmitter {
4
+ private store;
5
+ private metroPort;
6
+ private captureNetwork;
7
+ private ws;
8
+ private reconnectTimer;
9
+ private discoveryTimer;
10
+ private _connected;
11
+ private shouldReconnect;
12
+ private pendingRequests;
13
+ private cdpMessageId;
14
+ constructor(store: LogStore, metroPort?: number, captureNetwork?: boolean);
15
+ get isConnected(): boolean;
16
+ start(): void;
17
+ stop(): void;
18
+ private startDiscovery;
19
+ private discover;
20
+ private connectToTarget;
21
+ private enableDomains;
22
+ private sendCDP;
23
+ private scheduleReconnect;
24
+ private handleMessage;
25
+ }
26
+ //# sourceMappingURL=hermes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../src/monitors/hermes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAiBnD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAK;gBAEb,KAAK,EAAE,QAAQ,EAAE,SAAS,SAAO,EAAE,cAAc,UAAO;IAOpE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI;IAiBZ,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,eAAe;IA0CvB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,aAAa;CAwBtB"}