@deepseek-ai/dsh-client-ui-schedule 0.2.2-alpha.2 → 0.2.2-alpha.3

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.
@@ -15,9 +15,9 @@ export interface ClockPickerProps {
15
15
  /** Dismiss the panel. */
16
16
  readonly onClose: () => void;
17
17
  /**
18
- * Whether the panel offers the seconds column (default true). A cron rule has
19
- * no seconds field, so its form hides the column; a pick then keeps the staged
20
- * clock's own seconds.
18
+ * Whether the panel offers the seconds column (default true). A daily rule
19
+ * names only its hour and minute, so its form hides the column; a pick then
20
+ * keeps the staged clock's own seconds.
21
21
  */
22
22
  readonly seconds?: boolean;
23
23
  /** Row copy. */
@@ -1,11 +1,12 @@
1
1
  import type { RemoteResult } from '@deepseek-ai/dsh-api-remotes/client';
2
2
  import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
3
  import type { ScheduleDeliveryHistoryRequest, ScheduleDeliveryHistoryResult } from '@deepseek-ai/dsh-schedule/client';
4
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
4
5
  /** Read saved records without opening or activating the original Session. */
5
6
  export interface DeliveryHistoryInjected {
6
7
  /**
7
- * Read a newest-first page for the exact task and Session.
8
- * @param request - Task binding, required page size, and optional older-page cursor.
8
+ * Read a newest-first page of one task's saved deliveries.
9
+ * @param request - Task, required page size, and optional older-page cursor.
9
10
  * @returns Remote success or failure; transport exceptions may reject the promise.
10
11
  */
11
12
  readonly loadHistory: (request: ScheduleDeliveryHistoryRequest) => Promise<RemoteResult<ScheduleDeliveryHistoryResult>>;
@@ -13,17 +14,22 @@ export interface DeliveryHistoryInjected {
13
14
  type Cursor = ScheduleDeliveryHistoryRequest['before'];
14
15
  type Props = DeliveryHistoryInjected & PropsLocale<'schedule.manager'> & {
15
16
  id: ScheduleDeliveryHistoryRequest['id'];
16
- sessionId: ScheduleDeliveryHistoryRequest['sessionId'];
17
+ /** Open the Session that accepted one delivery. */
18
+ onOpenSession: (id: SessionId) => void;
19
+ /** Display titles of known Sessions, by id. */
20
+ sessionTitles: Readonly<Record<string, string>>;
21
+ /** Sessions that a delivery's open button may open. */
22
+ availableSessionIds: readonly string[];
17
23
  latestMessageId: Cursor;
18
24
  /** IANA zone of the task's own wall-clock rule; undefined for a one-shot or interval task. */
19
25
  timeZone?: string | undefined;
20
26
  };
21
27
  /**
22
- * Render immutable saved deliveries; the parent keys this view by task and Session.
28
+ * Render immutable saved deliveries; the parent keys this view by task.
23
29
  * Refreshes supersede pending older pages, and unmount ignores both late outcomes.
24
- * @param props - Exact task binding, latest receipt identity, Remote callback, task zone, and locale.
30
+ * @param props - Task, latest receipt identity, Remote callback, Session links, task zone, and locale.
25
31
  * @returns Saved records and explicit loading, failure, and pagination actions.
26
32
  */
27
- export declare function DeliveryHistory({ id, sessionId, latestMessageId, timeZone, loadHistory, t }: Props): import("react").JSX.Element;
33
+ export declare function DeliveryHistory({ id, latestMessageId, timeZone, loadHistory, onOpenSession, sessionTitles, availableSessionIds, t, }: Props): import("react").JSX.Element;
28
34
  export {};
29
35
  //# sourceMappingURL=DeliveryHistory.d.ts.map
@@ -0,0 +1,12 @@
1
+ /** Display the Host's effective admission interval before selecting per-run conversations. */
2
+ import { type ReactNode } from 'react';
3
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import type { HostTaskActions } from './TaskDetail.tsx';
5
+ /** Read the configured interval through an injected action; failed reads stay visible and retryable.
6
+ * @param props - The failure-contained read action and task-manager translations.
7
+ * @returns The configured interval, a loading indicator, or a retryable failure.
8
+ */
9
+ export declare function NewSessionLimit({ load, t }: PropsLocale<'schedule.manager'> & {
10
+ readonly load: HostTaskActions['loadNewSessionInterval'];
11
+ }): ReactNode;
12
+ //# sourceMappingURL=NewSessionLimit.d.ts.map
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { TaskMenuEntry } from './TaskMenu.tsx';
4
+ /** A labelled menu row using the current task detail's trigger, portal, and keyboard behavior. */
5
+ export declare function RuleSelectRow({ label, value, current, items, disabled, onChange, onDismiss, header, listClassName }: {
6
+ readonly label: string;
7
+ readonly value: string;
8
+ readonly current: string;
9
+ readonly items: readonly TaskMenuEntry[];
10
+ readonly disabled: boolean;
11
+ readonly onChange: (value: string) => void;
12
+ readonly onDismiss?: () => void;
13
+ readonly header?: ReactNode;
14
+ readonly listClassName?: string | undefined;
15
+ }): ReactNode;
16
+ /** The current task detail's searchable, localized zone menu with recent choices. */
17
+ export declare function RuleZoneRow({ value, disabled, onChange, t }: PropsLocale<'schedule.manager'> & {
18
+ readonly value: string;
19
+ readonly disabled: boolean;
20
+ readonly onChange: (value: string) => void;
21
+ }): ReactNode;
22
+ //# sourceMappingURL=RuleSelectRow.d.ts.map
@@ -1,9 +1,9 @@
1
1
  import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
- import type { ScheduleId } from '@deepseek-ai/dsh-schedule/client';
2
+ import type { ScheduleId, ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule/client';
3
3
  import type { CatalogInjected } from './catalog-source.ts';
4
4
  import { NS } from './locales.ts';
5
5
  /** Full props for the Session-header Schedule catalog action. */
6
- export type ScheduleCatalogActionProps = PropsRuntime<'conversation.session.header.utilities'> & PropsLocale<typeof NS> & InjectFace<CatalogInjected & {
6
+ export type ScheduleCatalogActionProps = PropsRuntime<'conversation.session.header.utilities'> & PropsLocale<typeof NS> & InjectFace<CatalogInjected<ScheduleCatalogEntry> & {
7
7
  /**
8
8
  * Show one task's detail in the right Sidebar for this entry's Session.
9
9
  * @param id - Task chosen by the Session entry.
@@ -4,6 +4,7 @@ import type { ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule/client';
4
4
  import type { CatalogSnapshot } from './catalog-source.ts';
5
5
  import { type TaskDetailInjected } from './TaskDetail.tsx';
6
6
  import type { TaskTabBindings } from './task-tab-bindings.ts';
7
+ import type { TaskEditorStoreProps } from './editor-store.ts';
7
8
  /** The Host task catalog the body, its chip, and the Tasks page all read. */
8
9
  export interface ScheduleTaskCatalogInjected {
9
10
  /** Shared Host task catalog with its query and deletion state. */
@@ -20,7 +21,7 @@ export interface ScheduleTaskBindingInjected {
20
21
  export interface ScheduleTaskTabInjected extends TaskDetailInjected, ScheduleTaskCatalogInjected, ScheduleTaskBindingInjected {
21
22
  }
22
23
  /** Props of the task tab's body: the tab it draws, localized copy, and its catalog face. */
23
- export type ScheduleTaskTabProps = PropsRuntime<'sidebar.right.pane.tab'> & PropsLocale<'schedule.manager'> & InjectFace<ScheduleTaskTabInjected>;
24
+ export type ScheduleTaskTabProps = PropsRuntime<'sidebar.right.pane.tab'> & TaskEditorStoreProps & PropsLocale<'schedule.manager'> & InjectFace<ScheduleTaskTabInjected>;
24
25
  /**
25
26
  * Render the single task named by this tab's navigation parameters or by the
26
27
  * binding those parameters last wrote.
@@ -1,60 +1,79 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
- import type { ScheduleCatalogEntry, ScheduleId } from '@deepseek-ai/dsh-schedule/client';
3
+ import type { ScheduleCatalogEntry, ScheduleCreateRequest, ScheduleEditRequest, ScheduleId } from '@deepseek-ai/dsh-schedule/client';
4
4
  import type { SessionId } from '@deepseek-ai/dsh-session/types';
5
5
  import { type DeliveryHistoryInjected } from './DeliveryHistory.tsx';
6
6
  import type { CatalogDeleteOutcome, CatalogSnapshot } from './catalog-source.ts';
7
- import type { TaskTimingInjected, TimingDraft } from './task-timing.ts';
7
+ import type { TaskEditorStoreProps } from './editor-store.ts';
8
+ /** Localized reason the Host refused an edit, or reason the wiring could not confirm it. */
9
+ export type HostEditFailure = 'host.saveError' | 'host.conflict' | 'host.notFuture' | 'host.invalidRule' | 'detail.missing';
10
+ /** Localized reason the Host refused a run, or reason the wiring could not confirm it. */
11
+ export type HostRunFailure = 'host.runError' | 'host.executionPending' | 'detail.missing';
12
+ /** Creation keeps a failed draft and never creates or activates its destination Session. */
13
+ export type TaskCreateOutcome = {
14
+ readonly created: ScheduleCatalogEntry;
15
+ } | {
16
+ readonly failed: 'host.createError' | 'host.notFuture' | 'host.invalidRule';
17
+ };
18
+ /** Target-based mutations supplied by the owning plugin's Remote wiring. */
19
+ export interface HostTaskActions {
20
+ /**
21
+ * Apply one edit and refresh the catalog after the Host answers.
22
+ * @param request - task, change, and the `updatedAt` value that the change started from.
23
+ * @returns `saved`, or the localized reason the edit did not take effect.
24
+ */
25
+ readonly edit: (request: ScheduleEditRequest) => Promise<'saved' | {
26
+ readonly failed: HostEditFailure;
27
+ }>;
28
+ /**
29
+ * Queue one run now and refresh the catalog after the Host answers.
30
+ * @param id - task to run.
31
+ * @returns `queued`, or the localized reason the run did not start.
32
+ */
33
+ readonly run: (id: ScheduleId) => Promise<'queued' | {
34
+ readonly failed: HostRunFailure;
35
+ }>;
36
+ /** Read the configured minimum new-conversation interval; undefined means the read failed. */
37
+ readonly loadNewSessionInterval: () => Promise<number | undefined>;
38
+ }
8
39
  /** The two views of one task's detail: its rule, or its saved delivery records. */
9
40
  export type TaskDetailTab = 'rule' | 'records';
10
- /** One recurrence choice a retained task can be switched to. */
11
- type RuleKind = 'daily' | 'weekdays' | 'weekly' | 'every' | 'once' | 'cron';
12
- /** ISO weekdays of the weekly choice in display order, Monday through Sunday. */
13
- declare const WEEKDAYS: readonly [1, 2, 3, 4, 5, 6, 7];
14
- /** One ISO weekday of the weekly choice. */
15
- type Weekday = (typeof WEEKDAYS)[number];
16
- /**
17
- * Deletion, name/instruction/timing updates, saved-history, and original-Session
18
- * actions one task's detail calls.
19
- */
20
- export interface TaskDetailInjected extends DeliveryHistoryInjected, TaskTimingInjected {
41
+ /** Deletion, Host edit and run, saved-history, and linked-Session actions one task's detail calls. */
42
+ export interface TaskDetailInjected extends DeliveryHistoryInjected {
43
+ /** Host-owned edit, run, and new-Session interval actions. */
44
+ readonly hostActions: HostTaskActions;
21
45
  /**
22
- * Delete one retained task through its original Session binding.
46
+ * Delete one task.
23
47
  * @param id - Task shown in this detail.
24
48
  * @returns The deletion's outcome after the Remote acknowledgement and
25
49
  * authoritative refresh; the wiring reports it as the app-wide toast.
26
50
  */
27
51
  readonly onDelete: (id: ScheduleId) => Promise<CatalogDeleteOutcome>;
28
52
  /**
29
- * Reload the catalog after a query failure or an acknowledged timing update,
53
+ * Reload the catalog after a query failure or an acknowledged edit,
30
54
  * and from a surface that needs a read newer than its own record.
31
55
  * @param since - request ordinal the caller last observed, 0 to share any read in flight.
32
56
  * @returns Resolution after publishing the read result; failures remain in catalog state.
33
57
  */
34
58
  readonly onRetry: (since?: number) => Promise<void>;
35
59
  /**
36
- * Open an available, unarchived original conversation after rechecking current metadata.
37
- * @param id - Session bound to the shown task.
60
+ * Open an available, unarchived linked conversation after rechecking current metadata.
61
+ * @param id - Session linked to the shown task.
38
62
  */
39
63
  readonly onOpenSession: (id: SessionId) => void;
40
64
  }
41
65
  /** One task's detail, as the Tasks page and the task tab both compose it. */
42
- export type TaskDetailProps = TaskDetailInjected & PropsLocale<'schedule.manager'> & Pick<PropsRuntime<'main'>, 'useSessions' | 'useWorkspaces'> & {
43
- /** Task shown; an authoritative catalog row refreshes on its own, without an edit draft. */
44
- readonly task: ScheduleCatalogEntry;
45
- /** Whether an authoritative catalog row backs the shown task; a draft alone disables deletion. */
46
- readonly authoritative: boolean;
66
+ type TaskDetailCommonProps = TaskDetailInjected & TaskEditorStoreProps & PropsLocale<'schedule.manager'> & Pick<PropsRuntime<'main'>, 'useSessions' | 'useWorkspaces'> & {
47
67
  /** Element id shared by the detail panels and any control that points at them. */
48
68
  readonly id: string;
49
- /** Catalog query state; loading keeps every action visible and disabled. */
69
+ /** Catalog query state; loading disables saved-task actions. */
50
70
  readonly status: 'loading' | 'ready' | 'error';
51
71
  /** Tasks with a deletion in flight. */
52
72
  readonly deleting: readonly ScheduleId[];
53
73
  /**
54
- * Report the shown task so its owner retains it while an update is pending
55
- * or failed, or while a confirmed deletion awaits the refreshed catalog.
74
+ * Retain a task while a confirmed deletion and its catalog refresh settle.
56
75
  */
57
- readonly onEditState: (task: ScheduleCatalogEntry | null) => void;
76
+ readonly onRetainTask: (task: ScheduleCatalogEntry | null) => void;
58
77
  /** Active detail view; the owner resets it to Rules when it selects another task. */
59
78
  readonly tab: TaskDetailTab;
60
79
  /** Select the active detail view. */
@@ -64,95 +83,51 @@ export type TaskDetailProps = TaskDetailInjected & PropsLocale<'schedule.manager
64
83
  /** Ask for one task's deletion confirmation, or dismiss it with null. */
65
84
  readonly onConfirm: (id: ScheduleId | null) => void;
66
85
  /**
67
- * Leave the shown task once the refreshed catalog confirms its deletion:
68
- * the Tasks page clears its selection and the session task tab closes.
86
+ * Leave the shown task once the Host applied its deletion and the catalog refresh after it
87
+ * settled: the Tasks page clears its selection and the session task tab closes.
69
88
  */
70
89
  readonly onDeleted: () => void;
71
90
  /** Close this detail; a view with no list to return to omits the control. */
72
91
  readonly onClose?: () => void;
73
- /** Session whose Sidebar hosts this detail; a task linked to it omits the redundant original-Session entry. */
74
- readonly withinSession?: SessionId;
75
92
  };
76
- /** One task detail's editing state, as its Tasks page or task tab owns it. */
93
+ /** New and existing tasks use the same editable page; only submission and saved-task actions differ. */
94
+ export type TaskDetailProps = TaskDetailCommonProps & ({
95
+ readonly task: ScheduleCatalogEntry;
96
+ readonly authoritative: boolean;
97
+ readonly onCreateTask?: never;
98
+ readonly onCreated?: never;
99
+ } | {
100
+ readonly task?: undefined;
101
+ readonly authoritative?: never;
102
+ readonly onCreateTask: (request: ScheduleCreateRequest) => Promise<TaskCreateOutcome>;
103
+ readonly onCreated: (task: ScheduleCatalogEntry) => void;
104
+ });
105
+ /** One task detail's selected tab, confirmation, and retained catalog row. */
77
106
  export interface TaskDetailController {
78
107
  /** Catalog row the shown id resolves to, or undefined when the read has no such row. */
79
108
  readonly record: ScheduleCatalogEntry | undefined;
80
- /** Task to show: the catalog row, or the draft a pending or failed mutation retained. */
109
+ /** Task to show: the catalog row, an unsaved draft's baseline, or a confirmed deletion's retained row. */
81
110
  readonly task: ScheduleCatalogEntry | undefined;
82
- /** Element id shared by the detail panels and any control that points at them. */
83
- readonly id: string;
84
- /** Task whose deletion confirmation is open, or null when none is. */
85
- readonly confirmId: ScheduleId | null;
86
- /** Ask for one task's deletion confirmation, or dismiss it with null. */
87
- readonly setConfirmId: (id: ScheduleId | null) => void;
88
- /** Select the active detail view. */
89
- readonly setTab: (tab: TaskDetailTab) => void;
90
111
  /** Props the shared detail element takes, without the task it shows. */
91
- readonly props: Omit<TaskDetailProps, 'task' | 'authoritative' | 'onClose' | 'onDeleted'>;
112
+ readonly props: Omit<TaskDetailCommonProps, 'onClose' | 'onDeleted'>;
92
113
  }
93
114
  /**
94
- * Own the editing state one task detail shares across both of its owners.
115
+ * Own selected-task state shared by the Tasks page and task tabs.
95
116
  *
96
- * The shown task is the catalog row for `taskId`, or the draft a mutation
97
- * pending against that row retained after the row left the catalog. The view,
98
- * the confirmation, and the draft all reset when `taskId` changes, so one
99
- * task's draft never carries into another.
117
+ * The shown task comes from the catalog, an unsaved form's CAS baseline, or a
118
+ * confirmed deletion. The view and confirmation reset when selection changes;
119
+ * the entry's store retains unsaved fields by task identity.
100
120
  * @param injected - detail actions, localized copy, and framework readers.
101
121
  * @param catalog - the owner's authoritative task catalog snapshot.
102
122
  * @param taskId - task the owner selected, or undefined when it selected none.
103
123
  * @returns the shown task and catalog row, its element id, its confirmation, and the detail props.
104
124
  */
105
- export declare function useTaskDetail(injected: TaskDetailInjected & PropsLocale<'schedule.manager'> & Pick<PropsRuntime<'main'>, 'useSessions' | 'useWorkspaces'>, catalog: CatalogSnapshot<ScheduleCatalogEntry>, taskId: ScheduleId | undefined): TaskDetailController;
125
+ export declare function useTaskDetail(injected: TaskDetailInjected & TaskEditorStoreProps & PropsLocale<'schedule.manager'> & Pick<PropsRuntime<'main'>, 'useSessions' | 'useWorkspaces'>, catalog: CatalogSnapshot<ScheduleCatalogEntry>, taskId: ScheduleId | undefined): TaskDetailController;
106
126
  /**
107
- * Render one task's rule or saved deliveries with confirm-first deletion and its original Session.
108
- *
109
- * A deletion this detail confirmed settles with the refreshed catalog: once
110
- * that refresh reports the row gone, the detail calls `onDeleted` and its owner
111
- * leaves the task. The app-wide toast, not this detail, announces the outcome.
112
- * @param props - task, catalog state, detail view, confirmation, localized copy, and action callbacks.
113
- * @returns the detail region, its deletion confirmation dialog, and the linked Session entry.
114
- */
115
- export declare function TaskDetail({ task, authoritative, id, status, deleting, onDelete, onRetry, onUpdateTiming, loadHistory, onOpenSession, onEditState, tab, onTabChange, confirmId, onConfirm, onDeleted, onClose, withinSession, useSessions, useWorkspaces, t, }: TaskDetailProps): ReactNode;
116
- /** Values one task's detail stages, seeded from one stored record. */
117
- interface RuleShown {
118
- /** Task name the heading control edits. */
119
- readonly title: string;
120
- /** Reminder instruction the instruction control edits. */
121
- readonly prompt: string;
122
- /** Recurrence choice the rows edit. */
123
- readonly kind: RuleKind;
124
- /** Native time inputs the choice edits. */
125
- readonly draft: TimingDraft;
126
- /** ISO weekday set the weekly choice edits; other choices never read it. */
127
- readonly weekdays: readonly Weekday[];
128
- }
129
- /**
130
- * Merge one refreshed authoritative record into a staged draft.
131
- *
132
- * Three cases, because a rule kind and the fields that describe it are one
133
- * value. The Monday-to-Friday choice and the weekly choice state the same Host
134
- * weekly rule, so the comparisons below fold them together and only the day set
135
- * tells them apart.
136
- *
137
- * The draft stages another kind than the stored record. Its fields describe a
138
- * rule the refreshed record does not state, so the draft keeps them whole.
139
- *
140
- * The draft stages the stored kind, and the refreshed record changed that kind.
141
- * The two rules cannot be mixed, so the draft is kept whole when the user edited
142
- * it and the refreshed rule is adopted whole when the user did not.
143
- *
144
- * All three kinds agree. Only here can one field differ legitimately on each
145
- * side, so the fields merge on their own: a field the user changed keeps the
146
- * draft value and every other field takes the refreshed record, which is what
147
- * carries a concurrent remote timing edit into an unrelated local edit.
148
- *
149
- * The name and the instruction merge field by field in every case: another
150
- * client's rename reaches this detail even while a rule change is staged.
151
- * @param authoritative - values of the refreshed record.
152
- * @param draft - values the detail currently shows.
153
- * @param stored - authoritative values the draft was compared against.
154
- * @returns the merged values.
127
+ * Render one new or existing task's editable rule or saved deliveries.
128
+ * @param props - Task, catalog state, detail view, confirmation, locale, and actions.
129
+ * @returns The detail region and its deletion confirmation dialog.
155
130
  */
156
- export declare function mergeRuleDraft(authoritative: RuleShown, draft: RuleShown, stored: RuleShown): RuleShown;
131
+ export declare function TaskDetail(props: TaskDetailProps): ReactNode;
157
132
  export {};
158
133
  //# sourceMappingURL=TaskDetail.d.ts.map
@@ -0,0 +1,54 @@
1
+ /** Fields shared by manual creation and editing inside the existing Rules view. */
2
+ import type { ReactNode } from 'react';
3
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import type { WorkspaceSnapshot } from '@deepseek-ai/dsh-api-workspace-controller/client';
5
+ import type { ScheduleCatalogEntry, SchedulePatch, ScheduleTargetRequest } from '@deepseek-ai/dsh-schedule/client';
6
+ import type { TimingDraft } from './editor-timing.ts';
7
+ import type { TaskManagerKey } from './task-manager-locales.ts';
8
+ /** Local form values; only Save writes a task. */
9
+ export interface TaskEditorDraft extends TimingDraft {
10
+ readonly title: string;
11
+ readonly prompt: string;
12
+ readonly target: 'session' | 'new_once' | 'new';
13
+ readonly sessionId: string;
14
+ readonly cwd: string;
15
+ }
16
+ /** Registered Workspaces offered as the directory of a created Session. */
17
+ interface ProjectChoices {
18
+ readonly items: readonly {
19
+ readonly value: string;
20
+ readonly label: string;
21
+ }[];
22
+ /** Directory a new destination starts with: the default Workspace, else the first listed one, else empty. */
23
+ readonly defaultCwd: string;
24
+ }
25
+ /** Label Workspaces as the Workspace list does and select the directory a new destination starts with. */
26
+ export declare function projectChoices(workspaces: WorkspaceSnapshot['items'], defaultName: string): ProjectChoices;
27
+ /** Initialize a new task without creating or activating a Session. */
28
+ export declare function newTaskDraft(): TaskEditorDraft;
29
+ /** Seed an edit without normalizing unsupported stored rules. */
30
+ export declare function taskDraft(task: ScheduleCatalogEntry): TaskEditorDraft;
31
+ /**
32
+ * Validate the form while retaining untouched stored timing.
33
+ * @param draft - Current form values.
34
+ * @param changes - Existing task patch; omitted validates a new timing as well.
35
+ * @returns First correction key, `incomplete` for missing required fields, or undefined when valid.
36
+ */
37
+ export declare function taskDraftIssue(draft: TaskEditorDraft, changes?: SchedulePatch): TaskManagerKey | 'incomplete' | undefined;
38
+ /** Only meaningful field changes enter the CAS edit; untouched timing is never rewritten. */
39
+ export declare function taskDraftPatch(draft: TaskEditorDraft, original: ScheduleCatalogEntry, intervalFromNow?: boolean): SchedulePatch;
40
+ /** Reapply changed field groups only after the user chooses to review a newer revision. */
41
+ export declare function reapplyTaskDraft(draft: TaskEditorDraft, latest: ScheduleCatalogEntry, changes: SchedulePatch): TaskEditorDraft;
42
+ /** Resolve the explicit destination, preserving an existing preset when the project is unchanged. */
43
+ export declare function draftTarget(draft: TaskEditorDraft, original?: ScheduleCatalogEntry): ScheduleTargetRequest;
44
+ /** Render manual creation and inline edits with the existing task rule controls. */
45
+ export declare function TaskEditorFields({ draft, onChange, projects, disabled, original, t }: {
46
+ readonly draft: TaskEditorDraft;
47
+ readonly onChange: (draft: TaskEditorDraft) => void;
48
+ readonly projects: ProjectChoices;
49
+ readonly disabled: boolean;
50
+ readonly original?: ScheduleCatalogEntry | undefined;
51
+ readonly t: PropsLocale<'schedule.manager'>['t'];
52
+ }): ReactNode;
53
+ export {};
54
+ //# sourceMappingURL=TaskEditorFields.d.ts.map
@@ -1,5 +1,7 @@
1
1
  import type { HostObservable, InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
- import type { ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule/client';
2
+ import type { ScheduleCatalogEntry, ScheduleCreateRequest } from '@deepseek-ai/dsh-schedule/client';
3
+ import type { TaskCreateOutcome } from './TaskDetail.tsx';
4
+ import type { TaskEditorStoreProps } from './editor-store.ts';
3
5
  import type { CatalogSnapshot } from './catalog-source.ts';
4
6
  import { type TaskDetailInjected } from './TaskDetail.tsx';
5
7
  /** Injected catalog and task actions for the management page. */
@@ -10,7 +12,7 @@ export interface TaskManagerInjected extends TaskDetailInjected {
10
12
  };
11
13
  /**
12
14
  * 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.
15
+ * schedule it, using the existing new-conversation action.
14
16
  */
15
17
  readonly onNewTask: () => void;
16
18
  /**
@@ -23,11 +25,13 @@ export interface TaskManagerInjected extends TaskDetailInjected {
23
25
  * @returns resolution after the outcome is reported.
24
26
  */
25
27
  readonly onClearEnded: () => Promise<void>;
28
+ /** Create a task directly through the Host, without a model request. */
29
+ readonly onCreateTask: (request: ScheduleCreateRequest) => Promise<TaskCreateOutcome>;
26
30
  }
27
31
  /** Root-scoped task catalog props derived from the framework and injected actions. */
28
- export type TaskManagerPageProps = PropsRuntime<'main'> & InjectFace<TaskManagerInjected> & PropsLocale<'schedule.manager'>;
32
+ export type TaskManagerPageProps = PropsRuntime<'main'> & InjectFace<TaskManagerInjected> & TaskEditorStoreProps & PropsLocale<'schedule.manager'>;
29
33
  /**
30
- * Render retained tasks with authoritative deletion and timing-only edits.
34
+ * Render retained tasks with manual creation, inline editing, and authoritative deletion.
31
35
  * @param props - framework catalog snapshot, localized copy, and action callbacks.
32
36
  * @returns the searchable task list beside the selected task's detail.
33
37
  */
@@ -0,0 +1,50 @@
1
+ /** Shared rule controls taken from the existing task detail. */
2
+ import type { ReactNode } from 'react';
3
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
4
+ type Weekday = 1 | 2 | 3 | 4 | 5 | 6 | 7;
5
+ /**
6
+ * Render the weekly rule's Weekday row: one pill per weekday, named by the row's
7
+ * label and toggled in the rule the caller is editing.
8
+ * @param props.weekdays - weekdays the rule currently selects, as ISO weekday numbers (Monday is 1).
9
+ * @param props.disabled - whether the rule's controls are read-only.
10
+ * @param props.t - frequency translator owning the weekday labels.
11
+ * @param props.rowId - id builder for the row's label, which names the pill group.
12
+ * @param props.onToggle - toggle one weekday in the rule being edited.
13
+ * @returns the labelled Weekday row.
14
+ */
15
+ export declare function RuleWeekdayRow({ weekdays, disabled, t, rowId, onToggle }: {
16
+ weekdays: readonly number[];
17
+ disabled: boolean;
18
+ t: PropsLocale<'schedule.manager'>['t'];
19
+ rowId: (name: string) => string;
20
+ onToggle: (weekday: Weekday) => void;
21
+ }): ReactNode;
22
+ /** Inputs of one whole-number stepper of the task rule form. */
23
+ interface RuleStepperProps {
24
+ /** Id the row's label points at. */
25
+ readonly id: string;
26
+ /** Smallest value the field accepts. */
27
+ readonly min: number;
28
+ /** Largest value the field accepts. */
29
+ readonly max: number;
30
+ /** Staged value. */
31
+ readonly value: number;
32
+ /** Whether every edit is blocked. */
33
+ readonly disabled: boolean;
34
+ /** Accessible name of the up arrow. */
35
+ readonly increaseLabel: string;
36
+ /** Accessible name of the down arrow. */
37
+ readonly decreaseLabel: string;
38
+ /** Stage one clamped whole value. */
39
+ readonly onChange: (value: number) => void;
40
+ }
41
+ /**
42
+ * One whole-number stepper of the task rule form, such as the repeat interval or
43
+ * the day of the month. Values clamp to the field's bounds, and an emptied or
44
+ * fractional input stages nothing, so the staged rule stays valid on every edit.
45
+ * @param props - bounds, staged value, blocking state, arrow labels, and callback.
46
+ * @returns the stepper pill.
47
+ */
48
+ export declare function RuleStepper({ id, min, max, value, disabled, increaseLabel, decreaseLabel, onChange }: RuleStepperProps): ReactNode;
49
+ export {};
50
+ //# sourceMappingURL=TaskRuleControls.d.ts.map
@@ -83,9 +83,12 @@ export interface CatalogInjected<Item extends {
83
83
  * Mutations retain visible rows until an authoritative list read succeeds, and
84
84
  * each deletion resolves with its own outcome for the caller to report.
85
85
  * @param deps - Remote calls and invalidation subscriptions.
86
- * @returns observable catalog and component callbacks.
86
+ * @returns observable catalog, component callbacks, and acknowledged-creation retention.
87
87
  */
88
88
  export declare function createCatalogSource<Item extends {
89
89
  readonly id: ScheduleId;
90
- } = ScheduleRecord>(deps: CatalogDependencies<Item>): CatalogInjected<Item>;
90
+ } = ScheduleRecord>(deps: CatalogDependencies<Item>): CatalogInjected<Item> & {
91
+ /** Retain a Host-confirmed creation until the next successful catalog read. */
92
+ readonly retainCreated: (record: Item) => void;
93
+ };
91
94
  //# sourceMappingURL=catalog-source.d.ts.map
@@ -0,0 +1,32 @@
1
+ /** Unsaved task forms survive navigation without persisting business records. */
2
+ import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
3
+ import type { PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import type { ScheduleCatalogEntry } from '@deepseek-ai/dsh-schedule/client';
5
+ import type { TaskEditorDraft } from './TaskEditorFields.tsx';
6
+ import type { HostEditFailure, TaskCreateOutcome } from './TaskDetail.tsx';
7
+ type EditorFailure = HostEditFailure | Extract<TaskCreateOutcome, {
8
+ failed: string;
9
+ }>['failed'];
10
+ interface EditorDraft {
11
+ readonly draft: TaskEditorDraft;
12
+ readonly base: ScheduleCatalogEntry | undefined;
13
+ readonly initial?: TaskEditorDraft;
14
+ readonly pending?: boolean;
15
+ readonly failure?: EditorFailure;
16
+ }
17
+ interface EditorState {
18
+ drafts: Record<string, EditorDraft | undefined>;
19
+ }
20
+ declare const editorActions: {
21
+ setDraft: (state: EditorState, key: string, draft: EditorDraft) => void;
22
+ clearDraft: (state: EditorState, key: string) => void;
23
+ };
24
+ /**
25
+ * Declare drafts retained by the framework for one entry's scope.
26
+ * @returns the entry's store handle.
27
+ */
28
+ export declare function createEditorStore(): EngineStoreHandle<EditorState, typeof editorActions>;
29
+ /** Framework-bound selectors and actions; components never receive the store itself. */
30
+ export type TaskEditorStoreProps = PropsStore<ReturnType<typeof createEditorStore>>;
31
+ export {};
32
+ //# sourceMappingURL=editor-store.d.ts.map
@@ -0,0 +1,47 @@
1
+ /** Lossless guided and Custom editor projections for typed Schedule timing. */
2
+ import type { ScheduleCatalogEntry, ScheduleTiming } from '@deepseek-ai/dsh-schedule/client';
3
+ /** Periods represented by guided controls, plus a lossless advanced editor. */
4
+ export type FrequencyPreset = 'once' | 'minutely' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'advanced';
5
+ /** Editable values that determine one typed timing selector. */
6
+ export interface TimingDraft {
7
+ readonly frequency: FrequencyPreset;
8
+ readonly interval: string;
9
+ readonly start: string;
10
+ readonly timeZone: string;
11
+ readonly rrule: string;
12
+ /** Stored typed timing, retained in Custom and used to anchor guided edits to the current period. */
13
+ readonly retainedTiming?: ScheduleTiming;
14
+ readonly weekdays: readonly number[];
15
+ /** Day of the month; a month without that day runs on its last day. */
16
+ readonly monthDay: number;
17
+ /** Daily `HH:MM` clock time. */
18
+ readonly dailyTime: string;
19
+ }
20
+ /**
21
+ * Initial form values for a new schedule.
22
+ * @returns Guided timing with a one-hour-ahead one-shot default.
23
+ */
24
+ export declare function defaultTiming(): TimingDraft;
25
+ /**
26
+ * Format guided timing as DTSTART and RRULE content lines; return advanced text verbatim.
27
+ * Draft fields and future occurrences require separate validation.
28
+ * @param draft - Guided timing values or advanced text.
29
+ * @param intervalFromNow - Use the current minute for intervals and the current period for edited typed recurrences;
30
+ * false preserves the draft anchor.
31
+ * @returns RFC 5545 content lines.
32
+ */
33
+ export declare function rruleFromDraft(draft: TimingDraft, intervalFromNow?: boolean): string;
34
+ /**
35
+ * Recover only supported form rules; unknown rules remain verbatim in Advanced mode.
36
+ * @param record - Stored schedule to edit.
37
+ * @returns Guided values or the original advanced text.
38
+ */
39
+ export declare function timingFromRecord(record: ScheduleCatalogEntry): TimingDraft;
40
+ /**
41
+ * Resolve Custom Cron or RRULE text into its distinct management type.
42
+ * @param draft - Current rule editor values, including any untouched stored timing.
43
+ * @param intervalFromNow - Whether saves anchor intervals and edited typed recurrences to the current date and time.
44
+ * @returns Typed timing for the shared Schedule management API.
45
+ */
46
+ export declare function timingFromDraft(draft: TimingDraft, intervalFromNow?: boolean): ScheduleTiming;
47
+ //# sourceMappingURL=editor-timing.d.ts.map