@deepseek-ai/dsh-client-ui-schedule 0.1.7-alpha.2 → 0.1.7-rc.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.
Files changed (42) hide show
  1. package/README.i18n.yaml +39 -5
  2. package/README.md +36 -39
  3. package/README.zh.md +42 -45
  4. package/lib/client.js +6735 -171
  5. package/lib/index.js +1 -1
  6. package/lib/types/client/CalendarIcon.d.ts +17 -0
  7. package/lib/types/client/CatalogFeedback.d.ts +28 -0
  8. package/lib/types/client/ClockPicker.d.ts +33 -0
  9. package/lib/types/client/DatePicker.d.ts +27 -0
  10. package/lib/types/client/DeleteToast.d.ts +47 -0
  11. package/lib/types/client/DeliveryHistory.d.ts +29 -0
  12. package/lib/types/client/PickerPopover.d.ts +27 -0
  13. package/lib/types/client/ScheduleCatalogAction.d.ts +12 -13
  14. package/lib/types/client/ScheduleCreateCard.d.ts +37 -0
  15. package/lib/types/client/ScheduleTaskTab.d.ts +36 -0
  16. package/lib/types/client/ScheduleTaskTabTitle.d.ts +21 -0
  17. package/lib/types/client/ScheduleTurnCard.d.ts +25 -0
  18. package/lib/types/client/SessionScheduleHover.d.ts +34 -0
  19. package/lib/types/client/SessionScheduleMark.d.ts +31 -0
  20. package/lib/types/client/TaskDetail.d.ts +158 -0
  21. package/lib/types/client/TaskManagerIcon.d.ts +11 -0
  22. package/lib/types/client/TaskManagerPage.d.ts +25 -0
  23. package/lib/types/client/TaskMenu.d.ts +76 -0
  24. package/lib/types/client/catalog-source.d.ts +91 -0
  25. package/lib/types/client/definition.d.ts +40 -0
  26. package/lib/types/client/frequency-locales.d.ts +71 -0
  27. package/lib/types/client/index.d.ts +40 -4
  28. package/lib/types/client/locales.d.ts +59 -8
  29. package/lib/types/client/recent-time-zones.d.ts +15 -0
  30. package/lib/types/client/relative-clock.d.ts +26 -0
  31. package/lib/types/client/schedule-create-card.d.ts +46 -0
  32. package/lib/types/client/schedule-format.d.ts +177 -0
  33. package/lib/types/client/schedule-turn.d.ts +63 -0
  34. package/lib/types/client/session-link.d.ts +41 -0
  35. package/lib/types/client/session-schedule-state.d.ts +62 -0
  36. package/lib/types/client/task-cron.d.ts +116 -0
  37. package/lib/types/client/task-manager-locales.d.ts +195 -0
  38. package/lib/types/client/task-tab-bindings.d.ts +114 -0
  39. package/lib/types/client/task-tab-target.d.ts +31 -0
  40. package/lib/types/client/task-timing.d.ts +96 -0
  41. package/lib/types/index.d.ts +1 -1
  42. package/package.json +31 -12
@@ -0,0 +1,25 @@
1
+ import type { HostObservable, InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule/client';
3
+ import type { CatalogSnapshot } from './catalog-source.ts';
4
+ import { type TaskDetailInjected } from './TaskDetail.tsx';
5
+ /** Injected catalog and task actions for the management page. */
6
+ export interface TaskManagerInjected extends TaskDetailInjected {
7
+ /** Host task catalog with its query and deletion state. */
8
+ readonly hooks: {
9
+ readonly catalog: HostObservable<CatalogSnapshot<ScheduleCatalogEntry>>;
10
+ };
11
+ /**
12
+ * Start a new Session, where a reminder is created by asking the model to
13
+ * schedule it. The page deliberately has no creation form of its own.
14
+ */
15
+ readonly onNewTask: () => void;
16
+ }
17
+ /** Root-scoped task catalog props derived from the framework and injected actions. */
18
+ export type TaskManagerPageProps = PropsRuntime<'main'> & InjectFace<TaskManagerInjected> & PropsLocale<'schedule.manager'>;
19
+ /**
20
+ * Render retained tasks with authoritative deletion and timing-only edits.
21
+ * @param props - framework catalog snapshot, localized copy, and action callbacks.
22
+ * @returns the searchable task list beside the selected task's detail.
23
+ */
24
+ export declare function TaskManagerPage(props: TaskManagerPageProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=TaskManagerPage.d.ts.map
@@ -0,0 +1,76 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Selectable row of a {@link TaskMenu}. */
3
+ export interface TaskMenuItem {
4
+ /** Identifier `onSelect` receives when the row is activated. */
5
+ id: string;
6
+ /** Visible row label. */
7
+ label: ReactNode;
8
+ /** Whether the row cannot be activated, and is not a step of the arrow walk. */
9
+ disabled?: boolean;
10
+ /** Leading icon. */
11
+ icon?: ReactNode;
12
+ /** Destructive row: error-colored text and icon, and the danger hover fill. */
13
+ danger?: boolean;
14
+ }
15
+ /** Hairline between item groups (not selectable). */
16
+ export interface TaskMenuSeparator {
17
+ type: 'separator';
18
+ id: string;
19
+ }
20
+ /** Non-interactive heading row above a group of items. */
21
+ export interface TaskMenuLabel {
22
+ type: 'label';
23
+ id: string;
24
+ text: string;
25
+ }
26
+ /** One TaskMenu entry: a row, a separator, or a heading label. */
27
+ export type TaskMenuEntry = TaskMenuItem | TaskMenuSeparator | TaskMenuLabel;
28
+ /** Inputs of {@link TaskMenu}. */
29
+ export interface TaskMenuProps {
30
+ /** Whether the list is showing (owner-controlled). */
31
+ open: boolean;
32
+ /** The trigger element, rendered in place. */
33
+ anchor: ReactNode;
34
+ /** Selectable rows and optional separators or heading labels (default none). */
35
+ items?: readonly TaskMenuEntry[];
36
+ /** Row shown as selected, marked with a trailing check. */
37
+ selectedId?: string | undefined;
38
+ /** Row activation callback (not called for disabled rows). */
39
+ onSelect: (id: string) => void;
40
+ /** Invoked on an outside pointer press, Escape, or a window blur that moved focus into an iframe. */
41
+ onClose: () => void;
42
+ /** List alignment against the anchor (default 'start'). */
43
+ align?: 'start' | 'end';
44
+ /** Render the list into document.body, fixed-positioned from the anchor rect. */
45
+ portal?: boolean;
46
+ /** Owner content pinned above the scrolling rows. */
47
+ header?: ReactNode;
48
+ /** Extra class on the anchor wrapper span. */
49
+ className?: string | undefined;
50
+ /** Extra class on the dropdown card itself; the only style hook that reaches a portaled list. */
51
+ listClassName?: string | undefined;
52
+ }
53
+ /**
54
+ * Render an anchored dropdown menu. While the list is open, Tab settles the
55
+ * focused row — from the trigger, Tab enters the list instead — Escape and
56
+ * Shift+Tab close it and return focus to the anchor's first enabled button, and
57
+ * selecting a row does the same.
58
+ * @param props.open - whether the list is showing (owner-controlled).
59
+ * @param props.anchor - the trigger element, rendered in place.
60
+ * @param props.items - selectable rows and optional separators or heading labels.
61
+ * @param props.selectedId - row shown as selected.
62
+ * @param props.onSelect - row activation callback, not called for disabled rows.
63
+ * @param props.onClose - invoked on an outside pointer press, Escape, or a
64
+ * window blur that moved focus into a cross-origin iframe.
65
+ * @param props.align - list alignment against the anchor (default 'start').
66
+ * @param props.portal - render the list into document.body, fixed-positioned
67
+ * from the anchor rect (follows scroll and resize while open).
68
+ * @param props.header - owner content pinned above the scrolling rows; a control
69
+ * it marks `data-menu-field` takes the keyboard once the list is placed, which
70
+ * is the frame a portaled list becomes focusable in.
71
+ * @param props.className - extra class on the anchor wrapper span.
72
+ * @param props.listClassName - extra class on the dropdown card itself.
73
+ * @returns the anchor wrapper with the conditional list.
74
+ */
75
+ export declare function TaskMenu({ open, anchor, items, selectedId, onSelect, onClose, align, portal, header, className, listClassName }: TaskMenuProps): import("react").JSX.Element;
76
+ //# sourceMappingURL=TaskMenu.d.ts.map
@@ -0,0 +1,91 @@
1
+ /** Authoritative Schedule queries and deletion for Session and Host catalogs. */
2
+ import type { RemoteResult } from '@deepseek-ai/dsh-api-remotes/client';
3
+ import type { HostObservable } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import type { ScheduleDeleteResult, ScheduleId, ScheduleRecord } from '@deepseek-ai/dsh-schedule/client';
5
+ /** How one deletion settled; the wiring reports it as a transient notice. */
6
+ export type CatalogDeleteOutcome = 'deleted' | 'failed' | 'pending';
7
+ /** Query and mutation state exposed to a catalog component. */
8
+ export interface CatalogSnapshot<Item extends {
9
+ readonly id: ScheduleId;
10
+ } = ScheduleRecord> {
11
+ readonly records: readonly Item[];
12
+ readonly status: 'loading' | 'ready' | 'error';
13
+ readonly deleting: readonly ScheduleId[];
14
+ /**
15
+ * Whether an authoritative list read has ever succeeded.
16
+ *
17
+ * A consumer may read `records` as the answer only once this holds: the first
18
+ * snapshot reports `loading` with no records, and a later refresh republishes
19
+ * `loading` over the records of the last successful read, so `status` alone
20
+ * cannot separate a first read from a refresh. A failed read leaves it alone.
21
+ */
22
+ readonly settled: boolean;
23
+ /**
24
+ * Count of reads this source has been asked for - by a consumer, and by its own
25
+ * `schedule/changed`, connection-reset, and post-deletion acknowledgement paths.
26
+ *
27
+ * A consumer that appears with a record of its own — a created-task card —
28
+ * records this at mount and asks for a read: an absence in the retained records
29
+ * states a deletion only once a read requested after that point has succeeded
30
+ * (see `readSettled`), because an earlier read may predate the record. A request
31
+ * shares the read in flight only when that read was requested after the ordinal
32
+ * the caller names, so this counts the requests rather than the `list()` calls.
33
+ * Counters rather than timestamps, so the answer never compares the browser's
34
+ * clock with the Host's.
35
+ */
36
+ readonly readRequest: number;
37
+ /**
38
+ * Ordinal of the read whose result the current records came from, and 0 before
39
+ * any read succeeded. A failed read leaves it alone.
40
+ */
41
+ readonly readSettled: number;
42
+ }
43
+ /** Remote operations and invalidations scoped by the registering entry. */
44
+ export interface CatalogDependencies<Item extends {
45
+ readonly id: ScheduleId;
46
+ } = ScheduleRecord> {
47
+ readonly list: () => Promise<RemoteResult<Item[]>>;
48
+ readonly remove: (id: ScheduleId) => Promise<RemoteResult<ScheduleDeleteResult>>;
49
+ readonly subscribeChanged: (listener: () => void) => () => void;
50
+ readonly subscribeReset: (listener: () => void) => () => void;
51
+ }
52
+ /** Props injected through a catalog slot. */
53
+ export interface CatalogInjected<Item extends {
54
+ readonly id: ScheduleId;
55
+ } = ScheduleRecord> {
56
+ readonly hooks: {
57
+ readonly catalog: HostObservable<CatalogSnapshot<Item>>;
58
+ };
59
+ /**
60
+ * Delete one reminder and refresh after the Remote acknowledgement.
61
+ * @param id - reminder shown in this catalog.
62
+ * @returns 'deleted' after the acknowledged deletion's refreshed query,
63
+ * 'failed' when the deletion was not confirmed, and 'pending' when a deletion
64
+ * of the same reminder was already in flight.
65
+ */
66
+ readonly onDelete: (id: ScheduleId) => Promise<CatalogDeleteOutcome>;
67
+ /**
68
+ * Reload the catalog: after a query failure or an acknowledged timing update,
69
+ * and from a created-task card that needs a read newer than its own result.
70
+ *
71
+ * Requests made in one commit share a single read, so several cards mounting
72
+ * together still send one. A caller that has already observed a request passes
73
+ * that ordinal as `since`, and only a read requested later than it is shared - so
74
+ * a read issued before the caller appeared cannot answer for it, and a caller
75
+ * that has seen the newest request gets a fresh read.
76
+ * @param since - request ordinal the caller last observed, 0 to share any read in flight.
77
+ * @returns Resolution after publishing the read result; failures remain in catalog state.
78
+ */
79
+ readonly onRetry: (since?: number) => Promise<void>;
80
+ }
81
+ /**
82
+ * Create a catalog whose Remote subscriptions follow its framework subscribers.
83
+ * Mutations retain visible rows until an authoritative list read succeeds, and
84
+ * each deletion resolves with its own outcome for the caller to report.
85
+ * @param deps - Remote calls and invalidation subscriptions.
86
+ * @returns observable catalog and component callbacks.
87
+ */
88
+ export declare function createCatalogSource<Item extends {
89
+ readonly id: ScheduleId;
90
+ } = ScheduleRecord>(deps: CatalogDependencies<Item>): CatalogInjected<Item>;
91
+ //# sourceMappingURL=catalog-source.d.ts.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Stage one of the task tab type's registration: what it IS.
3
+ *
4
+ * A page type: it recognizes no resource address, because its content is one
5
+ * task named by navigation parameters rather than by an address, and is opened
6
+ * by kind. `builtin` is the ordinary band for a type shipped with the product.
7
+ */
8
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-locale/client';
9
+ import type { SidebarRightTabDefinition, SidebarRightTabParamsMap, SidebarRightNavigationParams } from '@deepseek-ai/dsh-client-ui-sidebar-right/client';
10
+ import type { ScheduleId } from '@deepseek-ai/dsh-schedule/client';
11
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
12
+ /** This implementation's identity in the tab system: the key its body and title register under. */
13
+ export declare const SCHEDULE_TASK_ID = "@deepseek-ai/dsh-client-ui-schedule/task";
14
+ /** The tab kind this package owns. */
15
+ export declare const SCHEDULE_TASK_KIND = "scheduleTask";
16
+ declare module '@deepseek-ai/dsh-client-ui-sidebar-right/client' {
17
+ interface SidebarRightTabParamsMap {
18
+ /** One retained task, named by its original Session and its own identity. */
19
+ scheduleTask: {
20
+ sessionId: SessionId;
21
+ id: ScheduleId;
22
+ };
23
+ }
24
+ }
25
+ /**
26
+ * The task type's registry definition.
27
+ *
28
+ * The chip text captured here is a constant because an open names only a kind;
29
+ * `ScheduleTaskTabTitle` replaces it with the shown task's stored title.
30
+ * @param t - namespace-bound translate, read fresh on every title call.
31
+ * @returns the definition to register.
32
+ */
33
+ export declare function scheduleTaskDefinition(t: TranslateNS<'schedule.manager'>): SidebarRightTabDefinition;
34
+ /**
35
+ * Narrow one tab's navigation parameters to this type's task binding.
36
+ * @param params - the tab record's navigation parameters.
37
+ * @returns the Session and task the tab shows, or undefined for another type's parameters.
38
+ */
39
+ export declare function scheduleTaskParams(params: SidebarRightNavigationParams): SidebarRightTabParamsMap['scheduleTask'] | undefined;
40
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Stored-rule and elapsed-duration copy shared by the `schedule.catalog` and
3
+ * `schedule.manager` namespaces.
4
+ *
5
+ * Both namespaces label the same stored rule kinds, describe cron rules with
6
+ * the same `cronPreview` sentence, and word the same relative durations, so
7
+ * their wording for those keys is one source here. The keys either namespace
8
+ * words differently — its one-shot label, its list states, and its own delete
9
+ * and timing copy — stay in that namespace's dictionary.
10
+ * @module
11
+ */
12
+ /** Simplified Chinese rule and duration copy, key-set source of truth. */
13
+ export declare const frequencyZh: {
14
+ readonly 'time.locale': "zh-CN";
15
+ readonly 'time.utcPrefix': "UTC";
16
+ readonly 'frequency.daily': "每天 {time}({timeZone})";
17
+ readonly 'frequency.dailyLocal': "每天 {time}";
18
+ readonly 'frequency.weekly': "每周{weekdays} {time}({timeZone})";
19
+ readonly 'frequency.weeklyLocal': "每周{weekdays} {time}";
20
+ readonly 'frequency.cron': "Cron {expression}({timeZone})";
21
+ readonly 'frequency.cronLocal': "Cron {expression}";
22
+ readonly 'frequency.cronRule': "{rule}({timeZone})";
23
+ readonly 'cron.list.join': "、";
24
+ readonly 'cron.part.join': " ";
25
+ readonly 'cron.weekday.name': "周{weekday}";
26
+ readonly 'cron.weekday.range': "{from}至{to}";
27
+ readonly 'cron.months': "({months})";
28
+ readonly 'cron.day.every': "每天{months}";
29
+ readonly 'cron.day.weekdays': "{weekdays}{months}";
30
+ readonly 'cron.day.monthDays': "每月 {days} 日{months}";
31
+ readonly 'cron.day.both': "每月 {days} 日或{weekdays}{months}";
32
+ readonly 'cron.day.bothStarred': "每月 {days} 日且{weekdays}{months}";
33
+ readonly 'cron.hours.range': "{from} 至 {to}";
34
+ readonly 'cron.hours.list': "{hours}";
35
+ readonly 'cron.time.everyMinute': "每分钟";
36
+ readonly 'cron.time.everyMinutes': "每 {step} 分钟";
37
+ readonly 'cron.time.joinedEveryMinute': "每分钟";
38
+ readonly 'cron.time.joinedEveryMinutes': "每 {step} 分钟";
39
+ readonly 'cron.time.everyHour': "每小时";
40
+ readonly 'cron.time.joinedEveryHour': "每小时";
41
+ readonly 'cron.time.everyNHours': "每 {count} 小时";
42
+ readonly 'cron.time.joinedEveryNHours': "每 {count} 小时";
43
+ readonly 'cron.time.hourlyAt': "每小时的第 {minutes} 分钟";
44
+ readonly 'cron.time.joinedHourlyAt': "每小时的第 {minutes} 分钟";
45
+ readonly 'cron.time.hoursEveryMinute': "{hours} 点的每分钟";
46
+ readonly 'cron.time.hoursEveryMinutes': "{hours} 点内每 {step} 分钟";
47
+ readonly 'cron.time.at': "{times}";
48
+ readonly 'cron.time.hoursAt': "{hours} 点的第 {minutes} 分钟";
49
+ readonly 'frequency.weekday.join': "、";
50
+ readonly 'frequency.weekday.1': "一";
51
+ readonly 'frequency.weekday.2': "二";
52
+ readonly 'frequency.weekday.3': "三";
53
+ readonly 'frequency.weekday.4': "四";
54
+ readonly 'frequency.weekday.5': "五";
55
+ readonly 'frequency.weekday.6': "六";
56
+ readonly 'frequency.weekday.7': "日";
57
+ readonly 'unit.day.one': "天";
58
+ readonly 'unit.day.other': "天";
59
+ readonly 'unit.hour.one': "小时";
60
+ readonly 'unit.hour.other': "小时";
61
+ readonly 'unit.minute.one': "分钟";
62
+ readonly 'unit.minute.other': "分钟";
63
+ readonly 'unit.second.one': "秒";
64
+ readonly 'unit.second.other': "秒";
65
+ readonly 'relative.now': "现在到期";
66
+ readonly 'relative.future': "{value}{unit}后";
67
+ readonly 'relative.overdue': "已逾期 {value}{unit}";
68
+ };
69
+ /** English rule and duration copy, key-identical to the Chinese source. */
70
+ export declare const frequencyEn: Record<keyof typeof frequencyZh, string>;
71
+ //# sourceMappingURL=frequency-locales.d.ts.map
@@ -1,14 +1,50 @@
1
- /** Browser half of the read-only Schedule catalog. */
1
+ /**
2
+ * Browser catalogs for retained Host tasks and the selected Session's active
3
+ * reminders, plus the right-Sidebar page that shows one task's detail.
4
+ *
5
+ * The page type reaches the Sidebar through its public path only: the
6
+ * definition into `ctx.sidebarRightTabs`, the body into the keyed
7
+ * `sidebar.right.pane.tab` seat, and the chip title into
8
+ * `sidebar.right.pane.tab.title`, both under the definition's `id`. Because the
9
+ * Sidebar persists a tab's layout record and not the parameters its opener
10
+ * passed, the page also owns a binding from each tab page to the task it last
11
+ * showed, which its body and chip read back after a reload. The Session
12
+ * header entry and the task tab share one Host catalog source, so opening or
13
+ * deleting from either view reads and refreshes the same records.
14
+ *
15
+ * The created task of a `schedule_create` call renders at Turn level: a Turn
16
+ * Definition publishes the settled result against its Turn, and ui-chat's
17
+ * `conversation.chat.turnTail` list seat renders the card beneath
18
+ * the closing prose, outside the collapsible Tool group, opening the same
19
+ * right-Sidebar detail the header entry opens. The call's Tool-group cell
20
+ * stays with ui-tool's generic keyed tool view, so this package registers no
21
+ * `tool.call.toolview` entry for the wire name.
22
+ *
23
+ * Two ambient surfaces read the ONE Host catalog the page owns: ui-workspace's
24
+ * `sidebar.session.row.leading` seat marks an idle row whose Session has an
25
+ * active task, and its `sidebar.session.row.hover` seat lists those tasks
26
+ * inside the row's hover card. Both project the same source, so N visible rows
27
+ * issue one query rather than one per row. The header entry keeps its own
28
+ * per-Session source.
29
+ */
2
30
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
3
31
  import { type ScheduleCatalogKey } from './locales.ts';
32
+ import { type TaskManagerKey } from './task-manager-locales.ts';
4
33
  declare module '@deepseek-ai/dsh-client-ui-slots' {
5
34
  interface LocaleNamespaceMap {
6
- /** Read-only active Schedule catalog copy. */
35
+ /** Active Schedule catalog copy. */
7
36
  'schedule.catalog': ScheduleCatalogKey;
37
+ /** Host task management page and task tab copy. */
38
+ 'schedule.manager': TaskManagerKey;
8
39
  }
9
40
  }
10
- /** Required services for locale registration and header-slot contribution. */
41
+ /** Required services for catalogs, ambient Session marks, the right Sidebar, Remote queries, and original-Session navigation. */
11
42
  export declare const inject: string[];
12
- /** Register the dictionaries and Session-header catalog action. */
43
+ /**
44
+ * Register the Host task page, the Session-header reminder catalog, the
45
+ * right-Sidebar page that shows one task's detail, and the transcript card of
46
+ * one created task.
47
+ * @param ctx - browser services used by these contributions.
48
+ */
13
49
  export declare function apply(ctx: ClientContext): void;
14
50
  //# sourceMappingURL=index.d.ts.map
@@ -1,15 +1,52 @@
1
- /** `schedule.catalog` namespace dictionaries. */
2
1
  /** Dictionary namespace owned by this plugin. */
3
2
  export declare const NS = "schedule.catalog";
4
3
  /** Simplified Chinese dictionary (the key-set source of truth). */
5
4
  export declare const zh: {
6
- readonly 'trigger.one': "{count} 个提醒";
7
- readonly 'trigger.other': "{count} 个提醒";
8
- readonly 'list.aria': "活动提醒";
9
- readonly 'status.scheduled': "等待中";
10
- readonly 'status.overdue': "已逾期";
11
- readonly 'frequency.once': "单次";
12
- readonly 'frequency.every': "{value}{unit}一次";
5
+ readonly 'mark.aria': "{count} 个自动化任务";
6
+ readonly 'hover.more': "另有 {count} 个任务";
7
+ readonly 'time.locale': "zh-CN";
8
+ readonly 'time.utcPrefix': "UTC";
9
+ readonly 'frequency.daily': "每天 {time}({timeZone})";
10
+ readonly 'frequency.dailyLocal': "每天 {time}";
11
+ readonly 'frequency.weekly': "每周{weekdays} {time}({timeZone})";
12
+ readonly 'frequency.weeklyLocal': "每周{weekdays} {time}";
13
+ readonly 'frequency.cron': "Cron {expression}({timeZone})";
14
+ readonly 'frequency.cronLocal': "Cron {expression}";
15
+ readonly 'frequency.cronRule': "{rule}({timeZone})";
16
+ readonly 'cron.list.join': "、";
17
+ readonly 'cron.part.join': " ";
18
+ readonly 'cron.weekday.name': "周{weekday}";
19
+ readonly 'cron.weekday.range': "{from}至{to}";
20
+ readonly 'cron.months': "({months})";
21
+ readonly 'cron.day.every': "每天{months}";
22
+ readonly 'cron.day.weekdays': "{weekdays}{months}";
23
+ readonly 'cron.day.monthDays': "每月 {days} 日{months}";
24
+ readonly 'cron.day.both': "每月 {days} 日或{weekdays}{months}";
25
+ readonly 'cron.day.bothStarred': "每月 {days} 日且{weekdays}{months}";
26
+ readonly 'cron.hours.range': "{from} 至 {to}";
27
+ readonly 'cron.hours.list': "{hours}";
28
+ readonly 'cron.time.everyMinute': "每分钟";
29
+ readonly 'cron.time.everyMinutes': "每 {step} 分钟";
30
+ readonly 'cron.time.joinedEveryMinute': "每分钟";
31
+ readonly 'cron.time.joinedEveryMinutes': "每 {step} 分钟";
32
+ readonly 'cron.time.everyHour': "每小时";
33
+ readonly 'cron.time.joinedEveryHour': "每小时";
34
+ readonly 'cron.time.everyNHours': "每 {count} 小时";
35
+ readonly 'cron.time.joinedEveryNHours': "每 {count} 小时";
36
+ readonly 'cron.time.hourlyAt': "每小时的第 {minutes} 分钟";
37
+ readonly 'cron.time.joinedHourlyAt': "每小时的第 {minutes} 分钟";
38
+ readonly 'cron.time.hoursEveryMinute': "{hours} 点的每分钟";
39
+ readonly 'cron.time.hoursEveryMinutes': "{hours} 点内每 {step} 分钟";
40
+ readonly 'cron.time.at': "{times}";
41
+ readonly 'cron.time.hoursAt': "{hours} 点的第 {minutes} 分钟";
42
+ readonly 'frequency.weekday.join': "、";
43
+ readonly 'frequency.weekday.1': "一";
44
+ readonly 'frequency.weekday.2': "二";
45
+ readonly 'frequency.weekday.3': "三";
46
+ readonly 'frequency.weekday.4': "四";
47
+ readonly 'frequency.weekday.5': "五";
48
+ readonly 'frequency.weekday.6': "六";
49
+ readonly 'frequency.weekday.7': "日";
13
50
  readonly 'unit.day.one': "天";
14
51
  readonly 'unit.day.other': "天";
15
52
  readonly 'unit.hour.one': "小时";
@@ -21,6 +58,20 @@ export declare const zh: {
21
58
  readonly 'relative.now': "现在到期";
22
59
  readonly 'relative.future': "{value}{unit}后";
23
60
  readonly 'relative.overdue': "已逾期 {value}{unit}";
61
+ readonly 'trigger.label': "提醒";
62
+ readonly 'list.loading': "正在加载提醒…";
63
+ readonly 'list.error': "无法加载提醒。";
64
+ readonly 'list.retry': "重试";
65
+ readonly 'delete.action': "删除";
66
+ readonly 'delete.pending': "正在删除…";
67
+ readonly 'delete.label': "删除提醒:{title}";
68
+ readonly 'list.open': "打开提醒详情:{title}";
69
+ readonly 'trigger.one': "{count} 个提醒";
70
+ readonly 'trigger.other': "{count} 个提醒";
71
+ readonly 'list.aria': "活动提醒";
72
+ readonly 'list.nextRun': "下次运行";
73
+ readonly 'frequency.once': "单次";
74
+ readonly 'frequency.every': "{value}{unit}一次";
24
75
  };
25
76
  /** English dictionary, key-identical to the Chinese source of truth. */
26
77
  export declare const en: Record<ScheduleCatalogKey, string>;
@@ -0,0 +1,15 @@
1
+ /** Browser-local recently selected IANA time zones. */
2
+ /**
3
+ * Load up to five recent zones, or the system-zone/UTC first-run seed.
4
+ * @param system - the host's current IANA zone.
5
+ * @returns recent IANA zones in most-recent-first order.
6
+ */
7
+ export declare function loadRecentTimeZones(system: string): readonly string[];
8
+ /**
9
+ * Promote one exact IANA id and persist the bounded list when storage is available.
10
+ * @param recent - current most-recent-first IANA zones.
11
+ * @param zone - exact IANA zone to promote.
12
+ * @returns the updated bounded most-recent-first list.
13
+ */
14
+ export declare function rememberTimeZone(recent: readonly string[], zone: string): readonly string[];
15
+ //# sourceMappingURL=recent-time-zones.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Refresh period for relative-time text.
3
+ *
4
+ * The text names whole seconds, minutes, hours, or days, so a half-minute
5
+ * period keeps it correct to its own granularity without re-rendering a mounted
6
+ * page on every frame.
7
+ */
8
+ export declare const RELATIVE_CLOCK_PERIOD_MS = 30000;
9
+ /**
10
+ * Current epoch milliseconds, re-sampled on a fixed period.
11
+ *
12
+ * A relative duration is read against the moment it renders, not against the
13
+ * moment its component mounted: a page left open across a delivery would keep
14
+ * showing the time until the previous target.
15
+ *
16
+ * This is the shared clock of the mounted task page and its detail, the two
17
+ * surfaces that sit side by side and must not disagree about how long remains.
18
+ * Two other surfaces keep their own beat: the Session-header catalog reads
19
+ * `Date.now()` and then a one-second interval while its popover is open, and the
20
+ * Sidebar Session-row hover card samples `Date.now()` once per mount, because
21
+ * that preview must not drift while the pointer rests on it.
22
+ * @param periodMs - refresh period; defaults to {@link RELATIVE_CLOCK_PERIOD_MS}.
23
+ * @returns epoch milliseconds, updated once per period.
24
+ */
25
+ export declare function useRelativeClock(periodMs?: number): number;
26
+ //# sourceMappingURL=relative-clock.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Pure card model for one `schedule_create` call in the Session transcript.
3
+ *
4
+ * The tool's model-facing result is its canonical task value serialized as
5
+ * JSON (`renderValue`), so the created task's identity and rule are read from
6
+ * that text. Presentation runs while a call streams and again on Session-log
7
+ * replay of arbitrary logged arguments, so every step narrows wire JSON and
8
+ * returns empty rather than throwing.
9
+ */
10
+ import type { ScheduleRecord } from '@deepseek-ai/dsh-schedule/client';
11
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
12
+ /** One Tool call block as the card receives it: a running call or a settled result. */
13
+ type ToolBlock = ToolCallViewProps['block'];
14
+ /** Derived presentation of one `schedule_create` call. */
15
+ export interface ScheduleCreateCardModel {
16
+ /** Created task narrowed from the settled result, or undefined when the result carries none. */
17
+ readonly task: ScheduleRecord | undefined;
18
+ /** Single-line task title from the result, the call arguments, or the wire tool name. */
19
+ readonly title: string;
20
+ /** Raw model-facing result text of a settled call, when it is one text block. */
21
+ readonly output: string | null;
22
+ }
23
+ /**
24
+ * Narrow one opaque value to a complete Schedule rule.
25
+ *
26
+ * The value arrives from replayed wire JSON, so each rule kind is checked for
27
+ * the fields `formatScheduleFrequency` reads. A missing identity or an
28
+ * incomplete rule returns undefined and the card renders without a task.
29
+ *
30
+ * The result JSON normally carries the stored title. A result recorded before
31
+ * that field existed carries none, so this narrowing derives the display title
32
+ * from the instruction's first line; when the instruction has no such line it
33
+ * returns undefined.
34
+ * @param value - opaque value parsed from logged JSON.
35
+ * @returns the narrowed rule, or undefined when it is not a complete task.
36
+ */
37
+ export declare function narrowScheduleRecord(value: unknown): ScheduleRecord | undefined;
38
+ /**
39
+ * Derive the transcript card of one `schedule_create` call.
40
+ * @param block - raw call or result block carried by the Session journal.
41
+ * @param toolName - wire Tool name, used when no task title is available.
42
+ * @returns the created task, its title, and the settled result text.
43
+ */
44
+ export declare function scheduleCreateCardModel(block: ToolBlock, toolName: string): ScheduleCreateCardModel;
45
+ export {};
46
+ //# sourceMappingURL=schedule-create-card.d.ts.map