@openvulcan/dsh-vulcancode 0.4.3 → 0.4.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.
- package/README.md +30 -5
- package/cordis.patch.yml +2 -0
- package/node_modules/@openvulcan/dsh-decision-guard/lib/client.js +52 -14
- package/node_modules/@openvulcan/dsh-decision-guard/package.json +2 -2
- package/node_modules/@openvulcan/dsh-vulcan-account/package.json +2 -2
- package/node_modules/@openvulcan/dsh-vulcan-answers/lib/client.js +30 -30
- package/node_modules/@openvulcan/dsh-vulcan-answers/lib/committed-fiber.d.ts +18 -0
- package/node_modules/@openvulcan/dsh-vulcan-answers/lib/committed-fiber.js +62 -0
- package/node_modules/@openvulcan/dsh-vulcan-answers/package.json +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-luaskills/package.json +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-memory/assets/markdown-memory-guide.md +1 -0
- package/node_modules/@openvulcan/dsh-vulcan-memory/assets/memory-curator/SKILL.md +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-memory/lib/markdown/errors.d.ts +7 -0
- package/node_modules/@openvulcan/dsh-vulcan-memory/lib/markdown/errors.js +11 -0
- package/node_modules/@openvulcan/dsh-vulcan-memory/lib/markdown/index.d.ts +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-memory/lib/markdown/index.js +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-memory/lib/markdown/operations.js +22 -3
- package/node_modules/@openvulcan/dsh-vulcan-memory/package.json +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-reasoning/package.json +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-style/lib/client.js +4 -0
- package/node_modules/@openvulcan/dsh-vulcan-style/package.json +1 -1
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/LICENSE +21 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/client.js +1567 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/cloud.d.ts +39 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/cloud.js +187 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/contract.d.ts +58 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/contract.js +1 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/index.d.ts +49 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/lib/index.js +204 -0
- package/node_modules/@openvulcan/dsh-vulcan-voice-input/package.json +46 -0
- package/node_modules/@openvulcan/openvulcan-account/package.json +1 -1
- package/node_modules/@openvulcan/vulcan-decision/package.json +2 -2
- package/package.json +13 -11
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
**简体中文** | [English](README.en.md)
|
|
16
16
|
|
|
17
|
-
[特色功能](#特色功能) · [架构与包结构](#架构与包结构) · [快速开始](#快速开始) · [开发](#开发)
|
|
17
|
+
[特色功能](#特色功能) · [界面截图](#界面截图) · [架构与包结构](#架构与包结构) · [快速开始](#快速开始) · [开发](#开发)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -33,16 +33,27 @@ dsh-vulcancode 是 DeepSeek Harness(dsh)的社区插件套件。安装一个
|
|
|
33
33
|
- **工具调用可审查**,Vulcan Decision 在执行前使用云端或本机模型判定,并支持配置复核和人工确认。
|
|
34
34
|
- **技能与经验可复用**,LuaSkills 把技能发布为 AI 可调用的工具,Markdown 长期记忆保留用户、空间和项目经验。
|
|
35
35
|
- **模型可单独配置思考级别**,pi-ai 模型的可选级别和接口传输值可按供应商、按模型设置。
|
|
36
|
+
- **语音输入**使用 OpenVulcan 账号所属站点的免费转写服务,把口述内容插入对话草稿。
|
|
37
|
+
|
|
38
|
+
## 界面截图
|
|
39
|
+
|
|
40
|
+
### 暗色主题 · 工具分类卡片
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
### 指挥舱主题 · 记忆工具验证
|
|
45
|
+
|
|
46
|
+

|
|
36
47
|
|
|
37
48
|
## 架构与包结构
|
|
38
49
|
|
|
39
|
-
dsh 通过套件的 `cordis.patch.yml`
|
|
50
|
+
dsh 通过套件的 `cordis.patch.yml` 装载八个插件。自动审批和语音输入通过 `openvulcanAccount` 获取云端服务所需的凭据。账号插件和判定引擎复用同一账号库。发布包随附工作区依赖,用户只需安装套件。
|
|
40
51
|
|
|
41
52
|
### 套件入口
|
|
42
53
|
|
|
43
54
|
#### `@openvulcan/dsh-vulcancode`
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
套件通过 `dsh.bundle.patch` 声明插件组。dsh 加载各子插件的 `apply(ctx)` 入口,账号插件则导出 Cordis 服务类。安装后可在插件管理页查看套件及其组件。源码在 [packages/dsh-vulcancode](packages/dsh-vulcancode)。
|
|
46
57
|
|
|
47
58
|
### dsh 插件
|
|
48
59
|
|
|
@@ -74,6 +85,10 @@ dsh 通过套件的 `cordis.patch.yml` 装载七个插件。自动审批调用
|
|
|
74
85
|
|
|
75
86
|
在「设置 › 通用设置」的「Vulcan 界面风格」选择跟随系统、亮色、暗色、指挥舱或 dsh 自带主题。直角开关可与任意主题搭配,覆盖 Windows 桌面内容区等界面边角。设置布局为模型目录、内置插件和 LuaSkills 等页面留出更多可用宽度。源码在 [packages/dsh-vulcan-style](packages/dsh-vulcan-style)。
|
|
76
87
|
|
|
88
|
+
#### `@openvulcan/dsh-vulcan-voice-input`
|
|
89
|
+
|
|
90
|
+
登录 OpenVulcan 后,将鼠标移到对话输入框的麦克风按钮,可选择所属站点发布的免费转写模型、优先语言、麦克风和录音快捷键。可在「设置 › OpenVulcan 语音输入」测试麦克风和查看服务状态。录音快捷键支持单独绑定右 Ctrl 等左右修饰键。按住麦克风按钮或在输入框内按住所设快捷键说话,松开后转写内容会回填当前草稿。连续录满 120 秒会自动停止并转写。源码在 [packages/dsh-vulcan-voice-input](packages/dsh-vulcan-voice-input)。
|
|
91
|
+
|
|
77
92
|
### 共享库与命令行
|
|
78
93
|
|
|
79
94
|
#### `@openvulcan/vulcan-decision`
|
|
@@ -88,8 +103,18 @@ dsh 通过套件的 `cordis.patch.yml` 装载七个插件。自动审批调用
|
|
|
88
103
|
|
|
89
104
|
套件声明兼容 dsh `>=0.2.1-rc.2 <0.3.0`。
|
|
90
105
|
|
|
106
|
+
### 桌面版
|
|
107
|
+
|
|
108
|
+
在 dsh 侧栏打开「插件」,点击「添加插件」,在安装框中粘贴以下 npm 包名并安装。
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
@openvulcan/dsh-vulcancode
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 网页版
|
|
115
|
+
|
|
91
116
|
```sh
|
|
92
|
-
dsh plugin add @openvulcan/dsh-vulcancode
|
|
117
|
+
dsh plugin --profile web add @openvulcan/dsh-vulcancode
|
|
93
118
|
```
|
|
94
119
|
|
|
95
120
|
### 使用
|
|
@@ -116,7 +141,7 @@ pnpm run test
|
|
|
116
141
|
pnpm run pack:dsh # 生成 dist/openvulcan-dsh-vulcancode-<版本>.tgz
|
|
117
142
|
```
|
|
118
143
|
|
|
119
|
-
|
|
144
|
+
在网页版配置中安装本地包时,执行 `dsh plugin --profile web add ./dist/openvulcan-dsh-vulcancode-<版本>.tgz`。
|
|
120
145
|
|
|
121
146
|
## 致谢
|
|
122
147
|
|
package/cordis.patch.yml
CHANGED
|
@@ -323,6 +323,7 @@ window.__ModuleLoader__.load({
|
|
|
323
323
|
'status.auto.standalone': '独立开关方式不使用该预设,所有会话都受判定',
|
|
324
324
|
'status.decision.cloud': 'OpenVulcan 云端 · {model}',
|
|
325
325
|
'status.decision.cloudNoModel': 'OpenVulcan 云端 · 没有可用的模型',
|
|
326
|
+
'status.decision.cloudLoadFailed': 'OpenVulcan 云端 · 无法读取判定模型',
|
|
326
327
|
'status.decision.signedOut': 'OpenVulcan 云端 · 未登录,受管控的调用会询问你',
|
|
327
328
|
'status.decision.local': '本机 · {pack} 运行 {model}',
|
|
328
329
|
'status.decision.localMissing': '本机 · 尚未选择运行包与模型,受管控的调用会询问你',
|
|
@@ -680,6 +681,7 @@ window.__ModuleLoader__.load({
|
|
|
680
681
|
'status.auto.standalone': 'The standalone switch does not use the preset; every session is judged',
|
|
681
682
|
'status.decision.cloud': 'OpenVulcan cloud · {model}',
|
|
682
683
|
'status.decision.cloudNoModel': 'OpenVulcan cloud · no model available',
|
|
684
|
+
'status.decision.cloudLoadFailed': 'OpenVulcan cloud · could not load decision models',
|
|
683
685
|
'status.decision.signedOut': 'OpenVulcan cloud · not signed in; governed calls ask you',
|
|
684
686
|
'status.decision.local': 'This machine · {pack} runs {model}',
|
|
685
687
|
'status.decision.localMissing': 'This machine · no runtime pack and model chosen; governed calls ask you',
|
|
@@ -1076,26 +1078,45 @@ window.__ModuleLoader__.load({
|
|
|
1076
1078
|
ctx.effect(() => ctx.locale.register(i18n_1.NAMESPACE, { zh: i18n_1.zh, en: i18n_1.en }), 'vulcan-decision-guard: dictionaries');
|
|
1077
1079
|
ctx.effect(() => {
|
|
1078
1080
|
let accountKey;
|
|
1081
|
+
// A reconnect can keep the same authorization ID while replacing the backend.
|
|
1082
|
+
// 重连可能更换宿主,但仍保留相同的授权标识。
|
|
1083
|
+
let refreshCloud = true;
|
|
1084
|
+
/**
|
|
1085
|
+
* Invalidate account-scoped data and read the new Host state after reconnect or plugin changes.
|
|
1086
|
+
* 重连或插件变更后清除账号相关数据,并读取新的宿主状态。
|
|
1087
|
+
*/
|
|
1079
1088
|
const refreshAll = () => {
|
|
1089
|
+
refreshCloud = true;
|
|
1090
|
+
services.panel.reset();
|
|
1091
|
+
services.cloudModels.reset();
|
|
1092
|
+
services.endpoints.reset();
|
|
1080
1093
|
services.autoReview.refresh();
|
|
1081
1094
|
services.autoListed.refresh();
|
|
1082
1095
|
services.panel.refresh();
|
|
1083
1096
|
};
|
|
1084
1097
|
const stops = [
|
|
1085
|
-
ctx.remote.$on('plugin-manager/changed',
|
|
1098
|
+
ctx.remote.$on('plugin-manager/changed', refreshAll),
|
|
1086
1099
|
ctx.remote.$on('permission-presets/catalog-changed', () => { services.autoListed.refresh(); }),
|
|
1087
1100
|
ctx.on('connection/reset', refreshAll),
|
|
1088
|
-
//
|
|
1101
|
+
// Load the model list when the first signed-in account arrives, without opening any UI.
|
|
1102
|
+
// 首次确认账号已登录时主动加载模型目录,无需打开界面。
|
|
1089
1103
|
services.panel.subscribe(() => {
|
|
1090
1104
|
const account = services.panel.getSnapshot()?.account;
|
|
1091
1105
|
if (account === undefined)
|
|
1092
1106
|
return;
|
|
1093
|
-
const key = account.signedIn ? account.authorizationId ?? '' : null;
|
|
1094
|
-
if (
|
|
1107
|
+
const key = account.signedIn ? `${account.site ?? ''}:${account.authorizationId ?? ''}` : null;
|
|
1108
|
+
if (!refreshCloud && key === accountKey)
|
|
1109
|
+
return;
|
|
1110
|
+
const hadAccount = accountKey !== undefined;
|
|
1111
|
+
accountKey = key;
|
|
1112
|
+
refreshCloud = false;
|
|
1113
|
+
services.cloudModels.reset();
|
|
1114
|
+
services.endpoints.reset();
|
|
1115
|
+
if (account.signedIn) {
|
|
1095
1116
|
services.cloudModels.refresh();
|
|
1096
|
-
|
|
1117
|
+
if (hadAccount)
|
|
1118
|
+
services.endpoints.refresh();
|
|
1097
1119
|
}
|
|
1098
|
-
accountKey = key;
|
|
1099
1120
|
}),
|
|
1100
1121
|
];
|
|
1101
1122
|
refreshAll();
|
|
@@ -1279,8 +1300,8 @@ window.__ModuleLoader__.load({
|
|
|
1279
1300
|
return null;
|
|
1280
1301
|
const governed = value.mode === 'standalone' || permissions?.currentValue === shared_1.AUTO_PRESET;
|
|
1281
1302
|
const unattended = view?.unattended === true;
|
|
1282
|
-
const decision = (0, settings_1.decisionStatus)(t, value, live, models
|
|
1283
|
-
const dot = !governed ? 'off' : decision.tone === 'ok' ? 'ok' : 'warn';
|
|
1303
|
+
const decision = (0, settings_1.decisionStatus)(t, value, live, models);
|
|
1304
|
+
const dot = !governed || decision.tone === 'outline' ? 'off' : decision.tone === 'ok' ? 'ok' : 'warn';
|
|
1284
1305
|
return ((0, jsx_runtime_1.jsxs)("span", { className: "vdg", children: [(0, jsx_runtime_1.jsxs)("button", { ref: anchor, type: "button", className: "vdg-trigger", "aria-haspopup": "dialog", "aria-expanded": open, title: decision.text, onClick: () => {
|
|
1285
1306
|
if (!open) {
|
|
1286
1307
|
services.panel.refresh();
|
|
@@ -1568,16 +1589,25 @@ window.__ModuleLoader__.load({
|
|
|
1568
1589
|
// The sections appear in the same order in navigation and in the page.
|
|
1569
1590
|
// 分区在导航和正文中按同一顺序排列。
|
|
1570
1591
|
const SETTINGS_VIEWS = ['engine', 'policy', 'records'];
|
|
1571
|
-
/**
|
|
1572
|
-
|
|
1592
|
+
/**
|
|
1593
|
+
* Describe the configured backend using the latest account and model-list response.
|
|
1594
|
+
* 使用最新账号和模型目录响应描述已配置的判定后端。
|
|
1595
|
+
*/
|
|
1596
|
+
function decisionStatus(t, value, live, list) {
|
|
1573
1597
|
if (live == null)
|
|
1574
1598
|
return { tone: 'outline', text: t('loading') };
|
|
1575
1599
|
if (value.backend === 'cloud') {
|
|
1576
1600
|
if (!live.account.signedIn)
|
|
1577
1601
|
return { tone: 'warn', text: t('status.decision.signedOut') };
|
|
1578
|
-
|
|
1579
|
-
|
|
1602
|
+
if (list === undefined)
|
|
1603
|
+
return { tone: 'outline', text: t('model.loading') };
|
|
1604
|
+
if (list.kind === 'failed')
|
|
1605
|
+
return { tone: 'warn', text: t('status.decision.cloudLoadFailed') };
|
|
1606
|
+
const model = value.cloudModel === '' ? list.models[0] : value.cloudModel;
|
|
1607
|
+
if (list.models.length === 0 || model === undefined)
|
|
1580
1608
|
return { tone: 'warn', text: t('status.decision.cloudNoModel') };
|
|
1609
|
+
if (!list.models.includes(model))
|
|
1610
|
+
return { tone: 'warn', text: (0, i18n_1.fill)(t('model.disabled'), { model }) };
|
|
1581
1611
|
return { tone: 'ok', text: (0, i18n_1.fill)(t('status.decision.cloud'), { model }) };
|
|
1582
1612
|
}
|
|
1583
1613
|
const pack = live.packs.find(item => item.id === value.localPack && item.installed !== null);
|
|
@@ -1590,7 +1620,7 @@ window.__ModuleLoader__.load({
|
|
|
1590
1620
|
const heldByReview = (0, ui_1.useWatch)(services.autoReview);
|
|
1591
1621
|
const listed = (0, ui_1.useWatch)(services.autoListed);
|
|
1592
1622
|
const models = (0, ui_1.useWatch)(services.cloudModels);
|
|
1593
|
-
const decision = decisionStatus(t, value, live, models
|
|
1623
|
+
const decision = decisionStatus(t, value, live, models);
|
|
1594
1624
|
let auto;
|
|
1595
1625
|
if (value.mode === 'standalone')
|
|
1596
1626
|
auto = { tone: 'outline', text: 'status.auto.standalone', badge: 'tone.off' };
|
|
@@ -1600,7 +1630,7 @@ window.__ModuleLoader__.load({
|
|
|
1600
1630
|
auto = { tone: 'ok', text: 'status.auto.provided', badge: 'tone.ok' };
|
|
1601
1631
|
else
|
|
1602
1632
|
auto = { tone: 'outline', text: 'status.auto.pending', badge: 'status.auto.pending' };
|
|
1603
|
-
return ((0, jsx_runtime_1.jsx)(ui_1.Section, { title: t('status.title'), flush: true, children: (0, jsx_runtime_1.jsxs)("div", { className: "vdg-rows", children: [(0, jsx_runtime_1.jsxs)("div", { className: "vdg-row", children: [(0, jsx_runtime_1.jsx)("span", { className: "vdg-row-label", children: t('status.decision') }), (0, jsx_runtime_1.jsxs)("span", { className: "vdg-row-value", children: [decision.text, (0, jsx_runtime_1.jsx)(ui_1.Badge, { tone: decision.tone, children: t(decision.tone === 'ok' ? 'tone.ok' : 'tone.warn') })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "vdg-row", children: [(0, jsx_runtime_1.jsx)("span", { className: "vdg-row-label", children: t('status.auto') }), (0, jsx_runtime_1.jsxs)("span", { className: "vdg-row-value", children: [t(auto.text), (0, jsx_runtime_1.jsx)(ui_1.Badge, { tone: auto.tone, children: t(auto.badge) })] })] })] }) }));
|
|
1633
|
+
return ((0, jsx_runtime_1.jsx)(ui_1.Section, { title: t('status.title'), flush: true, children: (0, jsx_runtime_1.jsxs)("div", { className: "vdg-rows", children: [(0, jsx_runtime_1.jsxs)("div", { className: "vdg-row", children: [(0, jsx_runtime_1.jsx)("span", { className: "vdg-row-label", children: t('status.decision') }), (0, jsx_runtime_1.jsxs)("span", { className: "vdg-row-value", children: [decision.text, decision.tone === 'outline' ? null : (0, jsx_runtime_1.jsx)(ui_1.Badge, { tone: decision.tone, children: t(decision.tone === 'ok' ? 'tone.ok' : 'tone.warn') })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "vdg-row", children: [(0, jsx_runtime_1.jsx)("span", { className: "vdg-row-label", children: t('status.auto') }), (0, jsx_runtime_1.jsxs)("span", { className: "vdg-row-value", children: [t(auto.text), (0, jsx_runtime_1.jsx)(ui_1.Badge, { tone: auto.tone, children: t(auto.badge) })] })] })] }) }));
|
|
1604
1634
|
}
|
|
1605
1635
|
function OptionsSection({ t, value, disabled, save }) {
|
|
1606
1636
|
const row = (field, prefix, values) => ((0, jsx_runtime_1.jsxs)("div", { className: "vdg-row", children: [(0, jsx_runtime_1.jsx)("span", { children: t(`${prefix}.title`) }), (0, jsx_runtime_1.jsx)(ui_1.Segments, { label: t(`${prefix}.title`), value: value[field], options: values.map(item => ({ value: item, title: t(`${prefix}.${item}`) })), disabled: disabled, onChoose: (next) => { save({ [field]: next }); } })] }));
|
|
@@ -1824,6 +1854,14 @@ window.__ModuleLoader__.load({
|
|
|
1824
1854
|
this.#set(undefined);
|
|
1825
1855
|
});
|
|
1826
1856
|
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Clear the previous Host value and discard reads still in flight, keeping subscribers.
|
|
1859
|
+
* 清除旧宿主值并丢弃未完成的读取,同时保留订阅。
|
|
1860
|
+
*/
|
|
1861
|
+
reset() {
|
|
1862
|
+
++this.#generation;
|
|
1863
|
+
this.#set(undefined);
|
|
1864
|
+
}
|
|
1827
1865
|
/** Stop publishing answers that are still in flight. */
|
|
1828
1866
|
close() {
|
|
1829
1867
|
++this.#generation;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openvulcan/dsh-decision-guard",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Vulcan Decision permission guard for DeepSeek Harness: every tool call is judged before it runs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"icon": "./assets/decision-guard-icon.png",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@openvulcan/vulcan-decision": "0.4.
|
|
47
|
+
"@openvulcan/vulcan-decision": "0.4.4"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@deepseek-ai/cordis": "^4.0.5",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openvulcan/dsh-vulcan-account",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "OpenVulcan account for DeepSeek Harness: sign in once, used by every VulcanCode plugin.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"icon": "./assets/account-icon.png",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@openvulcan/openvulcan-account": "0.4.
|
|
45
|
+
"@openvulcan/openvulcan-account": "0.4.4"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@deepseek-ai/cordis": "^4.0.5",
|