@michengai/dsh-automation 0.1.6 → 0.1.7

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
@@ -123,6 +123,8 @@ async function snapshotValue(service, payload, signal) {
123
123
  models: snapshot.models,
124
124
  defaultModel: snapshot.defaultModel,
125
125
  skills: snapshot.skills,
126
+ permissions: snapshot.permissions,
127
+ defaultPermission: snapshot.defaultPermission,
126
128
  automations: snapshot.definitions.map((definition) => ({
127
129
  id: definition.id,
128
130
  revision: definition.revision,
@@ -21570,7 +21572,7 @@ var automationScheduleSchema = external_exports.discriminatedUnion("kind", [
21570
21572
  timeZone
21571
21573
  })
21572
21574
  ]);
21573
- var permissionPreset = external_exports.enum(["read-only", "workspace-write", "full-access"]);
21575
+ var permissionPreset = nonBlank;
21574
21576
  var creator = external_exports.object({ kind: external_exports.enum(["agent", "web"]), sessionId: nonBlank });
21575
21577
  var targetSnapshot = external_exports.object({
21576
21578
  workspaceId: nonBlank,
@@ -21756,7 +21758,6 @@ function positiveInteger(value, field) {
21756
21758
  // src/executor.ts
21757
21759
  import { installModelSelection } from "@deepseek-ai/dsh-agent";
21758
21760
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
21759
- import { setSandboxMode } from "@deepseek-ai/dsh-sandbox-policy";
21760
21761
  import { SessionId } from "@deepseek-ai/dsh-session";
21761
21762
  import { setApprovalPolicy } from "@deepseek-ai/dsh-user-approval";
21762
21763
  import { WorkspaceId } from "@deepseek-ai/dsh-workspace";
@@ -21801,8 +21802,9 @@ function unattendedToolGuardReason(name2, args) {
21801
21802
  }
21802
21803
  return UNATTENDED_TOOL_ALLOWLIST.has(name2) ? void 0 : `\u5DE5\u5177 '${name2}' \u4E0D\u5728\u65E0\u4EBA\u503C\u5B88\u81EA\u52A8\u5316\u5141\u8BB8\u5217\u8868\u4E2D\u3002`;
21803
21804
  }
21804
- function sandboxModeForPermission(permission) {
21805
- return permission === "full-access" ? "danger-full-access" : permission;
21805
+ function applyUnattendedPermission(presets, session, permission) {
21806
+ presets.set(session, permission);
21807
+ setApprovalPolicy(session, "never");
21806
21808
  }
21807
21809
  function summarizeRun(events, firstSeq) {
21808
21810
  let started = false;
@@ -21873,8 +21875,7 @@ async function executeAutomationRun(ctx, definition, run, config2) {
21873
21875
  installModelSelection(agentCtx, { current: selection, assembled: void 0 });
21874
21876
  const agent = agentCtx.agent;
21875
21877
  if (agent === void 0) throw new Error("automation setup has no scoped Agent");
21876
- setSandboxMode(agent.session, sandboxModeForPermission(target.permissionPreset));
21877
- setApprovalPolicy(agent.session, "never");
21878
+ applyUnattendedPermission(ctx.permissionPresets, agent.session, target.permissionPreset);
21878
21879
  agentCtx.tools.guard((exec) => unattendedToolGuardReason(exec.name, exec.arguments));
21879
21880
  }
21880
21881
  }));
@@ -21974,6 +21975,15 @@ function pinAutomationSessionTitle(ctx, session, title) {
21974
21975
  }
21975
21976
  }
21976
21977
 
21978
+ // src/permission-presets.ts
21979
+ function normalizePermissionPreset(input, names) {
21980
+ if (typeof input !== "string") return void 0;
21981
+ const raw = input.trim();
21982
+ if (raw === "") return void 0;
21983
+ const value = raw === "full-access" ? "danger-full-access" : raw;
21984
+ return names.includes(value) ? value : void 0;
21985
+ }
21986
+
21977
21987
  // src/service.ts
21978
21988
  var MAX_TIMER_DELAY_MS = 2147483647;
21979
21989
  var AUTOMATION_SESSION_PREFIX = "dsh-automation-session-";
@@ -22010,6 +22020,7 @@ var AutomationService = class _AutomationService {
22010
22020
  const service = new _AutomationService(ctx, domain2, config2);
22011
22021
  service.definitions = domain2.table("definitions");
22012
22022
  service.runs = domain2.table("runs");
22023
+ await service.migratePermissionPresets();
22013
22024
  await service.recoverInterruptedRuns();
22014
22025
  await service.reconcileMissingSessions();
22015
22026
  await service.pruneAllHistory();
@@ -22034,6 +22045,19 @@ var AutomationService = class _AutomationService {
22034
22045
  return typeof source === "object" && source !== null && source.kind === "automation";
22035
22046
  });
22036
22047
  }
22048
+ permissionNames() {
22049
+ return this.permissionPresets().names;
22050
+ }
22051
+ permissionOptions() {
22052
+ const presets = this.permissionPresets();
22053
+ return presets.names.map((name2) => presets.optionOf(name2));
22054
+ }
22055
+ defaultPermission() {
22056
+ const presets = this.permissionPresets();
22057
+ const value = normalizePermissionPreset(presets.defaultPreset, presets.names);
22058
+ if (value === void 0) throw new Error("Host \u7684\u9ED8\u8BA4\u6743\u9650\u9884\u8BBE\u4E0D\u5728\u5B98\u65B9\u6743\u9650\u5217\u8868\u4E2D\u3002");
22059
+ return value;
22060
+ }
22037
22061
  async dispose() {
22038
22062
  this.stopping = true;
22039
22063
  this.clearTimer();
@@ -22061,6 +22085,8 @@ var AutomationService = class _AutomationService {
22061
22085
  models: options.models,
22062
22086
  defaultModel: options.defaultModel,
22063
22087
  skills: options.skills,
22088
+ permissions: this.permissionOptions(),
22089
+ defaultPermission: this.defaultPermission(),
22064
22090
  definitions: definitions.map((definition) => ({
22065
22091
  ...definition,
22066
22092
  nextRunAt: definition.status === "active" ? nextOccurrence(definition.schedule, now2) : null,
@@ -22089,7 +22115,7 @@ var AutomationService = class _AutomationService {
22089
22115
  provider: target.provider,
22090
22116
  model: target.model,
22091
22117
  ...request.reasoningEffort === void 0 ? {} : { reasoningEffort: request.reasoningEffort },
22092
- permissionPreset: request.permissionPreset ?? "read-only",
22118
+ permissionPreset: this.requirePermission(request.permissionPreset),
22093
22119
  createdBy: { kind: scope.creatorKind, sessionId: scope.sessionId },
22094
22120
  now: now2
22095
22121
  });
@@ -22105,11 +22131,12 @@ var AutomationService = class _AutomationService {
22105
22131
  throwIfCancelled(signal);
22106
22132
  const now2 = toIso();
22107
22133
  const { status, ...fields } = input;
22134
+ const normalizedFields = fields.permissionPreset === void 0 ? fields : { ...fields, permissionPreset: this.requirePermission(fields.permissionPreset) };
22108
22135
  if (fields.schedule?.kind === "once" && nextOccurrence(fields.schedule, now2) === null) {
22109
22136
  throw new Error("\u4E00\u6B21\u6027\u81EA\u52A8\u5316\u5FC5\u987B\u5B89\u6392\u5728\u672A\u6765\u65F6\u95F4\u3002");
22110
22137
  }
22111
22138
  const statusChanged = status !== void 0 && status !== current.status;
22112
- const value = Object.keys(fields).length === 0 && !statusChanged ? current : updateDefinition(current, { ...fields, ...status === void 0 ? {} : { status }, now: now2 });
22139
+ const value = Object.keys(normalizedFields).length === 0 && !statusChanged ? current : updateDefinition(current, { ...normalizedFields, ...status === void 0 ? {} : { status }, now: now2 });
22113
22140
  if (value !== current) await this.definitions.put(id, value);
22114
22141
  return value;
22115
22142
  }, signal);
@@ -22466,6 +22493,34 @@ var AutomationService = class _AutomationService {
22466
22493
  });
22467
22494
  return result;
22468
22495
  }
22496
+ permissionPresets() {
22497
+ return this.ctx.permissionPresets;
22498
+ }
22499
+ requirePermission(input) {
22500
+ const presets = this.permissionPresets();
22501
+ if (input === void 0) return this.defaultPermission();
22502
+ const value = normalizePermissionPreset(input, presets.names);
22503
+ if (value === void 0) throw new Error(`unknown permission preset '${input}'`);
22504
+ return value;
22505
+ }
22506
+ /** 把旧版 full-access 及已移除的预设收敛到 Host 当前可用列表。 */
22507
+ async migratePermissionPresets() {
22508
+ const presets = this.permissionPresets();
22509
+ const fallback = this.defaultPermission();
22510
+ for (const [id, definition] of this.definitions.entries()) {
22511
+ const permissionPreset2 = normalizePermissionPreset(definition.permissionPreset, presets.names) ?? fallback;
22512
+ if (permissionPreset2 === definition.permissionPreset) continue;
22513
+ await this.definitions.put(id, { ...definition, permissionPreset: permissionPreset2 });
22514
+ }
22515
+ for (const [id, run] of this.runs.entries()) {
22516
+ const permissionPreset2 = normalizePermissionPreset(run.targetSnapshot.permissionPreset, presets.names) ?? fallback;
22517
+ if (permissionPreset2 === run.targetSnapshot.permissionPreset) continue;
22518
+ await this.runs.put(id, {
22519
+ ...run,
22520
+ targetSnapshot: { ...run.targetSnapshot, permissionPreset: permissionPreset2 }
22521
+ });
22522
+ }
22523
+ }
22469
22524
  async recoverInterruptedRuns() {
22470
22525
  const finishedAt = toIso();
22471
22526
  for (const [id, run] of this.runs.entries()) {
@@ -22633,6 +22688,7 @@ function scheduleFromArgs(args, now2) {
22633
22688
  }
22634
22689
  function registerAutomationTools(service, agent) {
22635
22690
  const scope = { sessionId: agent.id, creatorKind: "agent" };
22691
+ const permissionNames = [...service.permissionNames()];
22636
22692
  const disposers = [];
22637
22693
  const register = (definition) => {
22638
22694
  disposers.push(agent.ctx.tools.register(definition));
@@ -22650,7 +22706,7 @@ function registerAutomationTools(service, agent) {
22650
22706
  every_minutes: { type: "integer", description: "\u95F4\u9694\u8BA1\u5212\u7684\u5206\u949F\u6570\uFF0C\u6700\u5C0F 5\u3002" },
22651
22707
  time: { type: "string", description: "\u6BCF\u5929\u6216\u6BCF\u5468\u8BA1\u5212\u7684\u672C\u5730 HH:mm\u3002" },
22652
22708
  weekdays: { type: "array", items: { type: "string", enum: WEEKDAYS2 } },
22653
- permission: { type: "string", enum: ["read-only", "workspace-write", "full-access"] }
22709
+ permission: { type: "string", enum: permissionNames }
22654
22710
  },
22655
22711
  output: JSON_OUTPUT,
22656
22712
  async execute(args, exec) {
@@ -22706,7 +22762,7 @@ function registerAutomationTools(service, agent) {
22706
22762
  every_minutes: { type: "integer" },
22707
22763
  time: { type: "string" },
22708
22764
  weekdays: { type: "array", items: { type: "string", enum: WEEKDAYS2 } },
22709
- permission: { type: "string", enum: ["read-only", "workspace-write", "full-access"] }
22765
+ permission: { type: "string", enum: permissionNames }
22710
22766
  },
22711
22767
  output: JSON_OUTPUT,
22712
22768
  async execute(args, exec) {
@@ -22796,6 +22852,7 @@ var inject = [
22796
22852
  "workspaceRegistry",
22797
22853
  "agentDefaultModel",
22798
22854
  "agentPresets",
22855
+ "permissionPresets",
22799
22856
  "tools",
22800
22857
  "connection",
22801
22858
  "llm"
@@ -1,2 +1,2 @@
1
1
  import type { AutomationViewProps } from './contracts.js';
2
- export declare function AutomationView({ t, runtime, closeSettings, pickWorkspaceDirectory }: AutomationViewProps): JSX.Element;
2
+ export declare function AutomationView({ t, permissionT, runtime, closeSettings, pickWorkspaceDirectory }: AutomationViewProps): JSX.Element;
@@ -1,9 +1,11 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
2
  import type { AutomationLocaleKey } from './locales.js';
3
3
  import type { AutomationRuntime } from './runtime.js';
4
+ import type { PermissionTranslate } from './permissions.js';
4
5
  export type Translate = (key: AutomationLocaleKey, params?: Record<string, unknown>) => string;
5
6
  export interface AutomationViewProps {
6
7
  readonly t: Translate;
8
+ readonly permissionT: PermissionTranslate;
7
9
  readonly runtime: AutomationRuntime;
8
10
  readonly closeSettings?: () => void;
9
11
  readonly pickWorkspaceDirectory?: () => Promise<string | null>;
@@ -49,7 +51,7 @@ export interface ClientContext {
49
51
  readonly zh: Record<string, string>;
50
52
  readonly en: Record<string, string>;
51
53
  }): () => void;
52
- bind(namespace: string): Translate;
54
+ bind(namespace: string): (key: string, params?: Record<string, unknown>) => string;
53
55
  };
54
56
  slots: {
55
57
  inject(name: string, register: () => void | (() => void)): void;
@@ -1,7 +1,10 @@
1
1
  import type { Translate } from './contracts.js';
2
+ import type { PermissionOption } from './protocol.js';
3
+ import { type PermissionTranslate } from './permissions.js';
2
4
  import { type AutomationFormState } from './helpers.js';
3
- export declare function CreateModal({ t, busy, workspaces, models, defaultModel, skills, draft, editing, onClose, onSubmit, onAddWorkspace, pickWorkspaceDirectory, }: {
5
+ export declare function CreateModal({ t, permissionT, busy, workspaces, models, defaultModel, skills, permissions, defaultPermission, draft, editing, onClose, onSubmit, onAddWorkspace, pickWorkspaceDirectory, }: {
4
6
  readonly t: Translate;
7
+ readonly permissionT: PermissionTranslate;
5
8
  readonly busy: boolean;
6
9
  readonly workspaces: readonly {
7
10
  id: string;
@@ -22,6 +25,8 @@ export declare function CreateModal({ t, busy, workspaces, models, defaultModel,
22
25
  id: string;
23
26
  name: string;
24
27
  }[];
28
+ readonly permissions: readonly PermissionOption[];
29
+ readonly defaultPermission: string;
25
30
  readonly draft?: Partial<AutomationFormState>;
26
31
  readonly editing?: boolean;
27
32
  readonly onClose: () => void;
@@ -35,7 +35,7 @@ export declare function insertSkillGesture(prompt: string, token: string, caret:
35
35
  readonly caret: number;
36
36
  };
37
37
  export declare function localDateTimeValue(date?: Date): string;
38
- export declare function defaultFormState(now?: Date, workspaces?: readonly WorkspaceOption[], defaultModel?: ModelOption | null): AutomationFormState;
38
+ export declare function defaultFormState(now?: Date, workspaces?: readonly WorkspaceOption[], defaultModel?: ModelOption | null, defaultPermission?: string): AutomationFormState;
39
39
  export declare function buildCreateInput(form: AutomationFormState, workspaces: readonly WorkspaceOption[], models: readonly ModelOption[], now?: Date, options?: {
40
40
  readonly allowPastOnce?: boolean;
41
41
  }): CreateAutomationInput;
@@ -63,5 +63,5 @@ export interface HistoryGroup {
63
63
  readonly items: readonly import('./protocol.js').AutomationRunViewModel[];
64
64
  }
65
65
  export declare function groupHistory(runs: readonly import('./protocol.js').AutomationRunViewModel[], range: HistoryRange, now: Date, t: Translate): HistoryGroup[];
66
- export declare function formFromAutomation(item: import('./protocol.js').AutomationViewModel, workspaces?: readonly WorkspaceOption[], defaultModel?: ModelOption | null): AutomationFormState;
66
+ export declare function formFromAutomation(item: import('./protocol.js').AutomationViewModel, workspaces?: readonly WorkspaceOption[], defaultModel?: ModelOption | null, defaultPermission?: string): AutomationFormState;
67
67
  export declare function prettyModelName(model: string): string;
@@ -134,16 +134,6 @@ export declare const en: {
134
134
  readonly 'form.days': "Weekdays";
135
135
  readonly 'form.timeZone': "Time zone";
136
136
  readonly 'form.permission': "Permission boundary";
137
- readonly 'form.readOnly': "Read Only";
138
- readonly 'form.readOnlyHint': "Inspect the workspace without changing files.";
139
- readonly 'form.workspaceWrite': "Workspace Write";
140
- readonly 'form.fullAccess': "Full access";
141
- readonly 'form.workspaceWriteHint': "May change files in this workspace; past approvals are not reused.";
142
- readonly 'access.confirm.title': "Enable Full access?";
143
- readonly 'access.confirm.description': "Full access reduces confirmation steps and allows the Agent to directly perform more operations, including sensitive operations, file changes, or external commands. Use it only when you trust this task.";
144
- readonly 'access.confirm.acknowledge': "I understand the risks and want to continue";
145
- readonly 'access.confirm.cancel': "Cancel";
146
- readonly 'access.confirm.enable': "Enable Full access";
147
137
  readonly 'form.cancel': "Cancel";
148
138
  readonly 'form.submit': "Create automation";
149
139
  readonly 'form.submitting': "Creating…";
@@ -171,9 +161,6 @@ export declare const en: {
171
161
  readonly 'card.nextRun': "Next";
172
162
  readonly 'card.lastRun': "Last";
173
163
  readonly 'card.never': "Not yet run";
174
- readonly 'card.permission.read-only': "Read-only";
175
- readonly 'card.permission.workspace-write': "Workspace write";
176
- readonly 'card.permission.full-access': "Full access";
177
164
  readonly 'schedule.onceAt': "Once · {time}";
178
165
  readonly 'schedule.everyMinutes': "Every {count} minutes";
179
166
  readonly 'schedule.dailyAt': "Daily · {time}";
@@ -0,0 +1,4 @@
1
+ import type { PermissionOption } from './protocol.js';
2
+ export type PermissionTranslate = (key: string, params?: Record<string, unknown>) => string;
3
+ /** 与 Chat 一致:只本地化官方内置原名,自定义预设保留 Host 提供的名称。 */
4
+ export declare function permissionLabel(option: PermissionOption, t: PermissionTranslate): string;
@@ -1,7 +1,12 @@
1
1
  /** Web 客户端与 Host RPC 共享的 JSON 契约。 */
2
2
  export type AutomationStatus = 'active' | 'paused';
3
3
  export type AutomationRunStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'skipped' | 'cancelled' | 'interrupted';
4
- export type AutomationPermission = 'read-only' | 'workspace-write' | 'full-access';
4
+ export type AutomationPermission = string;
5
+ export interface PermissionOption {
6
+ readonly value: string;
7
+ readonly name: string;
8
+ readonly description?: string;
9
+ }
5
10
  export type AutomationSchedule = {
6
11
  readonly kind: 'once';
7
12
  readonly at: string;
@@ -93,6 +98,8 @@ export interface AutomationSnapshot {
93
98
  readonly id: string;
94
99
  readonly name: string;
95
100
  }[];
101
+ readonly permissions: readonly PermissionOption[];
102
+ readonly defaultPermission: string;
96
103
  readonly automations: readonly AutomationViewModel[];
97
104
  readonly runs: readonly AutomationRunViewModel[];
98
105
  readonly serverNow: string;
@@ -1,5 +1,6 @@
1
1
  /** 已认领 run 的独立 Agent 执行边界。 */
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
+ import type { PermissionPresetService } from './permission-presets.ts';
3
4
  import type { AutomationDefinition, AutomationRun } from './types.ts';
4
5
  interface SessionEventLike {
5
6
  readonly seq: number;
@@ -21,8 +22,8 @@ export interface ExecutorConfig {
21
22
  readonly sessionId: string;
22
23
  readonly signal?: AbortSignal;
23
24
  }
24
- /** 自动化权限名称与 DSH 沙箱事件名称不同,必须在写入会话前转换。 */
25
- export declare function sandboxModeForPermission(permission: AutomationDefinition['permissionPreset']): 'read-only' | 'workspace-write' | 'danger-full-access';
25
+ /** 先应用官方预设的完整语义,再让无人值守审批 fail-closed。 */
26
+ export declare function applyUnattendedPermission(presets: PermissionPresetService, session: unknown, permission: AutomationDefinition['permissionPreset']): void;
26
27
  export declare function summarizeRun(events: readonly SessionEventLike[], firstSeq: number): {
27
28
  readonly text: string;
28
29
  readonly reason?: Record<string, any>;
@@ -16,14 +16,10 @@ export interface ApprovalPolicyReader {
16
16
  };
17
17
  overrideOf?(session: unknown): SessionApprovalPolicy | undefined;
18
18
  }
19
- /**
20
- * 读会话审批策略。官方三档对应:
21
- * Read Only / Workspace Write → ask
22
- * Full access → never
23
- */
19
+ /** 读取当前会话实际审批策略;自定义权限预设也以 Host 投影结果为准。 */
24
20
  export declare function sessionApprovalPolicy(approval: ApprovalPolicyReader | undefined, session: unknown): SessionApprovalPolicy | undefined;
25
21
  /**
26
- * 只在官方 ask 策略下二次确认。never(Full access)再 ask,
22
+ * 只在实际 ask 策略下二次确认。never 策略再 ask,
27
23
  * 会被映射成 “the user rejected tool”,且不会弹窗。
28
24
  */
29
25
  export declare function needsHumanApproval(exec: {
@@ -0,0 +1,14 @@
1
+ /** Host 官方权限预设服务的最小结构契约。 */
2
+ export interface PermissionOption {
3
+ readonly value: string;
4
+ readonly name: string;
5
+ readonly description?: string;
6
+ }
7
+ export interface PermissionPresetService {
8
+ readonly names: readonly string[];
9
+ readonly defaultPreset: string;
10
+ optionOf(name: string): PermissionOption;
11
+ set(session: unknown, name: string): void;
12
+ }
13
+ /** 兼容旧版插件曾保存的 full-access 名称,其余值必须来自 Host 当前列表。 */
14
+ export declare function normalizePermissionPreset(input: unknown, names: readonly string[]): string | undefined;
@@ -1,5 +1,6 @@
1
1
  /** 持久化定义、occurrence 认领、时钟与执行调度。 */
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
+ import { type PermissionOption } from './permission-presets.ts';
3
4
  import type { AutomationDefinition, AutomationRun, AutomationSchedule, PermissionPreset, UpdateAutomationInput } from './types.ts';
4
5
  export declare const AUTOMATION_SESSION_PREFIX = "dsh-automation-session-";
5
6
  export interface AutomationConfig {
@@ -45,6 +46,8 @@ export interface AutomationSnapshot {
45
46
  readonly id: string;
46
47
  readonly name: string;
47
48
  }[];
49
+ readonly permissions: readonly PermissionOption[];
50
+ readonly defaultPermission: string;
48
51
  readonly definitions: readonly AutomationDefinitionView[];
49
52
  readonly runs: readonly AutomationRun[];
50
53
  }
@@ -73,6 +76,9 @@ export declare class AutomationService {
73
76
  static open(ctx: Context, config: AutomationConfig): Promise<AutomationService>;
74
77
  start(): void;
75
78
  ownsSession(sessionId: string, events?: readonly SessionEventLike[]): boolean;
79
+ permissionNames(): readonly string[];
80
+ permissionOptions(): readonly PermissionOption[];
81
+ defaultPermission(): string;
76
82
  dispose(): Promise<void>;
77
83
  snapshot(scope: AutomationScope, signal?: AbortSignal): Promise<AutomationSnapshot>;
78
84
  create(scope: AutomationScope, request: CreateRequest, signal?: AbortSignal): Promise<AutomationDefinition>;
@@ -105,6 +111,10 @@ export declare class AutomationService {
105
111
  private armRetryTimer;
106
112
  private clearTimer;
107
113
  private serialize;
114
+ private permissionPresets;
115
+ private requirePermission;
116
+ /** 把旧版 full-access 及已移除的预设收敛到 Host 当前可用列表。 */
117
+ private migratePermissionPresets;
108
118
  private recoverInterruptedRuns;
109
119
  private pruneWorkspaceHistory;
110
120
  private pruneAllHistory;
@@ -1,7 +1,8 @@
1
1
  export type AutomationStatus = 'active' | 'paused';
2
2
  export type AutomationRunStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'skipped' | 'cancelled';
3
3
  export type Weekday = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU';
4
- export type PermissionPreset = 'read-only' | 'workspace-write' | 'full-access';
4
+ /** 权限预设名称由 Host 的 permissionPresets 服务动态提供。 */
5
+ export type PermissionPreset = string;
5
6
  export interface OnceSchedule {
6
7
  readonly kind: 'once';
7
8
  readonly at: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-automation",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "在独立 DSH Session 中按计划执行编码任务,支持 Web 设置页与 Agent 双入口管理。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -74,7 +74,7 @@
74
74
  "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.5 <0.2.0",
75
75
  "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.5 <0.2.0",
76
76
  "@deepseek-ai/dsh-llm": ">=0.1.0-rc.5 <0.2.0",
77
- "@deepseek-ai/dsh-sandbox-policy": ">=0.1.0-rc.5 <0.2.0",
77
+ "@deepseek-ai/dsh-permission-presets": ">=0.1.0-rc.5 <0.2.0",
78
78
  "@deepseek-ai/dsh-session": ">=0.1.0-rc.5 <0.2.0",
79
79
  "@deepseek-ai/dsh-storage-domain": ">=0.1.0-rc.5 <0.2.0",
80
80
  "@deepseek-ai/dsh-tools": ">=0.1.0-rc.5 <0.2.0",
@@ -110,4 +110,3 @@
110
110
  "registry": "https://registry.npmjs.org/"
111
111
  }
112
112
  }
113
-