dsh-plugin-completion-notify 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.
package/lib/index.js ADDED
@@ -0,0 +1,29 @@
1
+ import { settingsNamespace } from "@deepseek-ai/dsh-settings";
2
+ import z from "@deepseek-ai/schemastery";
3
+ //#region lib/types/completion-notify-settings.js
4
+ /** Completion-notify preferences stored in the Host user-settings document. */
5
+ /** Settings namespace owned by the completion-notify plugin. */
6
+ const COMPLETION_NOTIFY_SETTINGS_NAMESPACE = "ui-completion-notify";
7
+ /** Field carrying whether desktop completion notifications are enabled. */
8
+ const COMPLETION_NOTIFY_ENABLED_FIELD = "enabled";
9
+ /** Default when the user-settings document has no override: notifications on. */
10
+ const DEFAULT_COMPLETION_NOTIFY_ENABLED = true;
11
+ /** Durable completion-notify schema; also the wire envelope the browser scope validates against. */
12
+ const CompletionNotifySettingsSchema = z.object({ [COMPLETION_NOTIFY_ENABLED_FIELD]: z.boolean().default(true) });
13
+ //#endregion
14
+ //#region lib/types/index.js
15
+ /** Host registration for the completion-notify preference. */
16
+ const NAMESPACE = settingsNamespace(COMPLETION_NOTIFY_SETTINGS_NAMESPACE);
17
+ /**
18
+ * Register the durable completion-notify section when the optional settings
19
+ * service is composed. The browser half reads and writes the enabled flag
20
+ * through the settings scope bound to this namespace.
21
+ * @param ctx - Host context that may acquire the settings service.
22
+ */
23
+ function apply(ctx) {
24
+ ctx.inject(["settings"], (settingsCtx) => {
25
+ settingsCtx.settings.register(NAMESPACE, CompletionNotifySettingsSchema);
26
+ });
27
+ }
28
+ //#endregion
29
+ export { COMPLETION_NOTIFY_ENABLED_FIELD, COMPLETION_NOTIFY_SETTINGS_NAMESPACE, DEFAULT_COMPLETION_NOTIFY_ENABLED, apply };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Completion-notify preference row: an enable switch for desktop completion
3
+ * notifications, registered into the General section item slot. The row is
4
+ * a simple checkbox pair (title + description) whose state mirrors the
5
+ * settings-scope snapshot. Styles are inline (a standalone plugin avoids the
6
+ * harness's CSS Modules pipeline).
7
+ */
8
+ import type { PropsLocale, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
9
+ import type { createCompletionNotifyRowStore } from './settings-store.js';
10
+ /** Injected business face: the preference write (t rides the standard locale seat). */
11
+ export interface CompletionNotifyRowInjected {
12
+ /** Persist the desktop-notification enabled flag. */
13
+ setEnabled: (enabled: boolean) => void;
14
+ }
15
+ /** Full component props: runtime share + store share + locale seat + injected face. */
16
+ export type CompletionNotifyRowComponentProps = PropsRuntime<'settings.general.item'> & PropsStore<ReturnType<typeof createCompletionNotifyRowStore>> & PropsLocale<'settings.completionNotify'> & CompletionNotifyRowInjected;
17
+ /**
18
+ * Render the completion-notify enable switch row.
19
+ * @param props - composed slot props.
20
+ * @returns the row element tree.
21
+ */
22
+ export declare function CompletionNotifyRow({ t, setEnabled, useStore }: CompletionNotifyRowComponentProps): import("react").JSX.Element;
23
+ //# sourceMappingURL=CompletionNotifyRow.d.ts.map
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Completion-notify surface plugin, browser half: raises a system desktop
3
+ * notification (browser Notification API) when a session completes while it
4
+ * is not the one the user is looking at. For a NON-selected session the
5
+ * completion marker already exists on the sessions list snapshot
6
+ * (`SessionListState.byId[id].completed`, armed by the runtime's
7
+ * `syncCompletedNotifications` for running→idle edges of non-selected
8
+ * sessions). For the SELECTED session — which the runtime never marks
9
+ * completed because the user is presumed to be watching it — this plugin
10
+ * detects the running→idle edge itself and raises the notification only
11
+ * while the page is in the background (`document.hidden`), i.e. when the
12
+ * user has switched away and would otherwise miss the completion.
13
+ */
14
+ import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
15
+ import { type CompletionNotifyKey } from './locales.js';
16
+ export { CompletionNotifyRow } from './CompletionNotifyRow.js';
17
+ export type { CompletionNotifyRowInjected } from './CompletionNotifyRow.js';
18
+ export type { CompletionNotifyKey } from './locales.js';
19
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
20
+ interface LocaleNamespaceMap {
21
+ /** The completion-notify settings row and notification copy. */
22
+ 'settings.completionNotify': CompletionNotifyKey;
23
+ }
24
+ }
25
+ /** Required services: the settings row slot, sessions list, locale, and the settings scope. */
26
+ export declare const inject: string[];
27
+ /**
28
+ * The browser Notification surface narrowed to what this plugin uses, so
29
+ * tests can stub it and non-browser environments degrade silently.
30
+ */
31
+ export interface NotificationApi {
32
+ readonly permission: NotificationPermission;
33
+ requestPermission(): Promise<NotificationPermission>;
34
+ create(title: string, options?: {
35
+ body?: string;
36
+ }): unknown;
37
+ }
38
+ /**
39
+ * Resolve the browser Notification constructor, or undefined where absent
40
+ * (old browsers, restricted environments, non-browser test hosts). The
41
+ * returned surface adapts the constructor: `create` wraps `new
42
+ * Notification(title, options)`, because the native constructor carries no
43
+ * `create` method.
44
+ * @returns the Notification surface when available.
45
+ */
46
+ export declare function browserNotification(): NotificationApi | undefined;
47
+ /**
48
+ * Raise one completion notification through the browser Notification API.
49
+ * Permission must already be granted — requesting it here would run in a
50
+ * non-user-gesture context (a backgrounded completion), which browsers
51
+ * silently ignore; the first interaction and the settings switch request
52
+ * permission instead. Any missing grant stays silent.
53
+ * @param api - the browser Notification surface.
54
+ * @param title - the notification title.
55
+ * @param body - the notification body.
56
+ */
57
+ export declare function notifyCompletion(api: NotificationApi, title: string, body: string): Promise<void>;
58
+ /**
59
+ * Request the browser notification permission, meant to run inside a user
60
+ * gesture (the settings switch's click, or the first interaction). Browsers
61
+ * require transient user activation for `Notification.requestPermission` and
62
+ * silently ignore it otherwise.
63
+ * @param api - the browser Notification surface.
64
+ * @returns whether the permission is granted afterwards.
65
+ */
66
+ export declare function requestNotificationPermission(api: NotificationApi): Promise<boolean>;
67
+ /**
68
+ * Whether the page is currently in the background (hidden tab or minimized
69
+ * window). The selected session's completion is only notified while this is
70
+ * true — when the page is visible the user is watching the completion.
71
+ * @returns whether the document is hidden.
72
+ */
73
+ export declare function pageIsHidden(): boolean;
74
+ /**
75
+ * Client plugin body: subscribe to the sessions list snapshot and raise a
76
+ * desktop notification when a session completes — the non-selected session
77
+ * via its runtime `completed` marker, the selected session via its
78
+ * running→idle edge while the page is hidden — plus register the
79
+ * General-settings enable switch.
80
+ * @param ctx - client root context.
81
+ */
82
+ export declare function apply(ctx: ClientContext): void;
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ /** `settings.completionNotify` namespace dictionaries (the settings row's and notification's copy). */
2
+ /** Simplified Chinese dictionary (the key-set source of truth). */
3
+ export declare const zh: {
4
+ 'row.title': string;
5
+ 'row.desc': string;
6
+ 'notification.title': string;
7
+ 'notification.body': string;
8
+ };
9
+ /** The settings.completionNotify namespace key union. */
10
+ export type CompletionNotifyKey = keyof typeof zh;
11
+ /** English dictionary, checked complete against the zh key set. */
12
+ export declare const en: {
13
+ 'row.title': string;
14
+ 'row.desc': string;
15
+ 'notification.title': string;
16
+ 'notification.body': string;
17
+ };
18
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Completion-notify settings row slot store: a mirror of the settings-scope
3
+ * snapshot. The plugin's apply-world change listener is the only writer; the
4
+ * row component reads via props.useStore.
5
+ *
6
+ * The store is a local implementation of the ui-slots StoreHandle contract
7
+ * instead of the harness runtime's `defineStore` engine: the standalone
8
+ * plugin cannot import that engine (it is not part of the published npm
9
+ * client bundle), so this module provides the minimal snapshot-source +
10
+ * baked-actions shape the render machinery consumes.
11
+ */
12
+ import type { StoreHandle } from '@deepseek-ai/dsh-client-ui-slots';
13
+ /** Store state mirrored from the settings scope snapshot. */
14
+ export interface CompletionNotifyRowState {
15
+ /** Whether desktop completion notifications are enabled. */
16
+ enabled: boolean;
17
+ /** Namespace revision; -1 until first sync so revision 0 lands as a change. */
18
+ revision: number;
19
+ }
20
+ /** Declared action shape giving the exported factory a stable return type. */
21
+ type CompletionNotifyRowActions = {
22
+ sync: (draft: CompletionNotifyRowState, enabled: boolean, revision: number) => void;
23
+ };
24
+ /**
25
+ * Declares the completion-notify row state and write surface.
26
+ * @returns the store handle.
27
+ */
28
+ export declare function createCompletionNotifyRowStore(): StoreHandle<CompletionNotifyRowState, CompletionNotifyRowActions>;
29
+ export {};
30
+ //# sourceMappingURL=settings-store.d.ts.map
@@ -0,0 +1,16 @@
1
+ /** Completion-notify preferences stored in the Host user-settings document. */
2
+ import z from '@deepseek-ai/schemastery';
3
+ /** Settings namespace owned by the completion-notify plugin. */
4
+ export declare const COMPLETION_NOTIFY_SETTINGS_NAMESPACE = "ui-completion-notify";
5
+ /** Field carrying whether desktop completion notifications are enabled. */
6
+ export declare const COMPLETION_NOTIFY_ENABLED_FIELD = "enabled";
7
+ /** Default when the user-settings document has no override: notifications on. */
8
+ export declare const DEFAULT_COMPLETION_NOTIFY_ENABLED = true;
9
+ /** Durable completion-notify section shared by the Host schema and the browser scope. */
10
+ export interface CompletionNotifySettings {
11
+ /** Whether a non-selected session completion raises a desktop notification. */
12
+ enabled: boolean;
13
+ }
14
+ /** Durable completion-notify schema; also the wire envelope the browser scope validates against. */
15
+ export declare const CompletionNotifySettingsSchema: z<CompletionNotifySettings>;
16
+ //# sourceMappingURL=completion-notify-settings.d.ts.map
@@ -0,0 +1,11 @@
1
+ /** Host registration for the completion-notify preference. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ export { COMPLETION_NOTIFY_ENABLED_FIELD, COMPLETION_NOTIFY_SETTINGS_NAMESPACE, DEFAULT_COMPLETION_NOTIFY_ENABLED, type CompletionNotifySettings, } from './completion-notify-settings.js';
4
+ /**
5
+ * Register the durable completion-notify section when the optional settings
6
+ * service is composed. The browser half reads and writes the enabled flag
7
+ * through the settings scope bound to this namespace.
8
+ * @param ctx - Host context that may acquire the settings service.
9
+ */
10
+ export declare function apply(ctx: Context): void;
11
+ //# sourceMappingURL=index.d.ts.map
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "dsh-plugin-completion-notify",
3
+ "description": "Desktop completion notifications for dsh web: a system notification when a session finishes while you are not looking at it",
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./lib/types/index.d.ts",
10
+ "default": "./lib/index.js"
11
+ },
12
+ "./client": {
13
+ "types": "./lib/types/client/index.d.ts",
14
+ "default": "./lib/client.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "dsh": {
19
+ "client": {
20
+ "inject": [
21
+ "@deepseek-ai/dsh-client-locale",
22
+ "@deepseek-ai/dsh-client-runtime",
23
+ "@deepseek-ai/dsh-client-ui-settings"
24
+ ],
25
+ "platform": "web"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "build": "tsc -p tsconfig.json && node scripts/build-client.mjs",
30
+ "bundle": "node scripts/build-client.mjs",
31
+ "watch": "node scripts/build-client.mjs --watch"
32
+ },
33
+ "peerDependencies": {
34
+ "@deepseek-ai/cordis": "^4.0.1",
35
+ "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
36
+ "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
37
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
38
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
39
+ "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
40
+ "@deepseek-ai/schemastery": "^3.18.1",
41
+ "react": "^18.2.0"
42
+ },
43
+ "devDependencies": {
44
+ "@deepseek-ai/cordis": "^4.0.1",
45
+ "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
46
+ "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
47
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
48
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
49
+ "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
50
+ "@deepseek-ai/schemastery": "^3.18.1",
51
+ "@types/node": "^22.20.1",
52
+ "@types/react": "~18.3.1",
53
+ "tsdown": "^0.22.2",
54
+ "typescript": "^6.0.3"
55
+ },
56
+ "files": [
57
+ "lib/index.js",
58
+ "lib/client.js",
59
+ "lib/types/**/*.d.ts"
60
+ ],
61
+ "keywords": [
62
+ "dsh-plugin",
63
+ "deepseek-harness",
64
+ "notification",
65
+ "desktop"
66
+ ]
67
+ }