mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-11 08:12:38 +02:00
feat: native desktop notifications + rowboat:// deep links
Adds INotificationService with an Electron implementation, plus a deep-link
dispatcher (rowboat://) for routing notification clicks back into the app.
Notifications:
- New `notify-user` skill + builtin tool. Title, message, optional primary
link, optional secondary actions. Supports https:// (opens in browser) and
rowboat:// (opens in app) targets.
- ElectronNotificationService holds strong refs to active Notification
instances so click handlers survive GC (otherwise macOS click silently
no-ops).
- Calendar meeting notifier fires 1-min warnings with "take notes" /
"join + take notes" actions backed by deep links.
Deep links (rowboat://):
- forge.config.cjs declares the protocol; main.ts wires single-instance
lock, setAsDefaultProtocolClient, open-url (mac), second-instance (win/
linux), and first-launch argv extraction.
- New deeplink.ts dispatcher with dispatchUrl(url): main-handled actions
(rowboat://action?type=...) vs renderer navigation (rowboat://open?...)
via app:openUrl IPC. Includes pending-URL buffering for first-launch
delivery before the renderer is ready.
- Renderer parseDeepLink supports file / chat / graph / task /
suggested-topics targets.
- New app:consumePendingDeepLink IPC for renderer one-time drain on mount.
Refactor: extractConferenceLink moved out of calendar-block.tsx into
shared lib/calendar-event.ts (used by both the block and the take-notes
deep-link handler)
This commit is contained in:
parent
9ed54e2b94
commit
1c2b2ac1fc
17 changed files with 712 additions and 20 deletions
|
|
@ -299,6 +299,28 @@ const ipcSchemas = {
|
|||
}),
|
||||
res: z.null(),
|
||||
},
|
||||
'app:openUrl': {
|
||||
req: z.object({
|
||||
url: z.string(),
|
||||
}),
|
||||
res: z.null(),
|
||||
},
|
||||
'app:takeMeetingNotes': {
|
||||
req: z.object({
|
||||
// Pass the raw calendar event JSON through; renderer adapts to its existing flow.
|
||||
event: z.unknown(),
|
||||
// When true, the renderer should also open the meeting URL (Zoom/Meet/etc.)
|
||||
// in addition to triggering the take-notes flow.
|
||||
openMeeting: z.boolean().optional(),
|
||||
}),
|
||||
res: z.null(),
|
||||
},
|
||||
'app:consumePendingDeepLink': {
|
||||
req: z.null(),
|
||||
res: z.object({
|
||||
url: z.string().nullable(),
|
||||
}),
|
||||
},
|
||||
'granola:getConfig': {
|
||||
req: z.null(),
|
||||
res: z.object({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue