tauri-plugin-debug-tools 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/AGENTS.md +346 -0
  2. package/LICENSE +21 -0
  3. package/README.md +303 -0
  4. package/dist-js/consoleLogger.d.ts +92 -0
  5. package/dist-js/consoleLogger.d.ts.map +1 -0
  6. package/dist-js/consoleLogger.js +317 -0
  7. package/dist-js/debugBridge.d.ts +50 -0
  8. package/dist-js/debugBridge.d.ts.map +1 -0
  9. package/dist-js/debugBridge.js +66 -0
  10. package/dist-js/index.d.ts +3 -0
  11. package/dist-js/index.d.ts.map +1 -0
  12. package/dist-js/index.js +2 -0
  13. package/dist-js/logAdapter.d.ts +36 -0
  14. package/dist-js/logAdapter.d.ts.map +1 -0
  15. package/dist-js/logAdapter.js +42 -0
  16. package/dist-js/screenshotHelper.d.ts +60 -0
  17. package/dist-js/screenshotHelper.d.ts.map +1 -0
  18. package/dist-js/screenshotHelper.js +100 -0
  19. package/examples/.vscode/extensions.json +3 -0
  20. package/examples/README.md +51 -0
  21. package/examples/bun.lock +265 -0
  22. package/examples/package.json +19 -0
  23. package/examples/src/assets/javascript.svg +1 -0
  24. package/examples/src/assets/tauri.svg +6 -0
  25. package/examples/src/index.html +56 -0
  26. package/examples/src/main.js +91 -0
  27. package/examples/src/styles.css +112 -0
  28. package/examples/src-tauri/Cargo.lock +5674 -0
  29. package/examples/src-tauri/Cargo.toml +25 -0
  30. package/examples/src-tauri/build.rs +3 -0
  31. package/examples/src-tauri/capabilities/default.json +7 -0
  32. package/examples/src-tauri/icons/128x128.png +0 -0
  33. package/examples/src-tauri/icons/128x128@2x.png +0 -0
  34. package/examples/src-tauri/icons/32x32.png +0 -0
  35. package/examples/src-tauri/icons/Square107x107Logo.png +0 -0
  36. package/examples/src-tauri/icons/Square142x142Logo.png +0 -0
  37. package/examples/src-tauri/icons/Square150x150Logo.png +0 -0
  38. package/examples/src-tauri/icons/Square284x284Logo.png +0 -0
  39. package/examples/src-tauri/icons/Square30x30Logo.png +0 -0
  40. package/examples/src-tauri/icons/Square310x310Logo.png +0 -0
  41. package/examples/src-tauri/icons/Square44x44Logo.png +0 -0
  42. package/examples/src-tauri/icons/Square71x71Logo.png +0 -0
  43. package/examples/src-tauri/icons/Square89x89Logo.png +0 -0
  44. package/examples/src-tauri/icons/StoreLogo.png +0 -0
  45. package/examples/src-tauri/icons/icon.icns +0 -0
  46. package/examples/src-tauri/icons/icon.ico +0 -0
  47. package/examples/src-tauri/icons/icon.png +0 -0
  48. package/examples/src-tauri/src/lib.rs +15 -0
  49. package/examples/src-tauri/src/main.rs +6 -0
  50. package/examples/src-tauri/tauri.conf.json +33 -0
  51. package/examples/tests/e2e.mac.test.ts +203 -0
  52. package/examples/tests/e2e.test.ts +131 -0
  53. package/examples/vitest.config.ts +10 -0
  54. package/guest-js/consoleLogger.ts +369 -0
  55. package/guest-js/debugBridge.ts +93 -0
  56. package/guest-js/index.ts +2 -0
  57. package/guest-js/logAdapter.ts +62 -0
  58. package/guest-js/screenshotHelper.ts +122 -0
  59. package/package.json +84 -0
  60. package/permissions/autogenerated/commands/append_debug_logs.toml +13 -0
  61. package/permissions/autogenerated/commands/capture_webview_state.toml +13 -0
  62. package/permissions/autogenerated/commands/get_console_logs.toml +13 -0
  63. package/permissions/autogenerated/commands/reset_debug_logs.toml +13 -0
  64. package/permissions/autogenerated/commands/send_debug_command.toml +13 -0
  65. package/permissions/autogenerated/commands/write_debug_snapshot.toml +13 -0
  66. package/permissions/autogenerated/reference.md +201 -0
  67. package/permissions/debug-with-logging.toml +26 -0
  68. package/permissions/default.toml +26 -0
  69. package/permissions/schemas/schema.json +384 -0
  70. package/skills/debug-tauri/SKILL.md +114 -0
  71. package/skills/debug-tauri/references/IPC_COMMANDS.md +196 -0
  72. package/skills/debug-tauri/references/LOGGING.md +195 -0
  73. package/skills/debug-tauri/references/MIGRATION.md +487 -0
  74. package/skills/debug-tauri/references/REFERENCE.md +206 -0
  75. package/skills/debug-tauri/references/REPORT_TEMPLATE.md +166 -0
  76. package/skills/debug-tauri/references/SCREENSHOTS.md +193 -0
  77. package/skills/debug-tauri/references/TROUBLESHOOTING.md +144 -0
  78. package/skills/debug-tauri/scripts/analyze_logs.sh +127 -0
  79. package/skills/debug-tauri/scripts/capture.sh +89 -0
  80. package/skills/debug-tauri/scripts/validate_setup.sh +181 -0
  81. package/src/commands.rs +147 -0
  82. package/src/lib.rs +41 -0
@@ -0,0 +1,127 @@
1
+ #!/bin/bash
2
+ # Analyze Tauri console logs for errors and patterns
3
+ # Usage: ./analyze_logs.sh [log-file] [bundle-id]
4
+ #
5
+ # Examples:
6
+ # ./analyze_logs.sh # Auto-detect from TAURI_BUNDLE_ID
7
+ # ./analyze_logs.sh /path/to/debug.log # Custom path
8
+ # ./analyze_logs.sh "" com.example.myapp # Specify bundle ID
9
+
10
+ # Auto-detect log file path based on platform and bundle ID
11
+ detect_log_path() {
12
+ local bundle_id="${1:-${TAURI_BUNDLE_ID}}"
13
+
14
+ if [ -z "$bundle_id" ]; then
15
+ echo "⚠️ Bundle ID not provided. Set TAURI_BUNDLE_ID or pass as argument."
16
+ return 1
17
+ fi
18
+
19
+ case "$(uname -s)" in
20
+ Darwin) # macOS
21
+ echo "$HOME/Library/Logs/$bundle_id/debug.log"
22
+ ;;
23
+ Linux)
24
+ echo "$HOME/.local/share/$bundle_id/logs/debug.log"
25
+ ;;
26
+ MINGW*|MSYS*|CYGWIN*) # Windows
27
+ echo "$LOCALAPPDATA/$bundle_id/logs/debug.log"
28
+ ;;
29
+ *)
30
+ echo "⚠️ Unsupported platform: $(uname -s)"
31
+ return 1
32
+ ;;
33
+ esac
34
+ }
35
+
36
+ # Determine log file
37
+ if [ -n "$1" ]; then
38
+ LOG_FILE="$1"
39
+ else
40
+ LOG_FILE=$(detect_log_path "${2}")
41
+ if [ $? -ne 0 ] || [ -z "$LOG_FILE" ]; then
42
+ echo "❌ Could not determine log file path"
43
+ echo "💡 Usage: $0 [log-file] [bundle-id]"
44
+ echo " Example: $0 \"\" com.example.myapp"
45
+ echo " Or set: export TAURI_BUNDLE_ID=com.example.myapp"
46
+ exit 1
47
+ fi
48
+ fi
49
+
50
+ if [ ! -f "$LOG_FILE" ]; then
51
+ echo "❌ Log file not found: $LOG_FILE"
52
+ echo "💡 Ensure tauri-plugin-log is initialized and app has been run"
53
+ echo "💡 Expected locations:"
54
+ echo " macOS: ~/Library/Logs/{bundle_id}/debug.log"
55
+ echo " Linux: ~/.local/share/{bundle_id}/logs/debug.log"
56
+ echo " Windows: %LOCALAPPDATA%\\{bundle_id}\\logs\\debug.log"
57
+ exit 1
58
+ fi
59
+
60
+ echo "🔍 Analyzing logs from: $LOG_FILE"
61
+ echo "=========================================="
62
+ echo ""
63
+
64
+ # Count log levels (tauri-plugin-log format: YYYY-MM-DDTHH:MM:SS.sssZ LEVEL app: message)
65
+ echo "📊 Log Statistics:"
66
+ total_lines=$(wc -l < "$LOG_FILE" | tr -d ' ')
67
+ error_count=$(grep -c " ERROR " "$LOG_FILE" 2>/dev/null || echo "0")
68
+ warn_count=$(grep -c " WARN " "$LOG_FILE" 2>/dev/null || echo "0")
69
+ info_count=$(grep -c " INFO " "$LOG_FILE" 2>/dev/null || echo "0")
70
+ debug_count=$(grep -c " DEBUG " "$LOG_FILE" 2>/dev/null || echo "0")
71
+ trace_count=$(grep -c " TRACE " "$LOG_FILE" 2>/dev/null || echo "0")
72
+
73
+ echo " Total lines: $total_lines"
74
+ echo " ERROR: $error_count"
75
+ echo " WARN: $warn_count"
76
+ echo " INFO: $info_count"
77
+ echo " DEBUG: $debug_count"
78
+ echo " TRACE: $trace_count"
79
+
80
+ echo ""
81
+ echo "❌ Recent Errors (last 5):"
82
+ if [ "$error_count" -eq 0 ]; then
83
+ echo " ✅ No errors found"
84
+ else
85
+ grep " ERROR " "$LOG_FILE" | tail -5
86
+ fi
87
+
88
+ echo ""
89
+ echo "⚠️ Recent Warnings (last 5):"
90
+ if [ "$warn_count" -eq 0 ]; then
91
+ echo " ✅ No warnings found"
92
+ else
93
+ grep " WARN " "$LOG_FILE" | tail -5
94
+ fi
95
+
96
+ echo ""
97
+ echo "📈 Pattern Analysis:"
98
+
99
+ # Common error patterns
100
+ echo " Searching for common issues..."
101
+
102
+ # Network errors
103
+ net_errors=$(grep -i "network\|fetch\|xhr\|cors" "$LOG_FILE" 2>/dev/null | wc -l | tr -d ' ')
104
+ if [ "$net_errors" -gt 0 ]; then
105
+ echo " 🌐 Network-related issues: $net_errors"
106
+ fi
107
+
108
+ # Type errors
109
+ type_errors=$(grep -i "typeerror\|undefined\|null" "$LOG_FILE" 2>/dev/null | wc -l | tr -d ' ')
110
+ if [ "$type_errors" -gt 0 ]; then
111
+ echo " 🔤 Type/undefined errors: $type_errors"
112
+ fi
113
+
114
+ # WebGPU errors
115
+ gpu_errors=$(grep -i "webgpu\|gpu\|shader" "$LOG_FILE" 2>/dev/null | wc -l | tr -d ' ')
116
+ if [ "$gpu_errors" -gt 0 ]; then
117
+ echo " 🎮 WebGPU-related issues: $gpu_errors"
118
+ fi
119
+
120
+ echo ""
121
+ echo "✅ Analysis complete"
122
+ echo ""
123
+ echo "💡 For full log review:"
124
+ echo " cat $LOG_FILE"
125
+ echo ""
126
+ echo "💡 Monitor logs in real-time:"
127
+ echo " tail -f $LOG_FILE"
@@ -0,0 +1,89 @@
1
+ #!/bin/bash
2
+ # Tauri app screenshot helper script (DEPRECATED)
3
+ # Usage: ./capture.sh
4
+ #
5
+ # ⚠️ DEPRECATED: This script is legacy and macOS-only.
6
+ #
7
+ # 💡 Migrate to official plugin API:
8
+ # import { captureMainWindow } from "tauri-plugin-debug-tools/screenshotHelper";
9
+ # const screenshot = await captureMainWindow();
10
+ #
11
+ # Benefits of plugin API:
12
+ # - Cross-platform (macOS/Windows/Linux)
13
+ # - No screen recording permissions required
14
+ # - Programmatic access from TypeScript
15
+ # - Base64 PNG data returned directly
16
+
17
+ APP_NAME="${TAURI_APP_NAME:-tauri-app}"
18
+ OUTPUT_DIR="/tmp"
19
+
20
+ # Show deprecation warning
21
+ echo "⚠️ WARNING: This script is deprecated"
22
+ echo "═══════════════════════════════════════"
23
+ echo ""
24
+ echo "This legacy script only works on macOS and requires Screen Recording permissions."
25
+ echo ""
26
+ echo "💡 Recommended: Use the official tauri-plugin-screenshots API instead:"
27
+ echo ""
28
+ echo " import { captureMainWindow } from 'tauri-plugin-debug-tools/screenshotHelper';"
29
+ echo " const screenshot = await captureMainWindow();"
30
+ echo ""
31
+ echo "Benefits:"
32
+ echo " ✅ Cross-platform (macOS/Windows/Linux)"
33
+ echo " ✅ No special permissions required"
34
+ echo " ✅ Programmatic access from TypeScript"
35
+ echo ""
36
+ echo "Press Enter to continue with legacy script, or Ctrl+C to cancel..."
37
+ read -r
38
+ echo ""
39
+
40
+ function check_app_running() {
41
+ if ! pgrep -x "$APP_NAME" > /dev/null; then
42
+ echo "❌ Error: $APP_NAME is not running"
43
+ echo "💡 Start the app with your dev command (e.g., tauri dev)"
44
+ exit 1
45
+ fi
46
+ echo "✅ $APP_NAME is running"
47
+ }
48
+
49
+ function capture_screenshot() {
50
+ local timestamp=$(date +%s)
51
+ local output_path="$OUTPUT_DIR/tauri_debug_$timestamp.png"
52
+
53
+ echo "📸 Capturing screenshot..."
54
+
55
+ if ! screencapture -x -T 0 "$output_path" 2>/dev/null; then
56
+ echo "❌ Failed to capture screenshot"
57
+ echo "💡 Check System Preferences > Security & Privacy > Screen Recording"
58
+ exit 1
59
+ fi
60
+
61
+ if [ ! -f "$output_path" ]; then
62
+ echo "❌ Screenshot file not created"
63
+ exit 1
64
+ fi
65
+
66
+ echo "✅ Screenshot saved: $output_path"
67
+ echo "$output_path"
68
+ }
69
+
70
+ function get_process_info() {
71
+ echo "🔍 Process information:"
72
+ ps aux | grep "$APP_NAME" | grep -v grep | head -1
73
+ }
74
+
75
+ function main() {
76
+ echo "🚀 Tauri Debug Helper"
77
+ echo "===================="
78
+ echo ""
79
+
80
+ check_app_running
81
+ echo ""
82
+
83
+ get_process_info
84
+ echo ""
85
+
86
+ capture_screenshot
87
+ }
88
+
89
+ main
@@ -0,0 +1,181 @@
1
+ #!/bin/bash
2
+ # Validate debug tools setup with official plugins
3
+ # Usage: ./validate_setup.sh [bundle-id]
4
+ #
5
+ # Examples:
6
+ # TAURI_BUNDLE_ID=com.example.myapp ./validate_setup.sh
7
+ # ./validate_setup.sh com.example.myapp
8
+
9
+ APP_NAME="${TAURI_APP_NAME:-tauri-app}"
10
+ BUNDLE_ID="${1:-${TAURI_BUNDLE_ID}}"
11
+
12
+ # Detect log file path based on platform
13
+ detect_log_path() {
14
+ local bundle_id="$1"
15
+
16
+ if [ -z "$bundle_id" ]; then
17
+ return 1
18
+ fi
19
+
20
+ case "$(uname -s)" in
21
+ Darwin)
22
+ echo "$HOME/Library/Logs/$bundle_id/debug.log"
23
+ ;;
24
+ Linux)
25
+ echo "$HOME/.local/share/$bundle_id/logs/debug.log"
26
+ ;;
27
+ MINGW*|MSYS*|CYGWIN*)
28
+ echo "$LOCALAPPDATA/$bundle_id/logs/debug.log"
29
+ ;;
30
+ *)
31
+ return 1
32
+ ;;
33
+ esac
34
+ }
35
+
36
+ echo "🔍 Validating debug setup..."
37
+ echo "============================"
38
+ echo ""
39
+
40
+ # Check if app is running
41
+ echo "📱 App Process:"
42
+ if pgrep -x "$APP_NAME" > /dev/null; then
43
+ pid=$(pgrep -x "$APP_NAME")
44
+ echo " ✅ App is running (PID: $pid)"
45
+
46
+ # Get process details
47
+ if command -v ps &> /dev/null; then
48
+ ps -p "$pid" -o pid,rss,%cpu,%mem,command 2>/dev/null | tail -1
49
+ fi
50
+ else
51
+ echo " ⚠️ App not running"
52
+ echo " 💡 Start with: tauri dev"
53
+ fi
54
+
55
+ echo ""
56
+
57
+ # Check screen recording permission (macOS only)
58
+ if [[ "$OSTYPE" == "darwin"* ]]; then
59
+ echo "📸 Screen Recording Permission:"
60
+
61
+ test_file="/tmp/screen_test_$$.png"
62
+ if screencapture -x -T 0 "$test_file" 2>/dev/null; then
63
+ rm -f "$test_file"
64
+ echo " ✅ Screen recording permission granted"
65
+ else
66
+ echo " ❌ Screen recording permission denied"
67
+ echo " 💡 Grant in: System Preferences > Security & Privacy > Screen Recording"
68
+ fi
69
+
70
+ echo ""
71
+ fi
72
+
73
+ # Check for official plugin log file
74
+ echo "📝 Official Plugin Logs (tauri-plugin-log):"
75
+ if [ -n "$BUNDLE_ID" ]; then
76
+ PLUGIN_LOG=$(detect_log_path "$BUNDLE_ID")
77
+
78
+ if [ -n "$PLUGIN_LOG" ] && [ -f "$PLUGIN_LOG" ]; then
79
+ log_size=$(wc -l < "$PLUGIN_LOG" | tr -d ' ')
80
+ echo " ✅ Plugin log file exists ($log_size lines)"
81
+ echo " Location: $PLUGIN_LOG"
82
+
83
+ if [ "$log_size" -eq 0 ]; then
84
+ echo " ⚠️ Log file is empty - logger may not be initialized"
85
+ echo " 💡 Call logger.initialize() in frontend"
86
+ fi
87
+ else
88
+ echo " ⚠️ Plugin log file not found"
89
+ echo " 💡 Expected: $PLUGIN_LOG"
90
+ echo " 💡 Ensure tauri-plugin-log is initialized and app has been run"
91
+ fi
92
+ else
93
+ echo " ℹ️ Bundle ID not provided"
94
+ echo " 💡 Set TAURI_BUNDLE_ID or pass as argument to check plugin logs"
95
+ echo " 💡 Example: TAURI_BUNDLE_ID=com.example.myapp ./validate_setup.sh"
96
+ fi
97
+
98
+ # Check for legacy log file
99
+ echo ""
100
+ echo "📝 Legacy Logs (consoleLogger):"
101
+ if [ -f "/tmp/tauri_console_logs.jsonl" ]; then
102
+ log_size=$(wc -l < /tmp/tauri_console_logs.jsonl | tr -d ' ')
103
+ echo " ⚠️ Legacy log file exists ($log_size lines)"
104
+ echo " 💡 Migrate to tauri-plugin-log for better persistence"
105
+ else
106
+ echo " ✅ No legacy logs (good - using official plugin)"
107
+ fi
108
+
109
+ # Check for screenshots
110
+ echo ""
111
+ echo "📸 Screenshots:"
112
+ screenshot_count=$(find /tmp -name "tauri_debug_*.png" -mtime -1 2>/dev/null | wc -l | tr -d ' ')
113
+ if [ "$screenshot_count" -gt 0 ]; then
114
+ echo " ℹ️ Found $screenshot_count legacy screenshot(s) in /tmp"
115
+ echo " $(ls -t /tmp/tauri_debug_*.png 2>/dev/null | head -1)"
116
+ echo " 💡 Use captureMainWindow() from screenshotHelper for plugin API"
117
+ else
118
+ echo " ℹ️ No legacy screenshots found"
119
+ fi
120
+
121
+ echo ""
122
+
123
+ # Check for required tools
124
+ echo "🛠️ Tools:"
125
+
126
+ check_tool() {
127
+ local tool=$1
128
+ local status=$2
129
+ local install_hint=$3
130
+
131
+ if command -v "$tool" &> /dev/null; then
132
+ echo " ✅ $tool ($status)"
133
+ else
134
+ echo " ⚠️ $tool not found ($status)"
135
+ if [ -n "$install_hint" ]; then
136
+ echo " Install: $install_hint"
137
+ fi
138
+ fi
139
+ }
140
+
141
+ # Optional tools
142
+ if [[ "$OSTYPE" == "darwin"* ]]; then
143
+ check_tool "screencapture" "legacy, optional" ""
144
+ fi
145
+
146
+ echo ""
147
+
148
+ # Check project structure (if run from project root)
149
+ echo "📁 Project Structure:"
150
+
151
+ if [ -f "tauri.conf.json" ] || [ -f "src-tauri/tauri.conf.json" ]; then
152
+ echo " ✅ Tauri project detected"
153
+
154
+ # Check for debug capabilities
155
+ if [ -f "src-tauri/capabilities/default.json" ]; then
156
+ echo " ✅ Capabilities file exists"
157
+
158
+ if grep -q "debug-tools" src-tauri/capabilities/default.json 2>/dev/null; then
159
+ echo " ✅ Debug tools permissions found"
160
+ else
161
+ echo " ⚠️ Debug tools permissions may not be configured"
162
+ fi
163
+ else
164
+ echo " ℹ️ No capabilities file found"
165
+ fi
166
+ else
167
+ echo " ℹ️ Not in a Tauri project directory (or run from skill directory)"
168
+ fi
169
+
170
+ echo ""
171
+ echo "=========================================="
172
+ echo "✅ Validation complete"
173
+ echo ""
174
+
175
+ # Summary
176
+ if pgrep -x "$APP_NAME" > /dev/null && [[ "$OSTYPE" == "darwin"* ]] && screencapture -x -T 0 /tmp/test_$$.png 2>/dev/null; then
177
+ rm -f /tmp/test_$$.png
178
+ echo "🎉 Ready to debug!"
179
+ else
180
+ echo "⚠️ Some issues found. Review output above."
181
+ fi
@@ -0,0 +1,147 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use std::path::PathBuf;
3
+ use tauri::{AppHandle, Emitter, Manager, Runtime};
4
+
5
+ #[derive(Debug, Serialize, Deserialize)]
6
+ pub struct WebViewState {
7
+ pub url: String,
8
+ pub title: String,
9
+ pub user_agent: String,
10
+ pub viewport: ViewportInfo,
11
+ }
12
+
13
+ #[derive(Debug, Serialize, Deserialize)]
14
+ pub struct ViewportInfo {
15
+ pub width: u32,
16
+ pub height: u32,
17
+ }
18
+
19
+ #[derive(Debug, Serialize, Deserialize)]
20
+ pub struct ConsoleMessage {
21
+ pub level: String,
22
+ pub message: String,
23
+ pub timestamp: i64,
24
+ }
25
+
26
+ #[derive(Debug, Serialize, Deserialize)]
27
+ pub struct ConsoleLogEntryPayload {
28
+ pub timestamp: i64,
29
+ pub level: String,
30
+ pub message: String,
31
+ pub args: serde_json::Value,
32
+ pub stack_trace: Option<String>,
33
+ }
34
+
35
+ fn console_log_path() -> PathBuf {
36
+ // Use platform temp directory to avoid hardcoded /tmp paths.
37
+ std::env::temp_dir().join("tauri_console_logs.jsonl")
38
+ }
39
+
40
+ /// Get WebView state.
41
+ #[tauri::command]
42
+ pub async fn capture_webview_state<R: Runtime>(app: AppHandle<R>) -> Result<WebViewState, String> {
43
+ let window = app
44
+ .get_webview_window("main")
45
+ .ok_or("Main window not found")?;
46
+
47
+ let url = window.url().map_err(|e| e.to_string())?;
48
+ let title = window.title().map_err(|e| e.to_string())?;
49
+
50
+ // Fetch viewport information.
51
+ let size = window
52
+ .inner_size()
53
+ .map_err(|e| format!("Failed to get window size: {}", e))?;
54
+
55
+ Ok(WebViewState {
56
+ url: url.to_string(),
57
+ title,
58
+ user_agent: "TauriWebView/2.0".to_string(), // TODO: Fetch the real User-Agent.
59
+ viewport: ViewportInfo {
60
+ width: size.width,
61
+ height: size.height,
62
+ },
63
+ })
64
+ }
65
+
66
+ /// Get console logs.
67
+ /// NOTE: Prefer fetching logs directly on the frontend instead of buffering in Rust.
68
+ /// Use debugBridge.getConsoleLogs() to inspect logs without Safari DevTools.
69
+ #[tauri::command]
70
+ pub async fn get_console_logs<R: Runtime>(
71
+ _app: AppHandle<R>,
72
+ ) -> Result<Vec<ConsoleMessage>, String> {
73
+ // Placeholder for backward compatibility.
74
+ // Actual log collection happens in the frontend consoleLogger.
75
+ Ok(vec![])
76
+ }
77
+
78
+ /// Send a message to the WebView for frontend handling.
79
+ /// Use event-based communication instead of eval().
80
+ #[tauri::command]
81
+ pub async fn send_debug_command<R: Runtime>(
82
+ app: AppHandle<R>,
83
+ command: String,
84
+ payload: serde_json::Value,
85
+ ) -> Result<String, String> {
86
+ let window = app
87
+ .get_webview_window("main")
88
+ .ok_or("Main window not found")?;
89
+
90
+ // Emit event to the frontend.
91
+ window
92
+ .emit("debug-command", (command, payload))
93
+ .map_err(|e| format!("Failed to send debug command: {}", e))?;
94
+
95
+ Ok("Command sent to frontend".to_string())
96
+ }
97
+
98
+ /// Append console logs to /tmp.
99
+ #[tauri::command]
100
+ pub async fn append_debug_logs(logs: Vec<ConsoleLogEntryPayload>) -> Result<String, String> {
101
+ if logs.is_empty() {
102
+ return Ok("no logs".to_string());
103
+ }
104
+
105
+ let path = console_log_path();
106
+ let mut file = std::fs::OpenOptions::new()
107
+ .create(true)
108
+ .append(true)
109
+ .open(&path)
110
+ .map_err(|e| format!("Failed to open log file: {}", e))?;
111
+
112
+ for entry in logs {
113
+ let line = serde_json::to_string(&entry)
114
+ .map_err(|e| format!("Failed to serialize log entry: {}", e))?;
115
+ use std::io::Write;
116
+ writeln!(file, "{}", line).map_err(|e| format!("Failed to write log: {}", e))?;
117
+ }
118
+
119
+ Ok(path.to_string_lossy().into_owned())
120
+ }
121
+
122
+ /// Reset the console log file.
123
+ #[tauri::command]
124
+ pub async fn reset_debug_logs() -> Result<String, String> {
125
+ let path = console_log_path();
126
+ std::fs::OpenOptions::new()
127
+ .create(true)
128
+ .write(true)
129
+ .truncate(true)
130
+ .open(&path)
131
+ .map_err(|e| format!("Failed to reset log file: {}", e))?;
132
+ Ok(path.to_string_lossy().into_owned())
133
+ }
134
+
135
+ /// Save a debug snapshot to /tmp.
136
+ #[tauri::command]
137
+ pub async fn write_debug_snapshot(payload: serde_json::Value) -> Result<String, String> {
138
+ let ts = std::time::SystemTime::now()
139
+ .duration_since(std::time::UNIX_EPOCH)
140
+ .map_err(|e| format!("Failed to get timestamp: {}", e))?
141
+ .as_secs();
142
+ let path = std::env::temp_dir().join(format!("tauri_debug_snapshot_{}.json", ts));
143
+ let json = serde_json::to_string_pretty(&payload)
144
+ .map_err(|e| format!("Failed to serialize payload: {}", e))?;
145
+ std::fs::write(&path, json).map_err(|e| format!("Failed to write file: {}", e))?;
146
+ Ok(path.to_string_lossy().into_owned())
147
+ }
package/src/lib.rs ADDED
@@ -0,0 +1,41 @@
1
+ use tauri::{
2
+ plugin::{Builder, TauriPlugin},
3
+ Manager, Runtime,
4
+ };
5
+ use tauri_plugin_log::{Target, TargetKind};
6
+
7
+ mod commands;
8
+
9
+ pub fn init<R: Runtime>() -> TauriPlugin<R> {
10
+ Builder::new("debug-tools")
11
+ .setup(|app, _api| {
12
+ let log_plugin = tauri_plugin_log::Builder::new()
13
+ .targets([
14
+ Target::new(TargetKind::Stdout),
15
+ Target::new(TargetKind::LogDir {
16
+ file_name: Some("debug.log".to_string()),
17
+ }),
18
+ Target::new(TargetKind::Webview),
19
+ ])
20
+ .max_file_size(50_000) // 50KB auto-rotation
21
+ .build();
22
+ let screenshots_plugin = tauri_plugin_screenshots::init();
23
+
24
+ let handle = app.app_handle().clone();
25
+ std::thread::spawn(move || {
26
+ let _ = handle.plugin(log_plugin);
27
+ let _ = handle.plugin(screenshots_plugin);
28
+ });
29
+
30
+ Ok(())
31
+ })
32
+ .invoke_handler(tauri::generate_handler![
33
+ commands::capture_webview_state,
34
+ commands::get_console_logs,
35
+ commands::send_debug_command,
36
+ commands::append_debug_logs,
37
+ commands::reset_debug_logs,
38
+ commands::write_debug_snapshot,
39
+ ])
40
+ .build()
41
+ }