@michengai/dsh-automation 1.0.4 → 1.0.6

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 CHANGED
@@ -21659,8 +21659,7 @@ function hasAutomationSource(hint = []) {
21659
21659
  return eventsHaveAutomationSource(readSessionEvents(hint));
21660
21660
  }
21661
21661
  function readSessionEvents(session) {
21662
- if (typeof session.snapshotEvents === "function") return session.snapshotEvents();
21663
- return session.events ?? [];
21662
+ return session.snapshotEvents();
21664
21663
  }
21665
21664
  function watchSessionEvents(ctx, session, fromSeq) {
21666
21665
  const events = [];
@@ -1,27 +1,30 @@
1
- import { type ComponentType, type ReactNode } from 'react';
1
+ import { type ComponentType } from 'react';
2
2
  import type { SessionSelector, Translate, WorkspaceSelector } from './contracts.js';
3
3
  import type { AutomationRuntime } from './runtime.js';
4
- import { type ScheduleView } from './schedule-overview.js';
5
- import type { NativeTabRegistry } from './native-tabs.js';
4
+ import { type NativeTabRegistry } from './native-tabs.js';
6
5
  import type { AutomationTaskSettingsRequest } from './task-settings-request.js';
7
- export declare function ScheduleRail({ t, runtime, openSession, openTaskSettings, view: controlledView, showViewSwitch, }: {
6
+ export declare function ScheduledRecordsView({ t, runtime, officialTree, hostProps, openSession, openTaskSettings, openCreateTask, useSessions, useWorkspaces, wide, }: {
8
7
  readonly t: Translate;
9
8
  readonly runtime: AutomationRuntime;
9
+ readonly officialTree?: ComponentType<Record<string, unknown>>;
10
+ readonly hostProps?: Record<string, unknown>;
10
11
  readonly openSession?: (sessionId: string) => void;
11
12
  readonly openTaskSettings?: (request: AutomationTaskSettingsRequest) => void;
12
- readonly view?: ScheduleView;
13
- readonly showViewSwitch?: boolean;
13
+ readonly openCreateTask?: () => void;
14
+ readonly useSessions?: SessionSelector;
15
+ readonly useWorkspaces?: WorkspaceSelector;
16
+ readonly wide?: boolean;
14
17
  }): JSX.Element;
15
- export declare function NativeScheduleShell({ t, runtime, officialTree, hostProps, openSession, openTaskSettings, useSessions, useWorkspaces, renderSlot, tabRegistry, wide, }: {
18
+ export declare function NativeScheduleShell({ t, runtime, officialTree, hostProps, openSession, openTaskSettings, openCreateTask, useSessions, useWorkspaces, tabRegistry, wide, }: {
16
19
  readonly t: Translate;
17
20
  readonly runtime: AutomationRuntime;
18
- readonly officialTree?: ComponentType<any>;
21
+ readonly officialTree?: ComponentType<Record<string, unknown>>;
19
22
  readonly hostProps?: Record<string, unknown>;
20
23
  readonly openSession?: (sessionId: string) => void;
21
24
  readonly openTaskSettings?: (request: AutomationTaskSettingsRequest) => void;
25
+ readonly openCreateTask?: () => void;
22
26
  readonly useSessions?: SessionSelector;
23
27
  readonly useWorkspaces?: WorkspaceSelector;
24
- readonly renderSlot?: (name: string, props?: Record<string, unknown>) => ReactNode;
25
28
  readonly tabRegistry?: NativeTabRegistry;
26
29
  readonly wide?: boolean;
27
30
  }): JSX.Element | null;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 记录视图的“新建”按钮与设置里的新建任务弹窗之间的跨组件请求。
3
+ * 宿主 WorkspaceBrowser 没有创建定时任务的 slot,因此沿用任务设置的事件桥。
4
+ */
5
+ export declare const AUTOMATION_CREATE_TASK_EVENT = "dsh-automation:create-task";
6
+ export declare const AUTOMATION_CREATE_TASK_STORAGE_KEY = "dsh-automation:pending-create-task";
7
+ export declare function requestAutomationCreateTask(): void;
8
+ export declare function readAutomationCreateTaskRequest(storage: Storage | undefined): boolean;
9
+ export declare function clearAutomationCreateTaskRequest(storage: Storage | undefined): void;
@@ -1,5 +1,5 @@
1
1
  import type { Translate } from './contracts.js';
2
- import type { AutomationSchedule, AutomationRunViewModel, AutomationSnapshot, AutomationViewModel, CreateAutomationInput, ModelOption, WorkspaceOption } from './protocol.js';
2
+ import type { AutomationSchedule, AutomationRunViewModel, AutomationViewModel, CreateAutomationInput, ModelOption, WorkspaceOption } from './protocol.js';
3
3
  export type ScheduleKind = 'once' | 'interval' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'custom';
4
4
  /** 使用宿主实际产生的触发类型和统一文案,避免把手动运行显示为定时。 */
5
5
  export declare function formatRunTrigger(trigger: AutomationRunViewModel['trigger'], t: Translate): string;
@@ -66,15 +66,7 @@ export declare function defaultFormState(now?: Date, workspaces?: readonly Works
66
66
  export declare function buildCreateInput(form: AutomationFormState, workspaces: readonly WorkspaceOption[], models: readonly ModelOption[], now?: Date, options?: {
67
67
  readonly allowPastOnce?: boolean;
68
68
  }): CreateAutomationInput;
69
- export interface OverviewStats {
70
- readonly total: number;
71
- readonly active: number;
72
- readonly attention: number;
73
- readonly nextRunAt?: string;
74
- }
75
- export declare function deriveOverview(snapshot: AutomationSnapshot): OverviewStats;
76
69
  export declare function formatRelativeTime(iso: string, now: Date, t: Translate): string;
77
- export declare function shortSessionId(sessionId: string): string;
78
70
  export declare function formatSchedule(schedule: AutomationSchedule, t: Translate): string;
79
71
  export declare function workspaceLabel(item: {
80
72
  readonly workspaceId?: string;
@@ -108,4 +100,3 @@ export declare function readSortDefault(storage: SortPreferenceStorage | undefin
108
100
  export declare function writeSortDefault(storage: SortPreferenceStorage, storageKey: string, key: AutomationSortKey, direction: AutomationSortDirection): void;
109
101
  export declare function groupHistory(runs: readonly import('./protocol.js').AutomationRunViewModel[], range: HistoryRange, now: Date, t: Translate): HistoryGroup[];
110
102
  export declare function formFromAutomation(item: import('./protocol.js').AutomationViewModel, workspaces?: readonly WorkspaceOption[], defaultModel?: ModelOption | null, defaultPermission?: string): AutomationFormState;
111
- export declare function prettyModelName(model: string): string;
@@ -0,0 +1,3 @@
1
+ import type { HostIcon } from './host-icon-resolve.js';
2
+ /** 把宿主图标组件渲染成可直接注入官方 DOM 的 SVG 字符串。 */
3
+ export declare function hostIconMarkup(icon: HostIcon, size?: number): string;
@@ -1,9 +1,7 @@
1
+ import type { CSSProperties } from 'react';
1
2
  export type HostIcon = (props: {
2
3
  readonly size?: number;
3
4
  readonly className?: string;
5
+ readonly style?: CSSProperties;
4
6
  }) => JSX.Element | null;
5
- /** 没有对应导出时返回 undefined,调用方再退回自绘。 */
6
- export declare function pickHostExport(source: Readonly<Record<string, unknown>>, name: string): unknown;
7
- /** 宿主图标渲染出 null 时改用自绘。 */
8
- export declare function hostOrFallback(icon: HostIcon, fallback: HostIcon): HostIcon;
9
7
  export declare function pickHostIcon(source: Readonly<Record<string, unknown>>, ...names: readonly string[]): HostIcon;
@@ -1,26 +1,19 @@
1
- import { pickHostIcon, type HostIcon } from './host-icon-resolve.js';
2
- export type { HostIcon };
3
- export { pickHostIcon };
4
- export declare const IconEllipsisOutline: HostIcon;
5
- export declare const IconSettingsOutline: HostIcon;
6
- export declare const IconArchiveOutline: HostIcon;
7
- export declare const IconBranchOutline: HostIcon;
8
- export declare const IconEditOutline: HostIcon;
9
- export declare const IconTrashOutline: HostIcon;
10
- export declare const IconCheckOutline: HostIcon;
11
- export declare const IconChevronDownOutline: HostIcon;
12
- export declare const IconListPenOutline: HostIcon;
13
- export declare const IconSearchOutline: HostIcon;
14
- export declare const IconCloseFill: HostIcon;
15
- export declare const IconSlidersTwoOutline: HostIcon;
16
- export declare const IconFolderClose: HostIcon;
17
- export declare const IconFolderOpen: HostIcon;
18
- export declare const IconTriangleRightFill: HostIcon;
19
- export declare const IconUnarchiveOutline: HostIcon;
20
- export declare const IconWorkspaceTreeOutline: HostIcon;
21
- export declare const IconFlatListOutline: HostIcon;
22
- export declare const IconChevronsUpDownOutline: HostIcon;
23
- export declare const IconClockOutline: HostIcon;
24
- export declare const IconCopyOutline: HostIcon;
25
- export declare const IconArchiveOffOutline: HostIcon;
26
- export declare const IconArchiveCheckOutline: HostIcon;
1
+ export declare const IconEllipsisOutline: import("./host-icon-resolve.js").HostIcon;
2
+ export declare const IconSearchOutline: import("./host-icon-resolve.js").HostIcon;
3
+ export declare const IconProjectAddOutline: import("./host-icon-resolve.js").HostIcon;
4
+ export declare const IconCloseFill: import("./host-icon-resolve.js").HostIcon;
5
+ export declare const IconSlidersTwoOutline: import("./host-icon-resolve.js").HostIcon;
6
+ export declare const IconFolderClose: import("./host-icon-resolve.js").HostIcon;
7
+ export declare const IconWorkspaceTreeOutline: import("./host-icon-resolve.js").HostIcon;
8
+ export declare const IconFlatListOutline: import("./host-icon-resolve.js").HostIcon;
9
+ export declare const IconClockOutline: import("./host-icon-resolve.js").HostIcon;
10
+ export declare const IconPlusOutline: import("./host-icon-resolve.js").HostIcon;
11
+ export declare const IconRefreshOutline: import("./host-icon-resolve.js").HostIcon;
12
+ export declare const IconInfoOutline: import("./host-icon-resolve.js").HostIcon;
13
+ export declare const IconNewChatOutline: import("./host-icon-resolve.js").HostIcon;
14
+ export declare const IconEditOutline: import("./host-icon-resolve.js").HostIcon;
15
+ export declare const IconChevronDownOutline: import("./host-icon-resolve.js").HostIcon;
16
+ export declare const IconSettingsOutline: import("./host-icon-resolve.js").HostIcon;
17
+ export declare const IconListPenOutline: import("./host-icon-resolve.js").HostIcon;
18
+ export declare const IconCheckOutline: import("./host-icon-resolve.js").HostIcon;
19
+ export declare const IconQueueOutline: import("./host-icon-resolve.js").HostIcon;
@@ -1,22 +1,4 @@
1
1
  import type { SVGProps } from 'react';
2
2
  type IconProps = SVGProps<SVGSVGElement>;
3
- export declare function PlusIcon(props: IconProps): JSX.Element;
4
- export declare function RefreshIcon(props: IconProps): JSX.Element;
5
- export declare function ShieldIcon(props: IconProps): JSX.Element;
6
- export declare function CalendarIcon(props: IconProps): JSX.Element;
7
- export declare function MoreIcon(props: IconProps): JSX.Element;
8
- export declare function InfoIcon(props: IconProps): JSX.Element;
9
- export declare function ClockIcon(props: IconProps): JSX.Element;
10
- export declare function ChatIcon(props: IconProps): JSX.Element;
11
3
  export declare function GithubIcon(props: IconProps): JSX.Element;
12
- /** 与技能管理器标题旁的问题反馈同一支 16px 笔,避免宿主图标把按钮撑高。 */
13
- export declare function FeedbackIcon(props: IconProps): JSX.Element;
14
- export declare function FolderIcon(props: IconProps): JSX.Element;
15
- export declare function SparkleIcon(props: IconProps): JSX.Element;
16
- export declare function UnarchiveOutlineIcon(props: IconProps): JSX.Element;
17
- export declare function FolderClosedIcon(props: IconProps): JSX.Element;
18
- export declare function FolderOpenIcon(props: IconProps): JSX.Element;
19
- export declare function ChevronIcon(props: IconProps): JSX.Element;
20
- /** 复刻官方任务树 running StateDot:3x3 像素绕圈。 */
21
- export declare function RunningStateDot(): JSX.Element;
22
4
  export {};
@@ -4,32 +4,17 @@ export declare const en: {
4
4
  readonly "sidebar.tab": "Scheduled";
5
5
  readonly "sidebar.tabs": "Workspace views";
6
6
  readonly "sidebar.tasksTab": "Tasks";
7
- readonly "sidebar.channelsTab": "Channels";
8
7
  readonly "sidebar.views": "Scheduled views";
9
8
  readonly "sidebar.viewOverview": "Task overview";
10
9
  readonly "sidebar.runsTab": "Records";
11
10
  readonly "sidebar.overviewTab": "Tasks";
12
- readonly "sidebar.empty": "No scheduled runs yet.";
13
- readonly "sidebar.tasksEmpty": "No web tasks yet.";
14
- readonly "sidebar.ungrouped": "Ungrouped";
15
- readonly "sidebar.section": "Scheduled";
11
+ readonly "records.groupReadOnly": "Scheduled task groups cannot be renamed or deleted here.";
12
+ readonly "records.groupByTask": "By task";
13
+ readonly "records.sectionTasks": "Tasks";
14
+ readonly "sidebar.treeUnavailable": "The official task tree is unavailable in this Host.";
16
15
  readonly "sidebar.workspaces": "Workspaces";
17
16
  readonly "sidebar.search": "Search";
18
- readonly "sidebar.sessions": "Sessions";
19
- readonly "sidebar.searchSessions": "Search session names";
20
17
  readonly "sidebar.clearSearch": "Clear search";
21
- readonly "sidebar.filter": "View options";
22
- readonly "sidebar.groupBy": "Group by";
23
- readonly "sidebar.groupWorkspace": "WorkSpace";
24
- readonly "sidebar.groupWorkspaceTree": "Workspace Tree";
25
- readonly "sidebar.groupList": "In one list";
26
- readonly "sidebar.sortBy": "Order by";
27
- readonly "sidebar.sortManual": "Manual";
28
- readonly "sidebar.sortTime": "Last updated";
29
- readonly "sidebar.filterBy": "Filter sessions";
30
- readonly "sidebar.hideArchived": "Hide archived";
31
- readonly "sidebar.showArchived": "All conversations (show archived)";
32
- readonly "sidebar.onlyArchived": "Archived only";
33
18
  readonly "header.lead": "Plan automatic tasks, or trigger them by hand. Describe the recurring work in any chat to create it quickly.";
34
19
  readonly "header.githubProject": "GitHub";
35
20
  readonly "header.githubFeedback": "Issues";
@@ -43,53 +28,11 @@ export declare const en: {
43
28
  readonly "examples.3.title": "Weekday morning briefing";
44
29
  readonly "examples.3.body": "Create a scheduled task that runs on weekdays and summarizes overnight changes.";
45
30
  readonly "examples.3.chip": "Weekdays 08:00";
46
- readonly "chat.hint": "In any conversation, describe the recurring work and ask the Agent to call automation_create.";
47
31
  readonly "chat.prompt": "I want to create a scheduled task that runs every [interval] and does [the actual task]";
48
32
  readonly "menu.run": "Run task";
49
33
  readonly "menu.edit": "Edit task";
50
34
  readonly "menu.delete": "Delete task";
51
- readonly "session.rename": "Rename";
52
- readonly "session.fork": "Fork session";
53
- readonly "session.archive": "Archive session";
54
- readonly "session.unarchive": "Restore";
55
- readonly "session.copySessionId": "Copy Session ID";
56
- readonly "session.moreActions": "More actions for {title}";
57
- readonly "session.groupActions": "Actions for {name}";
58
35
  readonly "session.taskSettings": "Task settings";
59
- readonly "session.archiveGroup": "Archive all conversations";
60
- readonly "session.archiveGroupConfirm": "Archive all";
61
- readonly "session.archiveGroupDescription": "Archive all {count} conversations for “{name}”. Choose Filter → Show archived to restore them.";
62
- readonly "session.archiveGroupPending": "Archiving conversations…";
63
- readonly "session.archiveGroupFailed": "Some conversations could not be archived: {message}";
64
- readonly "session.archiveGroupClose": "Close";
65
- readonly "session.archiveGroupCancel": "Cancel";
66
- readonly "session.unarchiveGroup": "Restore all conversations";
67
- readonly "session.unarchiveGroupConfirm": "Restore all";
68
- readonly "session.unarchiveGroupDescription": "Restore all {count} conversations for “{name}”.";
69
- readonly "session.unarchiveGroupPending": "Restoring conversations…";
70
- readonly "session.unarchiveGroupFailed": "Some conversations could not be restored: {message}";
71
- readonly "session.unarchiveGroupClose": "Close";
72
- readonly "session.unarchiveGroupCancel": "Cancel";
73
- readonly "session.deleteSession": "Delete session";
74
- readonly "session.deleteSessionConfirm": "Delete session";
75
- readonly "session.deleteSessionDescription": "This permanently deletes session “{name}”, its child agents (including any that are still running), and all of its records (conversation, stats, cache). This cannot be undone.";
76
- readonly "session.deleteSessionPending": "Deleting session…";
77
- readonly "session.deleteSessionFailed": "Could not delete the session: {message}";
78
- readonly "session.deleteSessionClose": "Close";
79
- readonly "session.deleteSessionCancel": "Cancel";
80
- readonly "session.idle": "Idle";
81
- readonly "session.runningStatus": "Running";
82
- readonly "session.completed": "Completed";
83
- readonly "session.waitingApproval": "Waiting for approval";
84
- readonly "session.planReview": "Plan to review";
85
- readonly "session.waitingAnswer": "Waiting for an answer";
86
- readonly "session.subagentsRunning": "{count} subagents running";
87
- readonly "session.archived": "Archived";
88
- readonly "session.delete": "Remove from Scheduled";
89
- readonly "session.deleteFolder": "Remove folder";
90
- readonly "session.confirmDeleteFolder": "Remove this folder from Scheduled?";
91
- readonly "session.confirmDeleteFolderHint": "This only unlists {count} session(s) in \"{name}\" from Scheduled. Host sessions are not deleted and they stay hidden from Tasks.";
92
- readonly "session.confirmDeleteFolderAction": "Remove from Scheduled";
93
36
  readonly "history.range.day": "By day";
94
37
  readonly "history.range.week": "By week";
95
38
  readonly "history.range.month": "By month";
@@ -110,7 +53,6 @@ export declare const en: {
110
53
  readonly "banner.wake": "Scheduled tasks run only while this computer stays awake.";
111
54
  readonly "tabs.mine": "Tasks";
112
55
  readonly "tabs.runs": "Run history";
113
- readonly "sort.by": "Sort";
114
56
  readonly "sort.created.asc": "Created time ascending";
115
57
  readonly "sort.created.desc": "Created time descending";
116
58
  readonly "sort.planned.asc": "Planned time ascending";
@@ -142,27 +84,11 @@ export declare const en: {
142
84
  readonly "modal.title": "New scheduled task";
143
85
  readonly "modal.edit": "Edit scheduled task";
144
86
  readonly "modal.save": "Save";
145
- readonly "header.eyebrow": "Unattended coding work";
146
- readonly "header.title": "Automations";
147
- readonly "header.subtitle": "Schedule standalone, auditable Agent runs for this workspace.";
148
- readonly "header.create": "New automation";
149
- readonly "header.closeCreate": "Hide form";
150
- readonly "scope.workspace": "Workspace";
151
- readonly "scope.folder": "Working directory";
152
- readonly "stats.total": "All";
153
- readonly "stats.active": "Active";
154
87
  readonly "stats.next": "Next run";
155
- readonly "stats.attention": "Needs attention";
156
88
  readonly "stats.noneScheduled": "None scheduled";
157
- readonly "stats.noAttention": "All clear";
158
- readonly "section.automations": "Workspace automations";
159
- readonly "section.automationsHint": "Each trigger starts a fresh DSH Session and keeps its own audit record.";
160
- readonly "section.runs": "Recent runs";
161
- readonly "section.runsHint": "Latest outcomes for this workspace.";
162
89
  readonly "section.refresh": "Refresh";
163
90
  readonly "empty.title": "Let recurring coding work run itself";
164
91
  readonly "empty.body": "Save a self-contained task, a schedule, and a permission boundary. Every run starts in a new Session.";
165
- readonly "empty.action": "Create the first automation";
166
92
  readonly "runs.empty": "No runs yet. Run one now, or wait for the next scheduled occurrence.";
167
93
  readonly "overview.empty": "No scheduled tasks yet. Create one in Settings.";
168
94
  readonly "form.title": "Create automation";
@@ -228,26 +154,19 @@ export declare const en: {
228
154
  readonly "status.skipped": "Skipped";
229
155
  readonly "status.cancelled": "Cancelled";
230
156
  readonly "status.interrupted": "Interrupted";
231
- readonly "card.nextRun": "Next";
232
- readonly "card.lastRun": "Last";
233
- readonly "card.never": "Not yet run";
234
157
  readonly "schedule.onceAt": "Once · {time}";
235
158
  readonly "schedule.everyMinutes": "Every {count} minutes";
236
159
  readonly "schedule.dailyAt": "Daily · {time}";
237
160
  readonly "schedule.weeklyAt": "{days} · {time}";
238
161
  readonly "card.pause": "Pause";
239
162
  readonly "card.resume": "Resume";
240
- readonly "card.runNow": "Run now";
241
163
  readonly "card.more": "More actions";
242
- readonly "card.delete": "Delete";
243
164
  readonly "card.confirmDelete": "Delete this automation?";
244
165
  readonly "card.confirmDeleteHint": "Run history is kept for audit.";
245
166
  readonly "card.confirm": "Delete";
246
167
  readonly "card.cancel": "Cancel";
247
168
  readonly "run.trigger.schedule": "Scheduled";
248
169
  readonly "run.trigger.manual": "Manual";
249
- readonly "run.openSession": "Session {id}";
250
- readonly "run.markRead": "Mark reviewed";
251
170
  readonly loading: "Loading automations…";
252
171
  readonly "error.title": "Automations could not be loaded";
253
172
  readonly "error.retry": "Try again";
@@ -261,11 +180,6 @@ export declare const en: {
261
180
  readonly "time.years": "{count}y";
262
181
  readonly "time.ago": "{text} ago";
263
182
  readonly "time.now": "now";
264
- readonly "session.copy": "Copy";
265
- readonly "session.copied": "Copied";
266
- readonly "session.compactApproval": "Approval";
267
- readonly "session.compactPlan": "Plan review";
268
- readonly "session.compactAnswer": "Answer";
269
183
  readonly "time.minuteAgo": "{count}m ago";
270
184
  readonly "time.hourAgo": "{count}h ago";
271
185
  readonly "time.dayAgo": "{count}d ago";
@@ -11,11 +11,35 @@ export interface NativeTabRegistry {
11
11
  readonly version: 1;
12
12
  officialTree: unknown;
13
13
  readonly sessionFilters: Array<(id: string) => boolean>;
14
+ readonly sessionOpeners: NativeSessionOpener[];
14
15
  getTabs(): NativeSidebarTab[];
16
+ /** 页签、过滤器或会话打开器发生变化时递增,供外壳重新计算。 */
17
+ getRevision(): number;
15
18
  subscribe(listener: () => void): () => void;
16
19
  insert(tab: NativeSidebarTab): () => void;
17
20
  addSessionFilter(filter: (id: string) => boolean): () => void;
21
+ addSessionOpener(opener: NativeSessionOpener): () => void;
18
22
  }
23
+ /** 按 order 选择第一个匹配的会话打开器;没有匹配时回退宿主打开。 */
24
+ export declare function openRegisteredSession(sessionId: string, registry?: NativeTabRegistry, hostOpen?: (id: string) => void): void;
25
+ export interface FilterableSessionState {
26
+ readonly ids?: readonly string[];
27
+ readonly byId?: Record<string, unknown>;
28
+ }
29
+ export interface NativeSessionOpener {
30
+ readonly id: string;
31
+ readonly order?: number;
32
+ matchSession(sessionId: string): boolean;
33
+ open(sessionId: string, hostOpen?: (id: string) => void): void;
34
+ }
35
+ /**
36
+ * 统一应用注册表里的会话过滤器。
37
+ * 没有过滤器时直接返回原 state,避免外壳为无人使用的过滤器付出重渲染成本。
38
+ *
39
+ * 缓存键是「注册表 + 快照 + revision」:换壳后的新注册表不会命中旧结果。
40
+ * 旧版注册表没有 `getRevision` 时退化为每次重算(结果仍正确,只是不再复用)。
41
+ */
42
+ export declare function applySessionFilters<T extends FilterableSessionState>(state: T, registry?: NativeTabRegistry): T;
19
43
  export declare function createNativeTabRegistry(officialTree: unknown): NativeTabRegistry;
20
44
  export declare function getNativeTabRegistry(target: unknown): NativeTabRegistry | undefined;
21
45
  export declare function attachNativeTabRegistry<T>(target: T, registry: NativeTabRegistry): NativeTabRegistry;
@@ -134,9 +134,6 @@ export interface CreateAutomationInput {
134
134
  readonly model?: string | null;
135
135
  readonly reasoningEffort?: string | null | undefined;
136
136
  }
137
- export interface SnapshotRequest {
138
- readonly sessionId?: string;
139
- }
140
137
  export interface CreateRequest {
141
138
  readonly sessionId?: string;
142
139
  readonly input: CreateAutomationInput;
@@ -0,0 +1,32 @@
1
+ /** 记录视图独立的视图状态;分组/排序/筛选不再借用官方任务树的 store。 */
2
+ export type RecordsGroupBy = 'task' | 'workspace' | 'workspace-tree' | 'flat';
3
+ export type RecordsOrderBy = 'manual' | 'updated';
4
+ export type RecordsArchivedFilter = 'default' | 'show' | 'only';
5
+ export interface RecordsViewState {
6
+ readonly groupBy: RecordsGroupBy;
7
+ readonly orderBy: RecordsOrderBy;
8
+ readonly groupExpansion: Readonly<Record<string, boolean>>;
9
+ readonly sessionOrderByAccount: Readonly<Record<string, readonly string[]>>;
10
+ readonly archivedFilter: RecordsArchivedFilter;
11
+ }
12
+ export interface RecordsViewActions {
13
+ setGroupBy(mode: RecordsGroupBy): void;
14
+ setOrderBy(mode: RecordsOrderBy, initialOrders: Readonly<Record<string, readonly string[]>>): void;
15
+ setGroupExpanded(key: string, expanded: boolean): void;
16
+ retainAccountKeys(workspaceKeys: readonly string[]): void;
17
+ setSessionOrder(accountKey: string, order: readonly string[], initialOrders: Readonly<Record<string, readonly string[]>>): void;
18
+ syncSessionOrders(orders: Readonly<Record<string, readonly string[]>>): void;
19
+ pinSessionOrder(sessionId: string, accountKeys: readonly string[], source: {
20
+ readonly members: Readonly<Record<string, readonly string[]>>;
21
+ }): void;
22
+ setArchivedFilter(filter: RecordsArchivedFilter): void;
23
+ ensureExpanded(keys: readonly string[]): void;
24
+ }
25
+ export interface RecordsViewStore {
26
+ getSnapshot(): RecordsViewState;
27
+ subscribe(listener: () => void): () => void;
28
+ actions: RecordsViewActions;
29
+ }
30
+ export declare function createRecordsViewStore(): RecordsViewStore;
31
+ /** 记录视图在页签切换后仍保留分组/排序选择。 */
32
+ export declare function getRecordsViewStore(): RecordsViewStore;
@@ -14,10 +14,11 @@ export declare function ScheduleViewSwitch({ t, view, onChange, }: {
14
14
  readonly onChange: (view: ScheduleView) => void;
15
15
  }): JSX.Element;
16
16
  /** 侧栏任务总览:点击卡片打开任务设置,右上角开关直接切换任务状态。 */
17
- export declare function ScheduleOverview({ t, automations, serverNow, openTaskSettings, onToggleAutomation, }: {
17
+ export declare function ScheduleOverview({ t, automations, serverNow, openTaskSettings, openCreateTask, onToggleAutomation, }: {
18
18
  readonly t: Translate;
19
19
  readonly automations: readonly AutomationViewModel[];
20
20
  readonly serverNow?: string;
21
21
  readonly openTaskSettings?: (request: AutomationTaskSettingsRequest) => void;
22
+ readonly openCreateTask?: () => void;
22
23
  readonly onToggleAutomation?: (automationId: string, mutation: 'pause' | 'resume') => void | Promise<void>;
23
24
  }): JSX.Element;
@@ -1,7 +1,9 @@
1
1
  /** 侧栏定时树与原生任务列表的纯函数,供组件和单测共用。 */
2
2
  import type { AutomationStatus } from './protocol.js';
3
3
  export declare const AUTOMATION_SESSION_PREFIX = "dsh-automation-session-";
4
- export declare const NATIVE_SIDEBAR_TAB_KEY = "dsh-automation.sidebar-tab";
4
+ /** 记录视图把每个自动化任务合成一个官方工作区分组,id 进入这个命名空间避免与真实工作区冲突。 */
5
+ export declare const AUTOMATION_TASK_WORKSPACE_PREFIX = "dsh-automation-task:";
6
+ export declare const NATIVE_SIDEBAR_TAB_KEY = "dsh-native-sidebar.tab";
5
7
  export interface ScheduleRailSession {
6
8
  readonly id: string;
7
9
  readonly running: boolean;
@@ -38,12 +40,10 @@ export interface NativeWorkspaceLike {
38
40
  readonly title?: string;
39
41
  readonly path?: string;
40
42
  readonly sessionIds?: readonly string[];
43
+ readonly createdAt?: string;
44
+ readonly updatedAt?: string;
41
45
  }
42
46
  export type NativeSidebarTab = 'tasks' | 'channels' | 'schedule';
43
- export { formatRunStamp } from '../run-title.js';
44
- /** 定时会话标题复刻任务树:优先用 Session 真实标题,没有再用执行时间兜底。 */
45
- export declare function scheduledSessionTitle(liveTitle: string | undefined, fallbackLabel: string): string;
46
- export declare function sessionUpdatedAtIso(value: number | string | undefined, fallback: string): string;
47
47
  export declare function groupScheduledSessions(automations: readonly {
48
48
  readonly id: string;
49
49
  readonly name: string;
@@ -67,8 +67,6 @@ export declare function deriveTaskOverviewRows(automations: readonly OverviewAut
67
67
  export type ArchivedSessionFilter = 'default' | 'show' | 'only';
68
68
  /** 默认隐藏已归档;显示和仅归档跟官方筛选同一套规则。空 id 一律不展示。 */
69
69
  export declare function scheduledSessionVisible(sessionId: string | undefined, archived: ReadonlySet<string>, filter: ArchivedSessionFilter): boolean;
70
- /** 归档立即摘掉。宿主会话簿经常晚于自动化快照,缺席不能当成已删除。 */
71
- export declare function keepScheduledSessionLink(sessionId: string | undefined, archived: ReadonlySet<string>, _presentIds?: ReadonlySet<string>): boolean;
72
70
  /** 当前打开的是定时会话,但快照还没有这条执行记录时,侧栏应立刻再拉一次。 */
73
71
  export declare function scheduledSessionNeedsSnapshotRefresh(sessionId: string | null | undefined, runs: readonly {
74
72
  readonly sessionId?: string;
@@ -76,21 +74,21 @@ export declare function scheduledSessionNeedsSnapshotRefresh(sessionId: string |
76
74
  export declare function collectScheduledSessionIds(runs: readonly {
77
75
  readonly sessionId?: string | null;
78
76
  }[] | undefined): Set<string>;
79
- /** 任务树要藏的定时会话:前缀、仍挂在定时快照上,或标题是定时跑出来的时间戳。 */
80
- export declare function isAutomationSidebarSession(id: string, item?: NativeSessionLike, scheduledIds?: ReadonlySet<string>): boolean;
81
- export declare function isNativeTaskSession(item: NativeSessionLike | undefined, scheduledIds?: ReadonlySet<string>): boolean;
82
- export declare function groupNativeTaskSessions(sessions: {
83
- readonly ids?: readonly string[];
84
- readonly byId?: Record<string, NativeSessionLike>;
85
- }, workspaces: {
86
- readonly items?: readonly NativeWorkspaceLike[];
87
- readonly archivedSessionIds?: readonly string[];
88
- } | undefined, ungroupedLabel: string, scheduledIds?: ReadonlySet<string>): {
89
- readonly id: string;
90
- readonly label: string;
91
- readonly sessions: readonly NativeSessionLike[];
92
- }[];
93
77
  export declare function readNativeSidebarTab(raw: string | null): NativeSidebarTab;
78
+ /** 迁移前各插件各写一份页签选择;新键统一后只在迁移时读一次。 */
79
+ export declare const LEGACY_AUTOMATION_TAB_KEY = "dsh-automation.sidebar-tab";
80
+ export declare const IM_TAB_KEY = "dsh-im-connect.sidebar-tab";
81
+ type TabStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
82
+ /**
83
+ * 读取侧栏页签选择:新键优先,缺失时回退到两边旧键并写回新键。
84
+ *
85
+ * 只清理本插件自己的旧键;`dsh-im-connect.sidebar-tab` 属于 IM,旧版 IM 仍会读它,
86
+ * 由 IM 自己迁移后清理,这里删掉会让旧版 IM 丢失用户选择。
87
+ * 存储不可用(隐私模式)时一律回落到任务页。
88
+ */
89
+ export declare function readStoredSidebarTab(storage: TabStorage | undefined): NativeSidebarTab;
90
+ /** 新建控件允许附带快捷键,但会话行仍须由调用方排除。 */
91
+ export declare function isHostNewSessionControl(label: string): boolean;
94
92
  /** 协作页签(频道/定时)以 registry 为准,不能因 sidebar.channels slot 未就绪就把点击打回任务。 */
95
93
  /** 只有当前会话变了才跟随切页签,避免点「定时」时被频道/任务会话打回去闪烁。 */
96
94
  export declare function shouldFollowSessionTab(previousCurrent: string | null | undefined, current: string | null | undefined): boolean;
@@ -103,7 +101,10 @@ export declare function resolveVisibleSidebarTab(input: {
103
101
  readonly channelsReady: boolean;
104
102
  readonly extraTabIds: readonly string[];
105
103
  }): string;
106
- export declare function tabForSessionId(sessionId: string | null | undefined, scheduledIds?: ReadonlySet<string>): NativeSidebarTab | undefined;
104
+ export declare function tabForSessionId(sessionId: string | null | undefined, scheduledIds?: ReadonlySet<string>, options?: {
105
+ readonly followSchedule?: boolean;
106
+ readonly followChannels?: boolean;
107
+ }): NativeSidebarTab | undefined;
107
108
  export declare function occupantLooksLikeCodexUi(value: unknown): boolean;
108
109
  export declare function slotOccupantName(item: unknown): string;
109
110
  export declare function hasCodexUiSidebar(entries: readonly unknown[] | undefined): boolean;
@@ -111,11 +112,37 @@ export interface SessionListState {
111
112
  readonly ids?: readonly string[];
112
113
  readonly byId?: Record<string, NativeSessionLike>;
113
114
  }
114
- export declare function filterTaskSessionState<T extends SessionListState>(state: T | undefined, scheduledIds?: ReadonlySet<string>): T;
115
+ /** 记录视图只保留定时执行产生的会话;其余字段原样带给官方树。 */
116
+ export declare function scheduledOnlySessionState<T extends SessionListState>(state: T | undefined, scheduledIds: ReadonlySet<string>): T;
115
117
  export interface WorkspaceListState {
116
118
  readonly items?: readonly NativeWorkspaceLike[];
117
119
  readonly archivedSessionIds?: readonly string[];
120
+ readonly pinnedSessionIds?: readonly string[];
121
+ readonly state?: 'idle' | 'loading' | 'error';
122
+ readonly phase?: 'pending' | 'ready';
123
+ readonly error?: unknown;
118
124
  }
125
+ export interface SyntheticTaskGroup {
126
+ readonly id: string;
127
+ readonly name: string;
128
+ readonly sessionIds: readonly string[];
129
+ /** 任务自身的创建时间(ISO-8601);官方树用它排序并渲染分组悬停卡片。 */
130
+ readonly createdAt: string;
131
+ }
132
+ export declare function automationTaskWorkspaceId(automationId: string): string;
133
+ export declare function automationIdFromTaskWorkspaceId(workspaceId: string | undefined): string | undefined;
134
+ /**
135
+ * 把自动化任务合成为官方 WorkspaceView 列表。
136
+ *
137
+ * 官方树只按 `workspaceId` + `sessionIds` 分组,不校验工作区是否真实存在;
138
+ * 保留源快照的 phase/state/archived/pinned,避免官方树一直停在未就绪状态。
139
+ */
140
+ export declare function syntheticTaskWorkspaceState<T extends WorkspaceListState>(state: T | undefined, groups: readonly SyntheticTaskGroup[]): T;
141
+ /**
142
+ * 按真实工作区分组时,只保留定时执行会话,并沿用官方的归档筛选。
143
+ * 保留 phase/state/archived/pinned,官方树才会正常渲染。
144
+ */
145
+ export declare function scheduledRealWorkspaceState<T extends WorkspaceListState>(state: T | undefined, scheduledIds: ReadonlySet<string>, archivedFilter: ArchivedSessionFilter): T;
119
146
  /** 0.2 主视图由 retainedBy.mainView 标记。 */
120
147
  export declare function resolveCurrentSessionId(snapshot: SessionListState | undefined): string | null;
121
148
  export interface ClientSessionOpenAccess {
@@ -143,9 +170,10 @@ export interface EnsureOpenScheduledSessionInput {
143
170
  }
144
171
  /** 先把会话挂回工作区并刷新客户端会话簿,再打开;避免侧栏能看见、点下去却 unknown session。 */
145
172
  export declare function ensureOpenScheduledSession(input: EnsureOpenScheduledSessionInput): Promise<boolean>;
146
- export declare function isHiddenSidebarSessionId(id: string, scheduledIds?: ReadonlySet<string>): boolean;
147
- export declare function filterWorkspaceListState<T extends WorkspaceListState>(state: T | undefined, scheduledIds?: ReadonlySet<string>): T;
148
173
  export type WrapperFlags = {
174
+ __dshNativeTabWrapped?: unknown;
175
+ __dshNativeTabOriginal?: unknown;
176
+ __dshNativeTabOwner?: unknown;
149
177
  __dshAutomationWrapped?: unknown;
150
178
  __dshAutomationOriginal?: unknown;
151
179
  __imConnectWrapped?: unknown;
@@ -153,33 +181,7 @@ export type WrapperFlags = {
153
181
  };
154
182
  export declare function wrapperFlags(component: unknown): WrapperFlags;
155
183
  export declare function isOwnAutomationWrapper(component: unknown): boolean;
156
- export declare function isMarkedWorkspaceWrapper(component: unknown): boolean;
157
184
  export declare function resolveOfficialTreeComponent(component: unknown): unknown;
158
185
  export declare function isAutomationWorkspaceWrapper(item: unknown): boolean;
159
186
  export declare function pickWrappableWorkspacesEntry(entries: readonly unknown[]): unknown;
160
- export type WorkspaceGroupMode = 'workspace' | 'workspace-tree' | 'list';
161
- /** 官方按工作区树:子目录挂到路径最长的已打开工作区下面。 */
162
- export declare function owningParentFolder(path: string, candidates: readonly string[]): string | undefined;
163
- export interface WorkspaceTreeGroup<T> {
164
- readonly id: string;
165
- readonly name: string;
166
- readonly depth: number;
167
- readonly keep?: boolean;
168
- readonly sessions: readonly T[];
169
- }
170
- /** 定时会话按宿主工作区归组,工作区路径嵌套时缩进。没有工作区的会话进未分组。 */
171
- export declare function groupScheduledSessionsByWorkspaceTree<T extends {
172
- readonly id?: string;
173
- }>(sessions: readonly T[], workspaces: readonly NativeWorkspaceLike[], ungroupedLabel: string): WorkspaceTreeGroup<T>[];
174
- export type WorkspaceListSort = 'manual' | 'time';
175
- export interface SearchableRailGroup {
176
- readonly name: string;
177
- readonly sessions: readonly {
178
- readonly title?: string;
179
- readonly label?: string;
180
- readonly updatedAt?: string;
181
- }[];
182
- /** 按工作区树时,没有自己的会话、只用来托住子工作区的父级也要留着。 */
183
- readonly keep?: boolean;
184
- }
185
- export declare function applyWorkspaceBrowserQuery<T extends SearchableRailGroup>(groups: readonly T[], query: string, sort: WorkspaceListSort, groupMode?: WorkspaceGroupMode): T[];
187
+ export {};
@@ -2,7 +2,7 @@
2
2
  * 设置页导航图标的非侵入式替换。
3
3
  *
4
4
  * 宿主会用自己的 svg 渲染设置导航图标;插件若直接改写宿主 svg 的 outerHTML,
5
- * 会与宿主/皮肤的内容级图标规则互相覆盖。这里改为插入独立的 mask 图标,
5
+ * 会与宿主/皮肤的内容级图标规则互相覆盖。这里改为插入独立的宿主时钟图标,
6
6
  * 只通过 marker 属性隐藏宿主 svg,卸载时可以完整还原。
7
7
  */
8
8
  export declare const SETTINGS_NAV_ICON_CLASS = "dsh-st-nav-icon-schedule";
@@ -14,7 +14,7 @@ export declare const SETTINGS_NAV_ICON_MARKER = "data-dsh-schedule-nav";
14
14
  * @param labels 返回当前语言下目标分区名称的函数
15
15
  * @returns 是否发生了实际变更;重复调用保持幂等
16
16
  */
17
- export declare function applySettingsNavIcon(button: HTMLButtonElement, labels: () => readonly string[]): boolean;
17
+ export declare function applySettingsNavIcon(button: HTMLButtonElement, labels: () => readonly string[], markup?: () => string): boolean;
18
18
  /**
19
19
  * 还原导航按钮:移除 marker 与插件插入的图标,宿主 svg 从未被修改。
20
20
  *
@@ -26,4 +26,4 @@ export declare function restoreSettingsNavIcon(button: HTMLButtonElement): boole
26
26
  *
27
27
  * 通过 MutationObserver 覆盖设置弹窗异步挂载、语言切换和宿主重渲染的场景。
28
28
  */
29
- export declare function installSettingsNavIcon(labels: () => readonly string[]): () => void;
29
+ export declare function installSettingsNavIcon(labels: () => readonly string[], markup?: () => string): () => void;