@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/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/lib/client.js +51 -51
- package/lib/client.js.map +3 -3
- package/lib/index.js +67 -10
- package/lib/types/client/AutomationView.d.ts +1 -1
- package/lib/types/client/contracts.d.ts +3 -1
- package/lib/types/client/create-modal.d.ts +6 -1
- package/lib/types/client/helpers.d.ts +2 -2
- package/lib/types/client/locales.d.ts +0 -13
- package/lib/types/client/permissions.d.ts +4 -0
- package/lib/types/client/protocol.d.ts +8 -1
- package/lib/types/executor.d.ts +3 -2
- package/lib/types/index.d.ts +2 -6
- package/lib/types/permission-presets.d.ts +14 -0
- package/lib/types/service.d.ts +10 -0
- package/lib/types/types.d.ts +2 -1
- package/package.json +2 -3
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 =
|
|
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
|
|
21805
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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:
|
|
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:
|
|
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):
|
|
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 =
|
|
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;
|
package/lib/types/executor.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
25
|
-
export declare function
|
|
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>;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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;
|
package/lib/types/service.d.ts
CHANGED
|
@@ -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;
|
package/lib/types/types.d.ts
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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-
|
|
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
|
-
|