dsh-mishu 0.6.2 → 0.7.2
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 +22 -6
- package/lib/client.js +683 -380
- package/lib/core/channels.js +142 -0
- package/lib/core/index.js +2 -0
- package/lib/core/notify.js +198 -0
- package/lib/dsh/api.js +47 -1
- package/lib/dsh/plugin.js +4 -0
- package/lib/dsh/runtime.js +39 -1
- package/lib/types/core/channels.d.ts +61 -0
- package/lib/types/core/index.d.ts +2 -0
- package/lib/types/core/notify.d.ts +97 -0
- package/lib/types/dsh/runtime.d.ts +10 -1
- package/package.json +1 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reaching you without you opening the board: a daily brief, urgent items
|
|
3
|
+
* as they come, and quiet hours.
|
|
4
|
+
*
|
|
5
|
+
* Urgent means someone is waiting on you or it is due today:
|
|
6
|
+
* - things you told it: due today or overdue
|
|
7
|
+
* - GitHub: a review requested, a mention, an assignment
|
|
8
|
+
* - mail: a meeting invitation
|
|
9
|
+
* Everything else waits for the daily brief. Each urgent item is sent once
|
|
10
|
+
* (again only when it changes reason or due day); turning reminders on does
|
|
11
|
+
* not send what was already on the board. During quiet hours nothing is
|
|
12
|
+
* sent; what came up is sent when they end.
|
|
13
|
+
*
|
|
14
|
+
* Times are read in the time zone your browser reported, so a server
|
|
15
|
+
* running on UTC still sends the brief at your morning.
|
|
16
|
+
*/
|
|
17
|
+
import type { BoardData } from './board.ts';
|
|
18
|
+
import { type Bi, type Lang } from './i18n.ts';
|
|
19
|
+
import type { Matter, MishuStore } from './store.ts';
|
|
20
|
+
export interface NotifySettings {
|
|
21
|
+
brief: {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
time: string;
|
|
24
|
+
};
|
|
25
|
+
urgent: boolean;
|
|
26
|
+
quiet: {
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
};
|
|
31
|
+
/** IANA zone from your browser; empty: this computer's own. */
|
|
32
|
+
timeZone: string;
|
|
33
|
+
channels: {
|
|
34
|
+
desktop: boolean;
|
|
35
|
+
feishu: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare const DEFAULT_NOTIFY: NotifySettings;
|
|
39
|
+
export declare const URGENT_REASONS: string[];
|
|
40
|
+
export type ChannelId = keyof NotifySettings['channels'];
|
|
41
|
+
export interface Message {
|
|
42
|
+
kind: 'brief' | 'urgent' | 'test';
|
|
43
|
+
title: string;
|
|
44
|
+
/** One or two lines, for a system notification. */
|
|
45
|
+
body: string;
|
|
46
|
+
/** The whole message, for a chat. */
|
|
47
|
+
text: string;
|
|
48
|
+
}
|
|
49
|
+
export interface Channel {
|
|
50
|
+
id: ChannelId;
|
|
51
|
+
status(): Promise<{
|
|
52
|
+
available: true;
|
|
53
|
+
} | {
|
|
54
|
+
available: false;
|
|
55
|
+
why: Bi;
|
|
56
|
+
}>;
|
|
57
|
+
send(message: Message): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
export interface NotifyReport {
|
|
60
|
+
at: number;
|
|
61
|
+
kind: Message['kind'];
|
|
62
|
+
count: number;
|
|
63
|
+
results: Array<{
|
|
64
|
+
channel: ChannelId;
|
|
65
|
+
ok: boolean;
|
|
66
|
+
error?: string;
|
|
67
|
+
}>;
|
|
68
|
+
}
|
|
69
|
+
export declare const NOTIFY_REPORT_KEY = "notify.last";
|
|
70
|
+
export declare function notifySettings(store: MishuStore): NotifySettings;
|
|
71
|
+
/** Check what the page sent and keep it; throws a sentence a person can act on. */
|
|
72
|
+
export declare function saveNotifySettings(store: MishuStore, input: Partial<NotifySettings>, now: number): NotifySettings;
|
|
73
|
+
/** The day and minute of the day in a time zone ('' = this computer's). */
|
|
74
|
+
export declare function localClock(now: number, timeZone: string): {
|
|
75
|
+
day: string;
|
|
76
|
+
minutes: number;
|
|
77
|
+
};
|
|
78
|
+
/** Whether a minute of the day is inside quiet hours, which may run past midnight. */
|
|
79
|
+
export declare function inQuiet(minutes: number, quiet: NotifySettings['quiet']): boolean;
|
|
80
|
+
/** Open items someone is waiting on, or due today. */
|
|
81
|
+
export declare function urgentMatters(store: MishuStore, today: string): Matter[];
|
|
82
|
+
/** The brief, from what the board shows; `undefined` when there is nothing to tell. */
|
|
83
|
+
export declare function briefMessage(board: BoardData, lang: Lang): Message | undefined;
|
|
84
|
+
export declare function testMessage(lang: Lang): Message;
|
|
85
|
+
/** Send to every enabled channel; one failing does not stop the others. */
|
|
86
|
+
export declare function deliver(store: MishuStore, channels: Channel[], message: Message, count: number, now: number): Promise<NotifyReport>;
|
|
87
|
+
/**
|
|
88
|
+
* One look at the clock: send what is due. Called every minute and after
|
|
89
|
+
* each sync. `channels` are the enabled ones; `board` builds the brief.
|
|
90
|
+
*/
|
|
91
|
+
export declare function notifyTick(options: {
|
|
92
|
+
store: MishuStore;
|
|
93
|
+
now: number;
|
|
94
|
+
lang: Lang;
|
|
95
|
+
channels: Channel[];
|
|
96
|
+
board: () => BoardData;
|
|
97
|
+
}): Promise<NotifyReport[]>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* what you set on the settings page on top), the keychain, and one sync of
|
|
5
5
|
* every source at a time.
|
|
6
6
|
*/
|
|
7
|
-
import { GithubDeviceLogin, type Defaults, type Lang, type MailAccount, type MailFetcher, type MailSyncReport, type MishuStore, type RestartPlan, type RestartStarted, type SecretStore, type TokenResult } from '../core/index.ts';
|
|
7
|
+
import { GithubDeviceLogin, type Defaults, type Lang, type MailAccount, type MailFetcher, type MailSyncReport, type MishuStore, type Channel, type ChannelId, type NotifyReport, type RestartPlan, type RestartStarted, type SecretStore, type TokenResult } from '../core/index.ts';
|
|
8
8
|
import type { MishuConfig } from './config.ts';
|
|
9
9
|
interface Logger {
|
|
10
10
|
info(message: string): void;
|
|
@@ -17,6 +17,9 @@ export declare class Runtime {
|
|
|
17
17
|
readonly fetcher: MailFetcher;
|
|
18
18
|
private readonly logger;
|
|
19
19
|
private syncing;
|
|
20
|
+
/** Where reminders can go; tests swap them for recorders. */
|
|
21
|
+
channels: Record<ChannelId, Channel>;
|
|
22
|
+
private notifying;
|
|
20
23
|
/** "Sign in with GitHub" in progress, if any; tests swap it to replay GitHub. */
|
|
21
24
|
githubLogin: GithubDeviceLogin;
|
|
22
25
|
/** How DSH restarts; tests swap it so they never restart anything. */
|
|
@@ -41,6 +44,12 @@ export declare class Runtime {
|
|
|
41
44
|
private syncGithubNow;
|
|
42
45
|
/** One account; the result is also kept as its last report. */
|
|
43
46
|
syncMailAccount(account: MailAccount): Promise<MailSyncReport | undefined>;
|
|
47
|
+
/** The channels that are turned on and work on this computer. */
|
|
48
|
+
activeChannels(): Promise<Channel[]>;
|
|
49
|
+
/** The board as the brief describes it. */
|
|
50
|
+
board(now: number, lang?: Lang): import("../core/board.ts").BoardData;
|
|
51
|
+
/** Send what is due now: urgent items, the daily brief. One at a time. */
|
|
52
|
+
notify(now?: number): Promise<NotifyReport[]>;
|
|
44
53
|
/** Every source once; concurrent callers share the sync in flight. */
|
|
45
54
|
syncAll(): Promise<void>;
|
|
46
55
|
/** Resolves when the sync in flight (if any) is done. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mishu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "DSH secretary (小秘书) for DeepSeek Harness (dsh): watches GitHub notifications and the dated things you tell it (bills, renewals, documents, birthdays), closes what is already resolved, and keeps a short list of what actually needs you. Bilingual (中文 / English), macOS / Windows / Linux. · DSH 小秘书:提醒、通知、待办、消息、收件箱、秘书。GitHub 通知按当前状态分诊,交代一句就记下到期和周期事项。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|