mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-30 20:39:46 +02:00
notification initial commit
This commit is contained in:
parent
0bb256879c
commit
8595190bd4
5 changed files with 91 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ import { getAccessToken } from "../../auth/tokens.js";
|
|||
import { API_URL } from "../../config/env.js";
|
||||
import { updateContent, updateTrackBlock } from "../../knowledge/track/fileops.js";
|
||||
import type { IBrowserControlService } from "../browser-control/service.js";
|
||||
import type { INotificationService } from "../notification/service.js";
|
||||
// Parser libraries are loaded dynamically inside parseFile.execute()
|
||||
// to avoid pulling pdfjs-dist's DOM polyfills into the main bundle.
|
||||
// Import paths are computed so esbuild cannot statically resolve them.
|
||||
|
|
@ -1514,4 +1515,37 @@ export const BuiltinTools: z.infer<typeof BuiltinToolsSchema> = {
|
|||
}
|
||||
},
|
||||
},
|
||||
|
||||
'notify-user': {
|
||||
description: "Show a native OS notification to the user. Clicking the notification opens the provided link in the default browser, or focuses the Rowboat app if no link is given.",
|
||||
inputSchema: z.object({
|
||||
title: z.string().min(1).max(120).optional().describe("Bold headline shown at the top of the notification. Defaults to 'Rowboat'."),
|
||||
message: z.string().min(1).describe("Body text of the notification."),
|
||||
link: z.string().url().refine((v) => /^https?:\/\//i.test(v), {
|
||||
message: "link must be an http:// or https:// URL",
|
||||
}).optional().describe("Optional http(s) URL opened when the user clicks the notification."),
|
||||
}),
|
||||
isAvailable: async () => {
|
||||
try {
|
||||
return container.resolve<INotificationService>('notificationService').isSupported();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
execute: async ({ title, message, link }: { title?: string; message: string; link?: string }) => {
|
||||
try {
|
||||
const service = container.resolve<INotificationService>('notificationService');
|
||||
if (!service.isSupported()) {
|
||||
return { success: false, error: 'Notifications are not supported on this system' };
|
||||
}
|
||||
service.notify({ title, message, link });
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
10
apps/x/packages/core/src/application/notification/service.ts
Normal file
10
apps/x/packages/core/src/application/notification/service.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export interface NotifyInput {
|
||||
title?: string;
|
||||
message: string;
|
||||
link?: string;
|
||||
}
|
||||
|
||||
export interface INotificationService {
|
||||
isSupported(): boolean;
|
||||
notify(input: NotifyInput): void;
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import { FSAgentScheduleRepo, IAgentScheduleRepo } from "../agent-schedule/repo.
|
|||
import { FSAgentScheduleStateRepo, IAgentScheduleStateRepo } from "../agent-schedule/state-repo.js";
|
||||
import { FSSlackConfigRepo, ISlackConfigRepo } from "../slack/repo.js";
|
||||
import type { IBrowserControlService } from "../application/browser-control/service.js";
|
||||
import type { INotificationService } from "../application/notification/service.js";
|
||||
|
||||
const container = createContainer({
|
||||
injectionMode: InjectionMode.PROXY,
|
||||
|
|
@ -49,3 +50,9 @@ export function registerBrowserControlService(service: IBrowserControlService):
|
|||
browserControlService: asValue(service),
|
||||
});
|
||||
}
|
||||
|
||||
export function registerNotificationService(service: INotificationService): void {
|
||||
container.register({
|
||||
notificationService: asValue(service),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue