@michengai/dsh-automation 0.1.4 → 0.1.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/README.md +14 -2
- package/README.zh-CN.md +14 -2
- package/lib/client.js +64 -4
- package/lib/client.js.map +2 -2
- package/lib/index.js +39 -2
- package/lib/types/client/create-modal-logic.d.ts +3 -0
- package/lib/types/client/locales.d.ts +5 -0
- package/lib/types/client/schedule-rail-model.d.ts +2 -0
- package/lib/types/executor.d.ts +2 -0
- package/lib/types/service.d.ts +2 -0
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -21801,6 +21801,9 @@ function unattendedToolGuardReason(name2, args) {
|
|
|
21801
21801
|
}
|
|
21802
21802
|
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
21803
|
}
|
|
21804
|
+
function sandboxModeForPermission(permission) {
|
|
21805
|
+
return permission === "full-access" ? "danger-full-access" : permission;
|
|
21806
|
+
}
|
|
21804
21807
|
function summarizeRun(events, firstSeq) {
|
|
21805
21808
|
let started = false;
|
|
21806
21809
|
let text = "";
|
|
@@ -21870,7 +21873,7 @@ async function executeAutomationRun(ctx, definition, run, config2) {
|
|
|
21870
21873
|
installModelSelection(agentCtx, { current: selection, assembled: void 0 });
|
|
21871
21874
|
const agent = agentCtx.agent;
|
|
21872
21875
|
if (agent === void 0) throw new Error("automation setup has no scoped Agent");
|
|
21873
|
-
|
|
21876
|
+
setSandboxMode(agent.session, sandboxModeForPermission(target.permissionPreset));
|
|
21874
21877
|
setApprovalPolicy(agent.session, "never");
|
|
21875
21878
|
agentCtx.tools.guard((exec) => unattendedToolGuardReason(exec.name, exec.arguments));
|
|
21876
21879
|
}
|
|
@@ -22008,6 +22011,7 @@ var AutomationService = class _AutomationService {
|
|
|
22008
22011
|
service.definitions = domain2.table("definitions");
|
|
22009
22012
|
service.runs = domain2.table("runs");
|
|
22010
22013
|
await service.recoverInterruptedRuns();
|
|
22014
|
+
await service.reconcileMissingSessions();
|
|
22011
22015
|
await service.pruneAllHistory();
|
|
22012
22016
|
return service;
|
|
22013
22017
|
} catch (error51) {
|
|
@@ -22167,6 +22171,32 @@ var AutomationService = class _AutomationService {
|
|
|
22167
22171
|
}
|
|
22168
22172
|
});
|
|
22169
22173
|
}
|
|
22174
|
+
async reconcileMissingSessions() {
|
|
22175
|
+
const known = await this.knownSessionIds();
|
|
22176
|
+
if (known === void 0) return;
|
|
22177
|
+
await this.serialize(async () => {
|
|
22178
|
+
for (const [runId, run] of this.runs.entries()) {
|
|
22179
|
+
if (typeof run.sessionId !== "string" || run.sessionId === "") continue;
|
|
22180
|
+
if (known.has(run.sessionId)) continue;
|
|
22181
|
+
await this.runs.put(runId, { ...run, sessionId: null });
|
|
22182
|
+
}
|
|
22183
|
+
});
|
|
22184
|
+
}
|
|
22185
|
+
async knownSessionIds() {
|
|
22186
|
+
const live = this.ctx.sessions;
|
|
22187
|
+
const persistence = this.ctx.get?.("sessionPersistence");
|
|
22188
|
+
const canListLive = typeof live?.list === "function";
|
|
22189
|
+
const canListStored = typeof persistence?.list === "function";
|
|
22190
|
+
if (!canListLive && !canListStored) return void 0;
|
|
22191
|
+
const ids = /* @__PURE__ */ new Set();
|
|
22192
|
+
if (canListLive && live?.list !== void 0) {
|
|
22193
|
+
for (const session of live.list()) ids.add(String(session.id));
|
|
22194
|
+
}
|
|
22195
|
+
if (canListStored && persistence?.list !== void 0) {
|
|
22196
|
+
for (const header of await persistence.list()) ids.add(String(header.id));
|
|
22197
|
+
}
|
|
22198
|
+
return ids;
|
|
22199
|
+
}
|
|
22170
22200
|
async forgetAutomationSessions(automationId) {
|
|
22171
22201
|
const id = automationId.trim();
|
|
22172
22202
|
if (id === "") return;
|
|
@@ -22819,13 +22849,15 @@ async function apply(ctx, rawConfig) {
|
|
|
22819
22849
|
};
|
|
22820
22850
|
let stopPrompt = () => {
|
|
22821
22851
|
};
|
|
22852
|
+
let stopSessionGone = () => {
|
|
22853
|
+
};
|
|
22822
22854
|
let removeRpc = async () => {
|
|
22823
22855
|
};
|
|
22824
22856
|
const cleanup = async () => {
|
|
22825
22857
|
if (cleaned) return;
|
|
22826
22858
|
cleaned = true;
|
|
22827
22859
|
alive = false;
|
|
22828
|
-
for (const stop of [stopCreated, stopDisposed, stopApproval, stopPrompt]) {
|
|
22860
|
+
for (const stop of [stopCreated, stopDisposed, stopApproval, stopPrompt, stopSessionGone]) {
|
|
22829
22861
|
try {
|
|
22830
22862
|
stop();
|
|
22831
22863
|
} catch (error51) {
|
|
@@ -22861,6 +22893,11 @@ async function apply(ctx, rawConfig) {
|
|
|
22861
22893
|
stopDisposed = ctx.on("agent/disposed", ({ agent }) => {
|
|
22862
22894
|
agentTools.delete(agent);
|
|
22863
22895
|
});
|
|
22896
|
+
stopSessionGone = ctx.on("session/disposed", (session) => {
|
|
22897
|
+
const id = String(session?.id ?? "");
|
|
22898
|
+
if (id === "") return;
|
|
22899
|
+
void service.forgetSession(id);
|
|
22900
|
+
});
|
|
22864
22901
|
const systemPrompt = ctx.get("systemPrompt");
|
|
22865
22902
|
if (typeof systemPrompt?.section === "function") {
|
|
22866
22903
|
stopPrompt = systemPrompt.section({
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { AutomationPermission } from './protocol.js';
|
|
1
2
|
/** 新建/编辑弹窗只允许取消或 ESC 关闭,点旁边不能关。 */
|
|
2
3
|
export declare function shouldCloseCreateModal(reason: 'backdrop' | 'escape' | 'cancel'): boolean;
|
|
4
|
+
/** 只有从非完全访问切换到完全访问时才需要风险确认。 */
|
|
5
|
+
export declare function shouldConfirmFullAccess(current: AutomationPermission, next: AutomationPermission): boolean;
|
|
3
6
|
/** 和 Chat 一样:先选目录,取消则不登记;没有手输路径这条路。 */
|
|
4
7
|
export declare function adoptPickedWorkspace(input: {
|
|
5
8
|
readonly pick: () => Promise<string | null>;
|
|
@@ -139,6 +139,11 @@ export declare const en: {
|
|
|
139
139
|
readonly 'form.workspaceWrite': "Workspace Write";
|
|
140
140
|
readonly 'form.fullAccess': "Full access";
|
|
141
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";
|
|
142
147
|
readonly 'form.cancel': "Cancel";
|
|
143
148
|
readonly 'form.submit': "Create automation";
|
|
144
149
|
readonly 'form.submitting': "Creating…";
|
|
@@ -44,6 +44,8 @@ export declare function groupScheduledSessions(automations: readonly {
|
|
|
44
44
|
readonly id: string;
|
|
45
45
|
readonly name: string;
|
|
46
46
|
}[], runs: readonly ScheduleRunLike[]): ScheduleRailGroup[];
|
|
47
|
+
/** 归档中的、以及宿主已经不认识的 Session,都不应再出现在定时页。 */
|
|
48
|
+
export declare function keepScheduledSessionLink(sessionId: string | undefined, archived: ReadonlySet<string>, presentIds?: ReadonlySet<string>): boolean;
|
|
47
49
|
export declare function collectScheduledSessionIds(runs: readonly {
|
|
48
50
|
readonly sessionId?: string | null;
|
|
49
51
|
}[] | undefined): Set<string>;
|
package/lib/types/executor.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface ExecutorConfig {
|
|
|
21
21
|
readonly sessionId: string;
|
|
22
22
|
readonly signal?: AbortSignal;
|
|
23
23
|
}
|
|
24
|
+
/** 自动化权限名称与 DSH 沙箱事件名称不同,必须在写入会话前转换。 */
|
|
25
|
+
export declare function sandboxModeForPermission(permission: AutomationDefinition['permissionPreset']): 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
24
26
|
export declare function summarizeRun(events: readonly SessionEventLike[], firstSeq: number): {
|
|
25
27
|
readonly text: string;
|
|
26
28
|
readonly reason?: Record<string, any>;
|
package/lib/types/service.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export declare class AutomationService {
|
|
|
86
86
|
runNow(scope: AutomationScope, id: string, signal?: AbortSignal): Promise<AutomationRun>;
|
|
87
87
|
markRead(scope: AutomationScope, runId: string, signal?: AbortSignal): Promise<AutomationRun>;
|
|
88
88
|
forgetSession(sessionId: string): Promise<void>;
|
|
89
|
+
reconcileMissingSessions(): Promise<void>;
|
|
90
|
+
private knownSessionIds;
|
|
89
91
|
forgetAutomationSessions(automationId: string): Promise<void>;
|
|
90
92
|
adoptSession(sessionId: string): Promise<void>;
|
|
91
93
|
addWorkspace(path: string): Promise<WorkspaceOption>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-automation",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "在独立 DSH Session 中按计划执行编码任务,支持 Web 设置页与 Agent 双入口管理。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"lib",
|
|
21
|
-
"assets",
|
|
21
|
+
"assets",
|
|
22
22
|
"docs",
|
|
23
23
|
"cordis.patch.yml",
|
|
24
24
|
"README.md",
|
|
@@ -110,4 +110,4 @@
|
|
|
110
110
|
"registry": "https://registry.npmjs.org/"
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
|