@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/README.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://www.npmjs.com/package/@michengai/dsh-automation)
|
|
15
|
+
[](https://www.npmjs.com/package/@michengai/dsh-automation)
|
|
15
16
|
[](https://github.com/MichengAI/dsh-automation)
|
|
16
17
|
[](https://nodejs.org/)
|
|
17
18
|
</div>
|
|
@@ -53,6 +54,17 @@ Run history stays in Settings and can be filtered by day, week, month, task, or
|
|
|
53
54
|
|
|
54
55
|

|
|
55
56
|
|
|
57
|
+
## DSH product ecosystem
|
|
58
|
+
|
|
59
|
+
This product can be installed independently or used through the desktop app or Web suite. They share the same DSH core but serve different ways of working; on stock DSH, this product does not depend on Codex UI:
|
|
60
|
+
|
|
61
|
+
| Product | Relationship to this product |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | The host runtime that provides models, sessions, tools, and the plugin system |
|
|
64
|
+
| [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop) | A ready-to-install desktop product with this product and the other five feature products built in |
|
|
65
|
+
| [DSH Codex Suite](https://github.com/MichengAI/dsh-codex-ui/tree/main/packages/dsh-codex-suite) | A one-click suite for existing DSH Web environments that installs this product and the other five feature products |
|
|
66
|
+
| Six feature products | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) · [IM Connect](https://github.com/MichengAI/dsh-im-connect) · [Automation](https://github.com/MichengAI/dsh-automation) · [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) · [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) · [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) |
|
|
67
|
+
|
|
56
68
|
## Prerequisites
|
|
57
69
|
|
|
58
70
|
- A working DeepSeek Harness Web installation with `dsh` available in PowerShell.
|
|
@@ -72,7 +84,7 @@ dsh plugin --profile web add @michengai/dsh-automation@latest --registry=https:/
|
|
|
72
84
|
dsh --profile web --dump-config
|
|
73
85
|
```
|
|
74
86
|
|
|
75
|
-
Restart DSH Web and hard-refresh the browser. Pin a version with `@0.1.
|
|
87
|
+
Restart DSH Web and hard-refresh the browser. Pin a version with `@0.1.5` instead of `@latest` when needed.
|
|
76
88
|
|
|
77
89
|
### Install from source
|
|
78
90
|
|
|
@@ -156,4 +168,4 @@ pnpm build
|
|
|
156
168
|
|
|
157
169
|
Start from the [documentation entry](docs/00-交接入口/00-阅读导航.md) for project status, architecture, and the current iteration. Product notes live in NOTICE.
|
|
158
170
|
|
|
159
|
-
This project uses [Apache License 2.0](LICENSE).
|
|
171
|
+
This project uses [Apache License 2.0](LICENSE).
|
package/README.zh-CN.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://www.npmjs.com/package/@michengai/dsh-automation)
|
|
15
|
+
[](https://www.npmjs.com/package/@michengai/dsh-automation)
|
|
15
16
|
[](https://github.com/MichengAI/dsh-automation)
|
|
16
17
|
[](https://nodejs.org/)
|
|
17
18
|
</div>
|
|
@@ -53,6 +54,17 @@
|
|
|
53
54
|
|
|
54
55
|

|
|
55
56
|
|
|
57
|
+
## DSH 产品生态
|
|
58
|
+
|
|
59
|
+
本产品既可以独立安装,也可以随桌面端或 Web 套件一起使用。它们共享同一个 DSH 核心,但面向不同的使用方式;在原生 DSH 下,本产品不依赖 Codex UI:
|
|
60
|
+
|
|
61
|
+
| 产品 | 与本产品的关系 |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | 本产品的运行宿主,提供模型、会话、工具和插件系统 |
|
|
64
|
+
| [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop) | 下载安装即用的桌面产品,已内置本产品和其他 5 个功能产品 |
|
|
65
|
+
| [DSH Codex Suite](https://github.com/MichengAI/dsh-codex-ui/tree/main/packages/dsh-codex-suite) | 面向已有 DSH Web 环境的一键套件,会安装本产品和其他 5 个功能产品 |
|
|
66
|
+
| 6 个功能产品 | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) · [IM Connect](https://github.com/MichengAI/dsh-im-connect) · [Automation](https://github.com/MichengAI/dsh-automation) · [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) · [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) · [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) |
|
|
67
|
+
|
|
56
68
|
## 前置条件
|
|
57
69
|
|
|
58
70
|
- 已可正常运行 DeepSeek Harness Web,且可在 PowerShell 中使用 `dsh`。
|
|
@@ -72,7 +84,7 @@ dsh plugin --profile web add @michengai/dsh-automation@latest --registry=https:/
|
|
|
72
84
|
dsh --profile web --dump-config
|
|
73
85
|
```
|
|
74
86
|
|
|
75
|
-
安装后重启 DSH Web,并在浏览器硬刷新。需要钉死某一版时,把 `@latest` 换成 `@0.1.
|
|
87
|
+
安装后重启 DSH Web,并在浏览器硬刷新。需要钉死某一版时,把 `@latest` 换成 `@0.1.5`。
|
|
76
88
|
|
|
77
89
|
### 从源码安装
|
|
78
90
|
|
|
@@ -156,4 +168,4 @@ pnpm build
|
|
|
156
168
|
|
|
157
169
|
项目状态、使用边界、技术架构和迭代记录从[文档交接入口](docs/00-交接入口/00-阅读导航.md)开始。补充说明见 NOTICE。
|
|
158
170
|
|
|
159
|
-
本项目采用 [Apache License 2.0](LICENSE)。
|
|
171
|
+
本项目采用 [Apache License 2.0](LICENSE)。
|
package/lib/client.js
CHANGED
|
@@ -398,6 +398,9 @@ function RunningStateDot() {
|
|
|
398
398
|
var import_react2 = require("react");
|
|
399
399
|
|
|
400
400
|
// src/client/create-modal-logic.ts
|
|
401
|
+
function shouldConfirmFullAccess(current, next) {
|
|
402
|
+
return current !== "full-access" && next === "full-access";
|
|
403
|
+
}
|
|
401
404
|
async function adoptPickedWorkspace(input) {
|
|
402
405
|
const path = await input.pick();
|
|
403
406
|
if (path == null || path.trim() === "") return null;
|
|
@@ -606,6 +609,7 @@ function useMenuState() {
|
|
|
606
609
|
}
|
|
607
610
|
|
|
608
611
|
// src/client/create-modal.tsx
|
|
612
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
609
613
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
610
614
|
var WEEKDAYS = [1, 2, 3, 4, 5, 6, 7];
|
|
611
615
|
var KINDS = ["once", "interval", "hourly", "daily", "weekly", "monthly", "custom"];
|
|
@@ -628,10 +632,29 @@ function CreateModal({
|
|
|
628
632
|
}) {
|
|
629
633
|
const [form, setForm] = (0, import_react2.useState)(() => ({ ...defaultFormState(/* @__PURE__ */ new Date(), workspaces, defaultModel), ...draft }));
|
|
630
634
|
const [validationError, setValidationError] = (0, import_react2.useState)();
|
|
635
|
+
const [confirmingFullAccess, setConfirmingFullAccess] = (0, import_react2.useState)(false);
|
|
636
|
+
const [fullAccessAcknowledged, setFullAccessAcknowledged] = (0, import_react2.useState)(false);
|
|
631
637
|
const update = (patch) => {
|
|
632
638
|
setForm((current) => ({ ...current, ...patch }));
|
|
633
639
|
setValidationError(void 0);
|
|
634
640
|
};
|
|
641
|
+
const choosePermission = (permission) => {
|
|
642
|
+
if (shouldConfirmFullAccess(form.permission, permission)) {
|
|
643
|
+
setFullAccessAcknowledged(false);
|
|
644
|
+
setConfirmingFullAccess(true);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
update({ permission });
|
|
648
|
+
};
|
|
649
|
+
const cancelFullAccessConfirmation = () => {
|
|
650
|
+
setFullAccessAcknowledged(false);
|
|
651
|
+
setConfirmingFullAccess(false);
|
|
652
|
+
};
|
|
653
|
+
const confirmFullAccess = () => {
|
|
654
|
+
if (!fullAccessAcknowledged) return;
|
|
655
|
+
update({ permission: "full-access" });
|
|
656
|
+
cancelFullAccessConfirmation();
|
|
657
|
+
};
|
|
635
658
|
(0, import_react2.useEffect)(() => {
|
|
636
659
|
const onKey = (event) => {
|
|
637
660
|
if (event.key !== "Escape") return;
|
|
@@ -825,7 +848,7 @@ function CreateModal({
|
|
|
825
848
|
{ value: "workspace-write", label: t("form.workspaceWrite"), icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }) },
|
|
826
849
|
{ value: "full-access", label: t("form.fullAccess"), icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }) }
|
|
827
850
|
],
|
|
828
|
-
onChange:
|
|
851
|
+
onChange: choosePermission
|
|
829
852
|
}
|
|
830
853
|
)
|
|
831
854
|
] }),
|
|
@@ -849,7 +872,22 @@ function CreateModal({
|
|
|
849
872
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "dsh-st-btn dsh-st-btn--primary", disabled: busy, children: t("modal.save") })
|
|
850
873
|
] })
|
|
851
874
|
] }),
|
|
852
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-flyout-root", ref: setMenuHost })
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-flyout-root", ref: setMenuHost }),
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
877
|
+
import_dsh_client_ui_primitives.RiskConfirmation,
|
|
878
|
+
{
|
|
879
|
+
open: confirmingFullAccess,
|
|
880
|
+
title: t("access.confirm.title"),
|
|
881
|
+
description: t("access.confirm.description"),
|
|
882
|
+
acknowledgeLabel: t("access.confirm.acknowledge"),
|
|
883
|
+
cancelLabel: t("access.confirm.cancel"),
|
|
884
|
+
confirmLabel: t("access.confirm.enable"),
|
|
885
|
+
acknowledged: fullAccessAcknowledged,
|
|
886
|
+
onAcknowledgedChange: setFullAccessAcknowledged,
|
|
887
|
+
onCancel: cancelFullAccessConfirmation,
|
|
888
|
+
onConfirm: confirmFullAccess
|
|
889
|
+
}
|
|
890
|
+
)
|
|
853
891
|
] }) });
|
|
854
892
|
}
|
|
855
893
|
function ModelPicker({
|
|
@@ -1562,6 +1600,11 @@ var en = {
|
|
|
1562
1600
|
"form.workspaceWrite": "Workspace Write",
|
|
1563
1601
|
"form.fullAccess": "Full access",
|
|
1564
1602
|
"form.workspaceWriteHint": "May change files in this workspace; past approvals are not reused.",
|
|
1603
|
+
"access.confirm.title": "Enable Full access?",
|
|
1604
|
+
"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.",
|
|
1605
|
+
"access.confirm.acknowledge": "I understand the risks and want to continue",
|
|
1606
|
+
"access.confirm.cancel": "Cancel",
|
|
1607
|
+
"access.confirm.enable": "Enable Full access",
|
|
1565
1608
|
"form.cancel": "Cancel",
|
|
1566
1609
|
"form.submit": "Create automation",
|
|
1567
1610
|
"form.submitting": "Creating\u2026",
|
|
@@ -1762,6 +1805,11 @@ var zh = {
|
|
|
1762
1805
|
"form.workspaceWrite": "Workspace Write",
|
|
1763
1806
|
"form.fullAccess": "Full access",
|
|
1764
1807
|
"form.workspaceWriteHint": "\u53EF\u4EE5\u4FEE\u6539\u5F53\u524D\u5DE5\u4F5C\u533A\u6587\u4EF6\uFF1B\u4E0D\u4F1A\u7EE7\u627F\u5386\u53F2\u6279\u51C6\u3002",
|
|
1808
|
+
"access.confirm.title": "\u786E\u8BA4\u542F\u7528 \u5B8C\u5168\u8BBF\u95EE\uFF1F",
|
|
1809
|
+
"access.confirm.description": "\u542F\u7528 \u5B8C\u5168\u8BBF\u95EE \u540E\uFF0Cagent \u5C06\u51CF\u5C11\u786E\u8BA4\u6B65\u9AA4\uFF0C\u5E76\u4E14\u53EF\u4EE5\u76F4\u63A5\u6267\u884C\u66F4\u591A\u64CD\u4F5C\uFF0C\u5305\u62EC\u654F\u611F\u64CD\u4F5C\u3001\u6587\u4EF6\u4FEE\u6539\u6216\u5916\u90E8\u547D\u4EE4\u3002\u4EC5\u5EFA\u8BAE\u5728\u4F60\u4FE1\u4EFB\u5F53\u524D\u4EFB\u52A1\u65F6\u4F7F\u7528\u3002",
|
|
1810
|
+
"access.confirm.acknowledge": "\u6211\u5DF2\u4E86\u89E3\u98CE\u9669\uFF0C\u5E76\u613F\u610F\u7EE7\u7EED",
|
|
1811
|
+
"access.confirm.cancel": "\u53D6\u6D88",
|
|
1812
|
+
"access.confirm.enable": "\u542F\u7528 \u5B8C\u5168\u8BBF\u95EE",
|
|
1765
1813
|
"form.cancel": "\u53D6\u6D88",
|
|
1766
1814
|
"form.submit": "\u521B\u5EFA\u81EA\u52A8\u5316",
|
|
1767
1815
|
"form.submitting": "\u521B\u5EFA\u4E2D\u2026",
|
|
@@ -2021,6 +2069,12 @@ function groupScheduledSessions(automations, runs) {
|
|
|
2021
2069
|
};
|
|
2022
2070
|
}).filter((group) => group.sessions.length > 0);
|
|
2023
2071
|
}
|
|
2072
|
+
function keepScheduledSessionLink(sessionId, archived, presentIds) {
|
|
2073
|
+
if (sessionId === void 0 || sessionId === "") return false;
|
|
2074
|
+
if (archived.has(sessionId)) return false;
|
|
2075
|
+
if (presentIds === void 0) return true;
|
|
2076
|
+
return presentIds.has(sessionId);
|
|
2077
|
+
}
|
|
2024
2078
|
function collectScheduledSessionIds(runs) {
|
|
2025
2079
|
const ids = /* @__PURE__ */ new Set();
|
|
2026
2080
|
for (const run of runs ?? []) {
|
|
@@ -2360,12 +2414,18 @@ function NativeScheduleSessionList(props) {
|
|
|
2360
2414
|
};
|
|
2361
2415
|
}, [runtime]);
|
|
2362
2416
|
const archived = (0, import_react5.useMemo)(() => new Set(archivedIds), [archivedIds]);
|
|
2417
|
+
const listedIds = useSessions ? useSessions((snap) => Array.isArray(snap?.ids) ? snap.ids : void 0) : void 0;
|
|
2418
|
+
const presentIds = (0, import_react5.useMemo)(() => {
|
|
2419
|
+
if (listedIds !== void 0) return new Set(listedIds);
|
|
2420
|
+
const keys = Object.keys(sessionById);
|
|
2421
|
+
return keys.length > 0 ? new Set(keys) : void 0;
|
|
2422
|
+
}, [listedIds, sessionById]);
|
|
2363
2423
|
const groups = (0, import_react5.useMemo)(() => {
|
|
2364
2424
|
const snapshot = state.snapshot;
|
|
2365
2425
|
if (snapshot === void 0) return [];
|
|
2366
2426
|
return groupScheduledSessions(snapshot.automations, snapshot.runs).map((group) => ({
|
|
2367
2427
|
...group,
|
|
2368
|
-
sessions: group.sessions.filter((session) =>
|
|
2428
|
+
sessions: group.sessions.filter((session) => keepScheduledSessionLink(session.id, archived, presentIds)).map((session) => {
|
|
2369
2429
|
const run = snapshot.runs.find((item) => item.sessionId === session.id);
|
|
2370
2430
|
return {
|
|
2371
2431
|
...session,
|
|
@@ -2375,7 +2435,7 @@ function NativeScheduleSessionList(props) {
|
|
|
2375
2435
|
};
|
|
2376
2436
|
})
|
|
2377
2437
|
})).filter((group) => group.sessions.length > 0);
|
|
2378
|
-
}, [archived, sessionById, state.snapshot]);
|
|
2438
|
+
}, [archived, presentIds, sessionById, state.snapshot]);
|
|
2379
2439
|
const visibleGroups = (0, import_react5.useMemo)(() => applyWorkspaceBrowserQuery(groups.map((group) => ({ ...group, name: group.name })), query, sort, groupMode), [groups, query, sort, groupMode]);
|
|
2380
2440
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n", children: [
|
|
2381
2441
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WorkspaceToolbar, { t, query, sort, groupMode, onQueryChange: setQuery, onSortChange: setSort, onGroupModeChange: setGroupMode }),
|