safari-mcp 2.7.13 → 2.7.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -437,6 +437,10 @@ xcodebuild -project "xcode/Safari MCP/Safari MCP.xcodeproj" \
437
437
  APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData/Safari_MCP-*/Build/Products/Release -name "Safari MCP.app" -maxdepth 2 | head -1)
438
438
  codesign --sign - --force --deep "$APP_PATH"
439
439
 
440
+ # 4. Re-sign safari-helper with the Apple Events entitlement
441
+ # (helps macOS surface the TCC Automation prompt reliably)
442
+ codesign --sign - --force --entitlements safari-helper.entitlements safari-helper
443
+
440
444
  # 4. Open the app (needed once so Safari registers the extension)
441
445
  open "$APP_PATH"
442
446
  ```
@@ -490,6 +494,7 @@ That call registers the Terminal app in the Automation database and then trigger
490
494
  |-------|-----|
491
495
  | "AppleScript error" | Enable "Allow JavaScript from Apple Events" in Safari → Develop |
492
496
  | "Not authorized to send Apple events to Safari" | Grant Automation → Safari to your IDE (see above) |
497
+ | "Not authorized" after `npm update` | Updating changes the binary's cdhash — macOS silently revokes Automation permission. Re-run the `osascript` one-liner above to re-grant it |
493
498
  | Screenshots empty | Grant Screen Recording permission to Terminal/VS Code |
494
499
  | Tab not found | Call `safari_list_tabs` to refresh tab indices |
495
500
  | Hebrew keyboard issues | All typing uses JS events — immune to keyboard layout |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safari-mcp",
3
- "version": "2.7.13",
3
+ "version": "2.7.15",
4
4
  "mcpName": "io.github.achiya-automation/safari-mcp",
5
5
  "description": "Safari browser automation for AI agents — native macOS, zero Chrome overhead. 80 tools via AppleScript + JavaScript.",
6
6
  "type": "module",
@@ -61,6 +61,7 @@
61
61
  "safari.js",
62
62
  "mcp-helpers.js",
63
63
  "safari-helper",
64
+ "safari-helper.entitlements",
64
65
  "safari-helper.swift",
65
66
  "extension/",
66
67
  "glama.json",
package/safari-helper CHANGED
Binary file
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>com.apple.security.automation.apple-events</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
package/safari.js CHANGED
@@ -1578,9 +1578,30 @@ export async function pressKey({ key, modifiers = [] }) {
1578
1578
  }
1579
1579
  }
1580
1580
  el.dispatchEvent(new KeyboardEvent('keyup', opts));
1581
+ // ContentEditable + Enter: check if the app actually handled it.
1582
+ // If editor content didn't change (no submit, no newline), the JS
1583
+ // keydown was ignored (isTrusted:false). Signal for native fallback.
1584
+ if ('${safeKey}' === 'Enter' && el.isContentEditable && !${shiftKey} && !prevented) {
1585
+ return '__ENTER_NOT_HANDLED__';
1586
+ }
1581
1587
  return 'OK';
1582
1588
  })()`
1583
1589
  );
1590
+
1591
+ // Fallback for ContentEditable Enter that wasn't handled by JS keydown:
1592
+ // apps like Discord/Slack require isTrusted:true. Briefly activate Safari
1593
+ // (~50ms), send real keystroke, then immediately restore the previous
1594
+ // frontmost app. The visual flash is imperceptible (<100ms total).
1595
+ if (result === '__ENTER_NOT_HANDLED__') {
1596
+ const savedApp = await saveFrontmostApp();
1597
+ await osascript(`tell application "Safari" to activate`);
1598
+ await new Promise(r => setTimeout(r, 80));
1599
+ await osascript(`tell application "System Events" to keystroke return`);
1600
+ await new Promise(r => setTimeout(r, 50));
1601
+ await restoreFocusIfStolen(savedApp);
1602
+ return `Pressed: enter (native fallback — brief activate+restore)`;
1603
+ }
1604
+
1584
1605
  return `Pressed: ${modifiers.length ? modifiers.join("+") + "+" : ""}${key}`;
1585
1606
  }
1586
1607