Skip to content

Comments

Add macOS Shortcuts deep-link support for start/stop recording#30

Open
filippohronsky wants to merge 3 commits intoruzin:mainfrom
filippohronsky:feature/macos-shortcuts-deeplink-recording
Open

Add macOS Shortcuts deep-link support for start/stop recording#30
filippohronsky wants to merge 3 commits intoruzin:mainfrom
filippohronsky:feature/macos-shortcuts-deeplink-recording

Conversation

@filippohronsky
Copy link

Description

This PR adds Apple macOS Shortcuts integration via stenoai:// deep links, allowing recording to be controlled from Shortcuts and automation flows.

What changed

app/main.js

  • Added protocol handling for:
    • stenoai://record/start?name=...
    • stenoai://record/stop
  • Added macOS open-url handling with startup queueing so links work on cold and warm launch
  • Added dev-safe protocol registration and argv fallback for deep-link delivery
  • Added renderer-ready handshake to prevent startup race conditions
  • Added idempotent shortcut behavior (already recording / already stopped)
  • Added quiet-launch behavior and Dock activate recovery
  • Added shortcut notifications (respecting existing notifications setting)

app/index.html

  • Added shortcut IPC listeners:
    • shortcut-start-recording -> reuses existing startBtn.click()
    • shortcut-stop-recording -> reuses existing stopBtn.click()
  • Added shortcut-renderer-ready handshake event

app/package.json

  • Added build.protocols registration for the stenoai URL scheme

README.md

  • Added macOS Shortcuts section with setup and URL examples
  • Added calendar automation documentation using Rules – Calendar Automation bridge
  • Clearly documented that macOS Shortcuts cannot natively trigger on Calendar event start

Why

Enable reliable macOS Shortcut and calendar-driven automation control for recording, without changing existing recording business logic.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • Tested locally with npm start
  • Verified CLI functionality works
  • Tested on macOS
  • No breaking changes to existing functionality

Manual test scenarios

  1. Warm launch deep link start:
    • stenoai://record/start?name=Daily%20Standup
  2. Warm launch deep link stop:
    • stenoai://record/stop
  3. Cold launch via deep link with hidden-window behavior
  4. Idempotent responses for repeated start/stop triggers
  5. Existing Cmd+Shift+R global hotkey unchanged
  6. Re-open from Dock after background shortcut start and verify UI shows active recording

Additional Notes

  • Recording start/stop backend logic was not modified; shortcuts are routed into existing renderer button handlers.
  • No Python backend changes.
  • app/package-lock.json intentionally not modified.
  • I have read the CLA Document and I hereby sign the CLA

	modified:   app/index.html
	modified:   app/main.js
	modified:   app/package.json
	modified:   app/main.js
Copy link
Owner

@ruzin ruzin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution, Filip! This is a well-scoped feature — routing shortcuts into the existing button handlers is a clean approach, and the cold-launch queuing + renderer-ready handshake are nice touches.

A few things that need to be addressed before merge:

Breaking: safeStorage import dropped

The PR's diff changes the require('electron') destructure and drops safeStorage, which is used elsewhere in main.js. This would break existing functionality. The fix is straightforward — just add Notification to the existing import line without removing anything.

Subprocess calls instead of existing IPC handlers

shouldShowShortcutNotifications() and isBackendRecording() both shell out via runPythonScript() to call simple_recorder.py. But main.js already has IPC handlers for both of these (get-notifications at line ~1982 and get-status at line ~407). Spawning a new Python subprocess for each is slower and creates a second code path to maintain. These should reuse the existing internal logic directly (or at minimum call the same handler functions).

No input sanitization on session name

The name query param from the URL is passed through to the renderer with only a .trim(). Since this is an externally-triggered input (any app can open a stenoai:// URL), it should have basic validation — e.g., strip path separators, limit length, restrict to alphanumeric + common punctuation.

Commit messages

The three commits all have \tmodified: <filename> as their headline, which looks like pasted git status output. Would recommend squashing into a single commit with a descriptive message on merge.

Minor: README placement

The macOS Shortcuts section is quite detailed for an optional/advanced feature. Consider wrapping it in a <details> collapse or moving to a separate doc (e.g., docs/shortcuts.md) and linking from the README.


Overall the approach is solid — the queuing, idempotent behavior, and edge case handling show good attention to detail. Just needs the above fixes and it should be good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants