@michengai/dsh-automation 0.1.2 → 0.1.4

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 (29) hide show
  1. package/README.md +54 -31
  2. package/README.zh-CN.md +50 -27
  3. package/assets/branding/dsh-banner.png +0 -0
  4. package/assets/screenshots/chat-approval.png +0 -0
  5. package/assets/screenshots/chat-create.png +0 -0
  6. package/assets/screenshots/chat-created.png +0 -0
  7. package/assets/screenshots/settings-runs.png +0 -0
  8. package/assets/screenshots/settings-tasks.png +0 -0
  9. package/assets/screenshots/workspace-scheduled.png +0 -0
  10. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/02-/345/275/223/345/211/215/347/212/266/346/200/201.md +2 -3
  11. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/03-/345/276/205/345/212/236/344/270/216/351/230/273/345/241/236.md +2 -2
  12. package/docs/01-/345/275/223/345/211/215/345/267/245/344/275/234/I001-/344/273/273/345/212/241/350/207/252/345/212/250/345/214/226/346/217/222/344/273/266/00-/350/277/255/344/273/243/346/200/273/350/247/210.md +10 -4
  13. package/lib/client.js +746 -424
  14. package/lib/client.js.map +4 -4
  15. package/lib/index.js +46 -5
  16. package/lib/types/client/AutomationView.d.ts +1 -1
  17. package/lib/types/client/ScheduleRail.d.ts +2 -2
  18. package/lib/types/client/contracts.d.ts +12 -0
  19. package/lib/types/client/create-modal-logic.d.ts +7 -0
  20. package/lib/types/client/create-modal.d.ts +2 -1
  21. package/lib/types/client/icons.d.ts +6 -0
  22. package/lib/types/client/locales.d.ts +18 -2
  23. package/lib/types/client/native-session-list.d.ts +1 -1
  24. package/lib/types/client/native-session-menu.d.ts +43 -4
  25. package/lib/types/client/schedule-rail-model.d.ts +46 -7
  26. package/lib/types/client/workspace-toolbar.d.ts +13 -0
  27. package/lib/types/index.d.ts +18 -1
  28. package/lib/types/prompt.d.ts +6 -0
  29. package/package.json +2 -6
package/lib/index.js CHANGED
@@ -7,6 +7,24 @@ var __export = (target, all) => {
7
7
  // src/index.ts
8
8
  import z2 from "@deepseek-ai/schemastery";
9
9
 
10
+ // src/prompt.ts
11
+ var AUTOMATION_PROMPT_NAME = "tool:automation";
12
+ var AUTOMATION_PROMPT_ORDER = 118;
13
+ var AUTOMATION_PROMPT_TEXT = [
14
+ "\u5F53\u7528\u6237\u8981\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u3001\u8BA1\u5212\u4EFB\u52A1\uFF0C\u6216\u8BA9\u67D0\u4EF6\u4E8B\u6BCF\u5929/\u6BCF\u5468/\u5DE5\u4F5C\u65E5\u81EA\u52A8\u6267\u884C\u65F6\uFF0C\u5FC5\u987B\u8C03\u7528 automation_create\u3002",
15
+ "\u4E0D\u8981\u5EFA\u8BAE crontab\u3001cron\u3001systemd timer\u3001GitHub Actions \u6216 CI \u5B9A\u65F6\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u64CD\u4F5C\u7CFB\u7EDF\u7EA7 cron\u3002",
16
+ "schedule_create \u53EA\u7528\u4E8E\u5F53\u524D\u4F1A\u8BDD\u91CC\u7684\u63D0\u9192\uFF0C\u4E0D\u4F1A\u65B0\u5F00\u72EC\u7ACB\u7F16\u7801 Session\u3002\u5199\u65E5\u62A5\u3001\u8DD1\u4EE3\u7801\u3001\u505A\u7814\u7A76\u7B49\u72EC\u7ACB\u5DE5\u4F5C\u5FC5\u987B\u7528 automation_create\u3002",
17
+ '\u81EA\u7136\u8BED\u8A00\u6620\u5C04\uFF1A\u6BCF\u4E2A\u5DE5\u4F5C\u65E5/\u5468\u4E00\u5230\u5468\u4E94 \u2192 kind=weekly, weekdays=["MO","TU","WE","TH","FR"]\uFF1B\u6BCF\u5929 \u2192 kind=daily\uFF1B\u65E9\u4E0A8\u70B9 \u2192 time="08:00"\u3002',
18
+ "\u672A\u6307\u5B9A\u65F6\u533A\u65F6\u4F7F\u7528 Asia/Shanghai\u3002prompt \u5FC5\u987B\u5199\u6210\u6BCF\u6B21\u72EC\u7ACB\u8FD0\u884C\u90FD\u80FD\u770B\u61C2\u7684\u5B8C\u6574\u4EFB\u52A1\u8BF4\u660E\u3002"
19
+ ].join("\n");
20
+ var AUTOMATION_CREATE_DESCRIPTION = [
21
+ "\u5F53\u7528\u6237\u8981\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u3001\u8BA1\u5212\u4EFB\u52A1\u3001\u6BCF\u5929/\u6BCF\u5468/\u5DE5\u4F5C\u65E5\u81EA\u52A8\u6267\u884C\u67D0\u4EF6\u4E8B\u65F6\u4F7F\u7528\u672C\u5DE5\u5177\u3002",
22
+ "\u4E0D\u8981\u6539\u7528 crontab\u3001systemd \u6216 CI\u3002",
23
+ "\u4E3A\u5F53\u524D\u5DE5\u4F5C\u533A\u521B\u5EFA\u4E00\u6761\u72EC\u7ACB DSH \u81EA\u52A8\u5316\uFF1B\u6BCF\u6B21\u89E6\u53D1\u5F00\u542F\u5168\u65B0 Session\uFF0C\u4E0D\u7EE7\u627F\u5F53\u524D\u5BF9\u8BDD\u3002",
24
+ '\u5DE5\u4F5C\u65E5\u65E9\u4E0A 8 \u70B9\u793A\u4F8B\uFF1Akind=weekly, weekdays=["MO","TU","WE","TH","FR"], time="08:00", time_zone="Asia/Shanghai"\u3002',
25
+ "\u5FC5\u987B\u4F7F\u7528\u663E\u5F0F IANA \u65F6\u533A\u3002\u6700\u77ED\u95F4\u9694 5 \u5206\u949F\u3002\u9ED8\u8BA4\u53EA\u8BFB\uFF1B\u53EA\u6709\u9700\u8981\u6539\u6587\u4EF6\u65F6\u624D\u9009 workspace-write\u3002"
26
+ ].join("");
27
+
10
28
  // src/rpc.ts
11
29
  var WEEKDAYS = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"];
12
30
  function record(value, label) {
@@ -22592,7 +22610,7 @@ function registerAutomationTools(service, agent) {
22592
22610
  try {
22593
22611
  register(defineTool({
22594
22612
  name: "automation_create",
22595
- description: "\u4E3A\u5F53\u524D\u5DE5\u4F5C\u533A\u521B\u5EFA\u4E00\u6761\u72EC\u7ACB\u81EA\u52A8\u5316\u3002\u6BCF\u6B21\u89E6\u53D1\u90FD\u4F1A\u5F00\u542F\u5168\u65B0 DSH Session\uFF0C\u4E0D\u4F1A\u7EE7\u627F\u5F53\u524D\u5BF9\u8BDD\u3002\u5FC5\u987B\u4F7F\u7528\u663E\u5F0F IANA \u65F6\u533A\u3002\u6700\u77ED\u95F4\u9694\u4E3A 5 \u5206\u949F\u3002\u9ED8\u8BA4\u53EA\u8BFB\uFF1B\u53EA\u6709\u9700\u8981\u6539\u6587\u4EF6\u65F6\u624D\u9009\u62E9 workspace-write\u3002",
22613
+ description: AUTOMATION_CREATE_DESCRIPTION,
22596
22614
  parameters: {
22597
22615
  name: { type: "string", required: true },
22598
22616
  prompt: { type: "string", required: true, description: "\u6BCF\u6B21\u72EC\u7ACB\u8FD0\u884C\u90FD\u4F7F\u7528\u7684\u81EA\u5305\u542B\u4EFB\u52A1\u8BF4\u660E\u3002" },
@@ -22764,8 +22782,16 @@ var MUTATING_TOOLS = /* @__PURE__ */ new Set([
22764
22782
  "automation_run_now",
22765
22783
  "automation_delete"
22766
22784
  ]);
22767
- function needsHumanApproval(exec, isMountedAgent) {
22785
+ function sessionApprovalPolicy(approval, session) {
22786
+ const override = approval?.overrideOf?.(session);
22787
+ if (override === "ask" || override === "never") return override;
22788
+ const fallback = approval?.config?.policy;
22789
+ if (fallback === "ask" || fallback === "never") return fallback;
22790
+ return void 0;
22791
+ }
22792
+ function needsHumanApproval(exec, isMountedAgent, policy) {
22768
22793
  if (!isMountedAgent || exec.signal.aborted || !MUTATING_TOOLS.has(exec.name)) return false;
22794
+ if (policy !== "ask") return false;
22769
22795
  if (exec.name !== "automation_update") return true;
22770
22796
  const args = typeof exec.arguments === "object" && exec.arguments !== null ? exec.arguments : {};
22771
22797
  return !(args.status === "paused" && Object.keys(args).every((key) => key === "id" || key === "status"));
@@ -22791,13 +22817,15 @@ async function apply(ctx, rawConfig) {
22791
22817
  };
22792
22818
  let stopApproval = () => {
22793
22819
  };
22820
+ let stopPrompt = () => {
22821
+ };
22794
22822
  let removeRpc = async () => {
22795
22823
  };
22796
22824
  const cleanup = async () => {
22797
22825
  if (cleaned) return;
22798
22826
  cleaned = true;
22799
22827
  alive = false;
22800
- for (const stop of [stopCreated, stopDisposed, stopApproval]) {
22828
+ for (const stop of [stopCreated, stopDisposed, stopApproval, stopPrompt]) {
22801
22829
  try {
22802
22830
  stop();
22803
22831
  } catch (error51) {
@@ -22833,9 +22861,21 @@ async function apply(ctx, rawConfig) {
22833
22861
  stopDisposed = ctx.on("agent/disposed", ({ agent }) => {
22834
22862
  agentTools.delete(agent);
22835
22863
  });
22864
+ const systemPrompt = ctx.get("systemPrompt");
22865
+ if (typeof systemPrompt?.section === "function") {
22866
+ stopPrompt = systemPrompt.section({
22867
+ name: AUTOMATION_PROMPT_NAME,
22868
+ order: AUTOMATION_PROMPT_ORDER,
22869
+ text: AUTOMATION_PROMPT_TEXT
22870
+ });
22871
+ }
22836
22872
  stopApproval = ctx.on("tools/pre-execute", async (exec, next) => {
22837
22873
  const downstream = await next();
22838
- if (downstream.kind !== "allow" || !needsHumanApproval(exec, agentTools.has(exec.agent))) return downstream;
22874
+ const approval = ctx.get("approval");
22875
+ const policy = sessionApprovalPolicy(approval, exec.agent?.session);
22876
+ if (downstream.kind !== "allow" || !needsHumanApproval(exec, agentTools.has(exec.agent), policy)) {
22877
+ return downstream;
22878
+ }
22839
22879
  return {
22840
22880
  kind: "ask",
22841
22881
  reason: humanApprovalReason(exec.name)
@@ -22865,5 +22905,6 @@ export {
22865
22905
  humanApprovalReason,
22866
22906
  inject,
22867
22907
  name,
22868
- needsHumanApproval
22908
+ needsHumanApproval,
22909
+ sessionApprovalPolicy
22869
22910
  };
@@ -1,2 +1,2 @@
1
1
  import type { AutomationViewProps } from './contracts.js';
2
- export declare function AutomationView({ t, runtime, closeSettings }: AutomationViewProps): JSX.Element;
2
+ export declare function AutomationView({ t, runtime, closeSettings, pickWorkspaceDirectory }: AutomationViewProps): JSX.Element;
@@ -7,11 +7,11 @@ type SessionSelector = <S>(select: (state: {
7
7
  ids?: string[];
8
8
  byId?: Record<string, NativeSessionLike>;
9
9
  current?: string | null;
10
- }) => S) => S;
10
+ }) => S, eq?: (a: S, b: S) => boolean) => S;
11
11
  type WorkspaceSelector = <S>(select: (state: {
12
12
  items?: NativeWorkspaceLike[];
13
13
  archivedSessionIds?: string[];
14
- }) => S) => S;
14
+ }) => S, eq?: (a: S, b: S) => boolean) => S;
15
15
  export declare function ScheduleRail({ t, runtime, openSession, }: {
16
16
  readonly t: Translate;
17
17
  readonly runtime: AutomationRuntime;
@@ -6,6 +6,7 @@ export interface AutomationViewProps {
6
6
  readonly t: Translate;
7
7
  readonly runtime: AutomationRuntime;
8
8
  readonly closeSettings?: () => void;
9
+ readonly pickWorkspaceDirectory?: () => Promise<string | null>;
9
10
  }
10
11
  export interface ClientRpc {
11
12
  call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<unknown>;
@@ -31,6 +32,17 @@ export interface ClientContext {
31
32
  };
32
33
  sessions?: {
33
34
  open(id: string): void;
35
+ refresh?: () => Promise<void>;
36
+ list?: {
37
+ getSnapshot(): {
38
+ ids?: readonly string[];
39
+ byId?: Record<string, unknown>;
40
+ current?: string | null;
41
+ };
42
+ };
43
+ };
44
+ workspaces?: {
45
+ pickDirectory(): Promise<string | null>;
34
46
  };
35
47
  locale: {
36
48
  register(namespace: string, dictionaries: {
@@ -0,0 +1,7 @@
1
+ /** 新建/编辑弹窗只允许取消或 ESC 关闭,点旁边不能关。 */
2
+ export declare function shouldCloseCreateModal(reason: 'backdrop' | 'escape' | 'cancel'): boolean;
3
+ /** 和 Chat 一样:先选目录,取消则不登记;没有手输路径这条路。 */
4
+ export declare function adoptPickedWorkspace(input: {
5
+ readonly pick: () => Promise<string | null>;
6
+ readonly add: (path: string) => Promise<string>;
7
+ }): Promise<string | null>;
@@ -1,6 +1,6 @@
1
1
  import type { Translate } from './contracts.js';
2
2
  import { type AutomationFormState } from './helpers.js';
3
- export declare function CreateModal({ t, busy, workspaces, models, defaultModel, skills, draft, editing, onClose, onSubmit, onAddWorkspace, }: {
3
+ export declare function CreateModal({ t, busy, workspaces, models, defaultModel, skills, draft, editing, onClose, onSubmit, onAddWorkspace, pickWorkspaceDirectory, }: {
4
4
  readonly t: Translate;
5
5
  readonly busy: boolean;
6
6
  readonly workspaces: readonly {
@@ -27,4 +27,5 @@ export declare function CreateModal({ t, busy, workspaces, models, defaultModel,
27
27
  readonly onClose: () => void;
28
28
  readonly onSubmit: (form: AutomationFormState) => Promise<void>;
29
29
  readonly onAddWorkspace?: (path: string) => Promise<string>;
30
+ readonly pickWorkspaceDirectory?: () => Promise<string | null>;
30
31
  }): JSX.Element;
@@ -16,8 +16,14 @@ export declare function ClockIcon(props: IconProps): JSX.Element;
16
16
  export declare function ChatIcon(props: IconProps): JSX.Element;
17
17
  export declare function FolderIcon(props: IconProps): JSX.Element;
18
18
  export declare function SparkleIcon(props: IconProps): JSX.Element;
19
+ export declare function CloseOutlineIcon(props: IconProps): JSX.Element;
20
+ export declare function CheckOutlineIcon(props: IconProps): JSX.Element;
21
+ export declare function SearchOutlineIcon(props: IconProps): JSX.Element;
22
+ export declare function SlidersIcon(props: IconProps): JSX.Element;
19
23
  export declare function FolderClosedIcon(props: IconProps): JSX.Element;
20
24
  export declare function FolderOpenIcon(props: IconProps): JSX.Element;
25
+ export declare function PlayOutlineIcon(props: IconProps): JSX.Element;
26
+ export declare function TreeCornerIcon(props: IconProps): JSX.Element;
21
27
  export declare function ChevronIcon(props: IconProps): JSX.Element;
22
28
  export declare function EllipsisIcon(props: IconProps): JSX.Element;
23
29
  export declare function PencilIcon(props: IconProps): JSX.Element;
@@ -9,6 +9,17 @@ export declare const en: {
9
9
  readonly 'sidebar.tasksEmpty': "No web tasks yet.";
10
10
  readonly 'sidebar.ungrouped': "Ungrouped";
11
11
  readonly 'sidebar.section': "Scheduled";
12
+ readonly 'sidebar.workspaces': "Workspaces";
13
+ readonly 'sidebar.search': "Search";
14
+ readonly 'sidebar.searchSessions': "Search sessions...";
15
+ readonly 'sidebar.clearSearch': "Clear search";
16
+ readonly 'sidebar.filter': "Filter";
17
+ readonly 'sidebar.groupBy': "Group by";
18
+ readonly 'sidebar.groupWorkspace': "By workspace";
19
+ readonly 'sidebar.groupList': "Single list";
20
+ readonly 'sidebar.sortBy': "Sort by";
21
+ readonly 'sidebar.sortManual': "Manual";
22
+ readonly 'sidebar.sortTime': "Recently updated";
12
23
  readonly 'header.lead': "Plan automatic tasks, or trigger them by hand. Describe the recurring work in any chat to create it quickly.";
13
24
  readonly 'examples.title': "Recommended examples";
14
25
  readonly 'examples.1.title': "Daily regression check";
@@ -27,8 +38,13 @@ export declare const en: {
27
38
  readonly 'session.rename': "Rename";
28
39
  readonly 'session.fork': "Fork session";
29
40
  readonly 'session.archive': "Archive session";
30
- readonly 'session.delete': "Delete session";
31
- readonly 'session.deleteFolder': "Delete folder";
41
+ readonly 'session.idle': "Idle";
42
+ readonly 'session.runningStatus': "Running";
43
+ readonly 'session.delete': "Remove from Scheduled";
44
+ readonly 'session.deleteFolder': "Remove folder";
45
+ readonly 'session.confirmDeleteFolder': "Remove this folder from Scheduled?";
46
+ readonly 'session.confirmDeleteFolderHint': "This only unlists {count} session(s) in \"{name}\" from Scheduled. Host sessions are not deleted and they stay hidden from Tasks.";
47
+ readonly 'session.confirmDeleteFolderAction': "Remove from Scheduled";
32
48
  readonly 'history.range.day': "By day";
33
49
  readonly 'history.range.week': "By week";
34
50
  readonly 'history.range.month': "By month";
@@ -1,6 +1,6 @@
1
1
  import type { Translate } from './contracts.js';
2
2
  import type { AutomationRuntime } from './runtime.js';
3
- export { nativeSessionMenuStyle, nextOpenSessionMenuId, relativeTime, resolveEventElement, shouldCloseNativeSessionMenu, } from './native-session-menu.js';
3
+ export { nativeSessionMenuStyle, nextOpenSessionMenu, nextOpenSessionMenuId, pointerPoint, relativeTime, resolveEventElement, shouldCloseNativeSessionMenu, } from './native-session-menu.js';
4
4
  export declare function NativeScheduleSessionList(props: {
5
5
  readonly t: Translate;
6
6
  readonly runtime: AutomationRuntime;
@@ -5,9 +5,48 @@ export declare function resolveEventElement(target: unknown): object | null;
5
5
  export declare function shouldCloseNativeSessionMenu(target: unknown, keepInside: readonly unknown[]): boolean;
6
6
  /** 侧栏同一时间只保留一条会话菜单。再点同一条则关闭。 */
7
7
  export declare function nextOpenSessionMenuId(current: string | null, clicked: string): string | null;
8
- /** 用视口坐标固定菜单,避免被侧栏 overflow 裁切后叠到下一条会话上。 */
9
- export declare function nativeSessionMenuStyle(box: {
10
- readonly bottom: number;
8
+ export type NativeSessionMenuState = {
9
+ readonly id: string;
10
+ readonly x: number;
11
+ readonly y: number;
12
+ } | null;
13
+ export declare function pointerPoint(event: {
14
+ readonly clientX?: unknown;
15
+ readonly clientY?: unknown;
16
+ } | null | undefined): {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ export declare function clampMenuPoint(x: number, y: number, width: number, height: number, viewport: {
21
+ readonly width: number;
22
+ readonly height: number;
23
+ }): {
24
+ x: number;
25
+ y: number;
26
+ };
27
+ export declare function nextOpenSessionMenu(current: NativeSessionMenuState, clicked: string, point: {
28
+ readonly x: number;
29
+ readonly y: number;
30
+ }): NativeSessionMenuState;
31
+ /** 和 IM 一样:菜单出现在指针处,再用真实尺寸限制在视口内。 */
32
+ export declare function nativeSessionMenuStyle(point: {
33
+ readonly x: number;
34
+ readonly y: number;
35
+ }, size?: {
36
+ readonly width: number;
37
+ readonly height: number;
38
+ }, viewport?: {
39
+ readonly width: number;
40
+ readonly height: number;
41
+ }): CSSProperties;
42
+ export declare function nativeSessionHoverStyle(row: {
11
43
  readonly right: number;
12
- }, viewportWidth: number): CSSProperties;
44
+ readonly top: number;
45
+ }, card: {
46
+ readonly width: number;
47
+ readonly height: number;
48
+ }, viewport: {
49
+ readonly width: number;
50
+ readonly height: number;
51
+ }): CSSProperties;
13
52
  export declare function relativeTime(value: string): string;
@@ -22,6 +22,7 @@ export interface ScheduleRunLike {
22
22
  export interface NativeSessionLike {
23
23
  readonly id?: string;
24
24
  readonly title?: string;
25
+ readonly displayTitle?: string;
25
26
  readonly blank?: boolean;
26
27
  readonly origin?: string;
27
28
  readonly updatedAt?: number | string;
@@ -43,20 +44,37 @@ export declare function groupScheduledSessions(automations: readonly {
43
44
  readonly id: string;
44
45
  readonly name: string;
45
46
  }[], runs: readonly ScheduleRunLike[]): ScheduleRailGroup[];
46
- export declare function isNativeTaskSession(item: NativeSessionLike | undefined): boolean;
47
+ export declare function collectScheduledSessionIds(runs: readonly {
48
+ readonly sessionId?: string | null;
49
+ }[] | undefined): Set<string>;
50
+ /** 任务树要藏的定时会话:前缀、仍挂在定时快照上,或标题是定时跑出来的时间戳。 */
51
+ export declare function isAutomationSidebarSession(id: string, item?: NativeSessionLike, scheduledIds?: ReadonlySet<string>): boolean;
52
+ export declare function isNativeTaskSession(item: NativeSessionLike | undefined, scheduledIds?: ReadonlySet<string>): boolean;
47
53
  export declare function groupNativeTaskSessions(sessions: {
48
54
  readonly ids?: readonly string[];
49
55
  readonly byId?: Record<string, NativeSessionLike>;
50
56
  }, workspaces: {
51
57
  readonly items?: readonly NativeWorkspaceLike[];
52
58
  readonly archivedSessionIds?: readonly string[];
53
- } | undefined, ungroupedLabel: string): {
59
+ } | undefined, ungroupedLabel: string, scheduledIds?: ReadonlySet<string>): {
54
60
  readonly id: string;
55
61
  readonly label: string;
56
62
  readonly sessions: readonly NativeSessionLike[];
57
63
  }[];
58
64
  export declare function readNativeSidebarTab(raw: string | null): NativeSidebarTab;
59
- export declare function tabForSessionId(sessionId: string | null | undefined): NativeSidebarTab | undefined;
65
+ /** 协作页签(频道/定时)以 registry 为准,不能因 sidebar.channels slot 未就绪就把点击打回任务。 */
66
+ /** 只有当前会话变了才跟随切页签,避免点「定时」时被频道/任务会话打回去闪烁。 */
67
+ export declare function shouldFollowSessionTab(previousCurrent: string | null | undefined, current: string | null | undefined): boolean;
68
+ export declare function ownedSidebarTabIds(input: {
69
+ readonly extraTabIds: readonly string[];
70
+ readonly channelsReady: boolean;
71
+ }): string[];
72
+ export declare function resolveVisibleSidebarTab(input: {
73
+ readonly tab: string;
74
+ readonly channelsReady: boolean;
75
+ readonly extraTabIds: readonly string[];
76
+ }): string;
77
+ export declare function tabForSessionId(sessionId: string | null | undefined, scheduledIds?: ReadonlySet<string>): NativeSidebarTab | undefined;
60
78
  export declare function occupantLooksLikeCodexUi(value: unknown): boolean;
61
79
  export declare function slotOccupantName(item: unknown): string;
62
80
  export declare function hasCodexUiSidebar(entries: readonly unknown[] | undefined): boolean;
@@ -65,14 +83,24 @@ export interface SessionListState {
65
83
  readonly byId?: Record<string, NativeSessionLike>;
66
84
  readonly current?: string | null;
67
85
  }
68
- export declare function filterTaskSessionState<T extends SessionListState>(state: T | undefined): T;
86
+ export declare function filterTaskSessionState<T extends SessionListState>(state: T | undefined, scheduledIds?: ReadonlySet<string>): T;
69
87
  export interface WorkspaceListState {
70
88
  readonly items?: readonly NativeWorkspaceLike[];
71
89
  readonly archivedSessionIds?: readonly string[];
72
90
  }
73
- export declare function openScheduledSession(id: string, openRuntime?: (sessionId: string) => void, openHost?: (sessionId: string) => void): void;
74
- export declare function isHiddenSidebarSessionId(id: string): boolean;
75
- export declare function filterWorkspaceListState<T extends WorkspaceListState>(state: T | undefined): T;
91
+ export declare function openScheduledSession(id: string, openRuntime?: (sessionId: string) => void, openHost?: (sessionId: string) => void): boolean;
92
+ export interface EnsureOpenScheduledSessionInput {
93
+ readonly id: string;
94
+ readonly adopt?: (sessionId: string) => Promise<void>;
95
+ readonly listed?: (sessionId: string) => boolean;
96
+ readonly refresh?: () => Promise<void>;
97
+ readonly openRuntime?: (sessionId: string) => void;
98
+ readonly openHost?: (sessionId: string) => void;
99
+ }
100
+ /** 先把会话挂回工作区并刷新客户端会话簿,再打开;避免侧栏能看见、点下去却 unknown session。 */
101
+ export declare function ensureOpenScheduledSession(input: EnsureOpenScheduledSessionInput): Promise<boolean>;
102
+ export declare function isHiddenSidebarSessionId(id: string, scheduledIds?: ReadonlySet<string>): boolean;
103
+ export declare function filterWorkspaceListState<T extends WorkspaceListState>(state: T | undefined, scheduledIds?: ReadonlySet<string>): T;
76
104
  export type WrapperFlags = {
77
105
  __dshAutomationWrapped?: unknown;
78
106
  __dshAutomationOriginal?: unknown;
@@ -85,3 +113,14 @@ export declare function isMarkedWorkspaceWrapper(component: unknown): boolean;
85
113
  export declare function resolveOfficialTreeComponent(component: unknown): unknown;
86
114
  export declare function isAutomationWorkspaceWrapper(item: unknown): boolean;
87
115
  export declare function pickWrappableWorkspacesEntry(entries: readonly unknown[]): unknown;
116
+ export type WorkspaceGroupMode = 'workspace' | 'list';
117
+ export type WorkspaceListSort = 'manual' | 'time';
118
+ export interface SearchableRailGroup {
119
+ readonly name: string;
120
+ readonly sessions: readonly {
121
+ readonly title?: string;
122
+ readonly label?: string;
123
+ readonly updatedAt?: string;
124
+ }[];
125
+ }
126
+ export declare function applyWorkspaceBrowserQuery<T extends SearchableRailGroup>(groups: readonly T[], query: string, sort: WorkspaceListSort, groupMode?: WorkspaceGroupMode): T[];
@@ -0,0 +1,13 @@
1
+ import type { Translate } from './contracts.js';
2
+ import type { WorkspaceGroupMode, WorkspaceListSort } from './schedule-rail-model.js';
3
+ /** 官方 WorkspaceBrowser:折叠 14px,展开 11px。 */
4
+ export declare function officialSearchIconSize(expanded: boolean): 11 | 14;
5
+ export declare function WorkspaceToolbar({ t, query, sort, groupMode, onQueryChange, onSortChange, onGroupModeChange, }: {
6
+ readonly t: Translate;
7
+ readonly query: string;
8
+ readonly sort: WorkspaceListSort;
9
+ readonly groupMode: WorkspaceGroupMode;
10
+ readonly onQueryChange: (query: string) => void;
11
+ readonly onSortChange: (sort: WorkspaceListSort) => void;
12
+ readonly onGroupModeChange: (mode: WorkspaceGroupMode) => void;
13
+ }): JSX.Element;
@@ -9,11 +9,28 @@ export interface Config {
9
9
  readonly historyLimit?: number;
10
10
  }
11
11
  export declare const Config: any;
12
+ export type SessionApprovalPolicy = 'ask' | 'never';
13
+ export interface ApprovalPolicyReader {
14
+ readonly config?: {
15
+ readonly policy?: SessionApprovalPolicy;
16
+ };
17
+ overrideOf?(session: unknown): SessionApprovalPolicy | undefined;
18
+ }
19
+ /**
20
+ * 读会话审批策略。官方三档对应:
21
+ * Read Only / Workspace Write → ask
22
+ * Full access → never
23
+ */
24
+ export declare function sessionApprovalPolicy(approval: ApprovalPolicyReader | undefined, session: unknown): SessionApprovalPolicy | undefined;
25
+ /**
26
+ * 只在官方 ask 策略下二次确认。never(Full access)再 ask,
27
+ * 会被映射成 “the user rejected tool”,且不会弹窗。
28
+ */
12
29
  export declare function needsHumanApproval(exec: {
13
30
  readonly name: string;
14
31
  readonly arguments?: unknown;
15
32
  readonly signal: AbortSignal;
16
- }, isMountedAgent: boolean): boolean;
33
+ }, isMountedAgent: boolean, policy?: SessionApprovalPolicy): boolean;
17
34
  export declare function humanApprovalReason(toolName: string): string;
18
35
  export declare function apply(ctx: Context, rawConfig: Config): Promise<void>;
19
36
  export type * from './types.ts';
@@ -0,0 +1,6 @@
1
+ /** 给模型看的定时任务入口说明,避免把「定时任务」理解成操作系统 cron。 */
2
+ export declare const AUTOMATION_PROMPT_NAME = "tool:automation";
3
+ export declare const AUTOMATION_PROMPT_ORDER = 118;
4
+ export declare const AUTOMATION_PROMPT_TEXT: string;
5
+ export declare const AUTOMATION_CREATE_DESCRIPTION: string;
6
+ export declare function shouldUseAutomationCreate(userText: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-automation",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "在独立 DSH Session 中按计划执行编码任务,支持 Web 设置页与 Agent 双入口管理。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "files": [
20
20
  "lib",
21
+ "assets",
21
22
  "docs",
22
23
  "cordis.patch.yml",
23
24
  "README.md",
@@ -107,11 +108,6 @@
107
108
  "publishConfig": {
108
109
  "access": "public",
109
110
  "registry": "https://registry.npmjs.org/"
110
- },
111
- "pnpm": {
112
- "onlyBuiltDependencies": [
113
- "esbuild"
114
- ]
115
111
  }
116
112
  }
117
113