@dsh-plus/agent-preset-rea 0.1.0 → 0.1.1

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.
@@ -1,7 +1,9 @@
1
1
  /**
2
- * 配置卡片样式:基础规则走 @dsh-plus/shared/client 的 cardCss('apr'),
3
- * 本文件只补插件特有规则(提示词多行输入框)。
2
+ * 配置卡片样式:基础规则走 @dsh-plus/shared/client 的 cardCss('apr')
3
+ * (按钮/字段/徽标等类名由共享控件生成,本文件**不**重复定义),这里只补
4
+ * 插件特有规则:提示词多行框、安装状态表、作业进度条与日志。
4
5
  * 沿用官方 data-plugin / data-plugin-css 约定(HMR 据此卸载)。
6
+ * 颜色与度量全部走官方主题变量(--dsw-alias-*),不写死色值。
5
7
  * @module agent-preset-rea/client/styles
6
8
  */
7
9
  import { cardCss, injectCardStyle } from '@dsh-plus/shared/client'
@@ -12,6 +14,9 @@ export const PLUGIN_ID = '@dsh-plus/agent-preset-rea'
12
14
  * 多行提示词输入框:度量对齐官方 settings-form 的 textarea
13
15
  * (与 -input 同边框/底色/圆角,正文 13px/1.6),窄屏 16px 防 iOS 聚焦缩放、
14
16
  * 纵向可拖拽但不横向溢出。
17
+ *
18
+ * 类名避让 cardCss 已生成的 `-status` / `-badge` 前缀(那是 CardChrome 的状态行与
19
+ * 字段徽标),安装表与作业块一律用 `-install*` / `-pill*` / `-job*`。
15
20
  */
16
21
  const extraCss = `
17
22
  .apr-textarea{box-sizing:border-box;width:100%;min-height:180px;resize:vertical;font:inherit;font-size:13px;line-height:1.6;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px 12px;transition:border-color .18s,background .18s}
@@ -19,8 +24,28 @@ const extraCss = `
19
24
  .apr-textarea:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}
20
25
  .apr-textarea:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}
21
26
  .apr-textarea::placeholder{color:var(--dsw-alias-label-tertiary)}
27
+ .apr-btnRow{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
28
+ .apr-install{margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
29
+ .apr-installRow{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
30
+ .apr-installKey{flex:none;width:118px;margin:0;font-size:12px;color:var(--dsw-alias-label-tertiary)}
31
+ .apr-installVal{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:0;font-size:13px;color:var(--dsw-alias-label-primary)}
32
+ .apr-mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;word-break:break-all}
33
+ .apr-pill{flex:none;padding:2px 8px;border-radius:999px;font-size:11px;line-height:16px}
34
+ .apr-pillOk{background:var(--dsw-alias-state-success-secondary);color:var(--dsw-alias-state-success-primary)}
35
+ .apr-pillMiss,.apr-pillError,.apr-pillCancelled{background:var(--dsw-alias-state-error-secondary);color:var(--dsw-alias-state-error-primary)}
36
+ .apr-pillRunning{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
37
+ .apr-job{margin-top:12px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3)}
38
+ .apr-jobHead{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
39
+ .apr-jobTitle{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}
40
+ .apr-bar{margin-top:8px;height:6px;border-radius:999px;background:var(--dsw-alias-interactive-bg-hover);overflow:hidden}
41
+ .apr-barFill{height:100%;background:var(--dsw-alias-brand-primary);transition:width .3s}
42
+ .apr-logBox{margin-top:8px}
43
+ .apr-logSummary{font-size:12px;color:var(--dsw-alias-label-tertiary);cursor:pointer}
44
+ .apr-log{margin:6px 0 0;max-height:200px;overflow:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.5;white-space:pre-wrap;word-break:break-all;color:var(--dsw-alias-label-tertiary)}
45
+ .apr-error{margin:4px 0 0;font-size:12px;color:var(--dsw-alias-state-error-primary)}
22
46
  @media (max-width:767px){
23
47
  .apr-textarea{font-size:16px;min-height:140px}
48
+ .apr-installKey{width:100%}
24
49
  }
25
50
  `
26
51
 
package/src/config.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  * 与 settings 用户层(GUI 配置卡片写入 profile 行级覆盖层,loader 原位提交活动
6
6
  * 引用,消费端 `unwrapVolatile` 现取即热)。
7
7
  *
8
- * **只有 `personaPrefix` 标 `.volatile()`**:它是对用户的承诺(配置卡片必须给出
9
- * 编辑器,见 src/client/card.tsx),也是本预设里唯一需要热更的字段;其余字段是
10
- * **部署方平面**(MCP 参数、超时、附加 skill 根等运维旋钮),由 `cordis.patch.yml`
8
+ * **活动字段只有两个**:`personaPrefix` 与 `proxyPort`——两者都在配置卡片里有编辑器
9
+ * (见 src/client/card.tsx),保存即热更(预设换代 / 安装作业即时生效)。其余字段是
10
+ * **部署方平面**(安装位置、超时、附加 skill 根等运维旋钮),由 `cordis.patch.yml`
11
11
  * 整体覆盖,GUI 不提供入口。
12
12
  *
13
13
  * **persona 默认为空串**:`dsh-persona` 的空模板照样遮蔽部署级 persona 段,
@@ -21,12 +21,7 @@
21
21
  import z from '@deepseek-ai/schemastery'
22
22
  import type { UnwrapVolatile } from '@dsh-plus/shared'
23
23
 
24
- import {
25
- DEFAULT_MCP_COMMAND,
26
- INPUT_SCHEMA_PROFILES,
27
- OUTPUT_SCHEMA_PROFILES,
28
- REA_PINNED_VERSION,
29
- } from './mcp.ts'
24
+ import { INPUT_SCHEMA_PROFILES, OUTPUT_SCHEMA_PROFILES, REA_PINNED_VERSION } from './mcp.ts'
30
25
  import { SETTINGS_NS as NS_LITERAL } from './ns.ts'
31
26
 
32
27
  /** settings 命名空间(字面量即合法命名空间;配置卡片与运行期读取同一份)。 */
@@ -67,13 +62,29 @@ export const Config = z.object({
67
62
  .string()
68
63
  .description('钉版的 rea-agents 版本(npx 拉取)')
69
64
  .default(REA_PINNED_VERSION),
65
+ installRoot: z
66
+ .string()
67
+ .description(
68
+ 'REA 受管安装树位置(空 = <DSH_HOME>/dsh-plus/dsh-plus-agent-preset-rea/rea-agent)',
69
+ )
70
+ .default(''),
71
+ proxyPort: z
72
+ .natural()
73
+ .max(65535)
74
+ .description('安装/更新时使用的本机代理端口(0 = 不用代理;npm 与原生依赖 prebuild 下载同此)')
75
+ .default(0)
76
+ .volatile(),
70
77
  mcpCommand: z
71
78
  .string()
72
- .description('MCP stdio 可执行文件;Windows 需 cmd.exe 配方,见包文档')
73
- .default(DEFAULT_MCP_COMMAND),
79
+ .description(
80
+ '显式 MCP 启动命令(空 = 用受管安装入口,未安装时该行禁用;填 npx 即启动期拉取,风险自负)',
81
+ )
82
+ .default(''),
74
83
  mcpArgs: z
75
84
  .array(z.string())
76
- .description('MCP stdio 参数;留空 = 按 reaVersion 派生 ["-y","rea-agents@<version>","mcp"]')
85
+ .description(
86
+ 'MCP stdio 附加参数;留空 = 受管入口补 ["mcp"],显式 npx 则派生 ["-y","rea-agents@<version>","mcp"]',
87
+ )
77
88
  .default([]),
78
89
  inputSchemaProfile: z
79
90
  .union(INPUT_SCHEMA_PROFILES)
package/src/definition.ts CHANGED
@@ -8,8 +8,12 @@
8
8
  *
9
9
  * 增量仅三处,测试按 {@link ADDED_ROWS} / {@link CONFIG_DELTAS} 白名单放行:
10
10
  * 1. `persona` 行 `prefix` 取配置值(默认空串 = 空 persona);
11
- * 2. `skill-filesystem` 行加 `customSkillDirs`(随包 REA skill + 配置追加目录);
12
- * 3. 新增 `mcp-rea` 行:官方 MCP 客户端连 REA stdio 服务,落在本预设作用域内。
11
+ * 2. `skill-filesystem` 行加 `customSkillDirs`(随包 REA skill 或手动更新副本 + 追加目录);
12
+ * 3. 新增 `mcp-rea` 行:官方 MCP 客户端连 REA stdio 服务,落在本预设作用域内;
13
+ * **未安装 REA 时该行 `disabled`**(不 spawn npx,见 mcp.ts 的说明)。
14
+ *
15
+ * {@link RuntimeSnapshot} 是运行期事实(受管安装与 skill 来源),由 manager 现探后
16
+ * 传入;不传即「未安装 + 随包 skill」,测试据此断言两种形态。
13
17
  *
14
18
  * 组行必须带 `isolate` 归属 realm,否则注册表拒绝挂载(服务泄漏判定)。
15
19
  * @module @dsh-plus/agent-preset-rea/definition
@@ -17,9 +21,10 @@
17
21
  import type { PresetDefinition } from '@deepseek-ai/dsh-agent-preset-registry'
18
22
 
19
23
  import type { AgentPresetReaConfig } from './config.ts'
20
- import { reaMcpArgs, reaMcpEnv } from './mcp.ts'
24
+ import type { RuntimeSnapshot } from './manager.ts'
25
+ import { DEFAULT_MCP_COMMAND, reaMcpArgs, reaMcpEnv, reaMcpLaunch } from './mcp.ts'
21
26
  import { PLAN_MODE_SECTION } from './prompt.ts'
22
- import { reaSkillDirs } from './skill.ts'
27
+ import { BUNDLED_SKILL_ROOT, reaSkillDirs } from './skill.ts'
23
28
 
24
29
  /** 预设注册表身份(改 id 等于换预设,default 等引用都会落空)。 */
25
30
  export const REA_PRESET_ID = 'rea'
@@ -42,147 +47,199 @@ const POSIX_ONLY = { __jsExpr: "process.platform !== 'win32'" } as const
42
47
 
43
48
  /** 官方 loader 的嵌套组行名。 */
44
49
  const GROUP = 'cordis:group'
50
+ /** 未安装、随包 skill 的运行期事实(默认值:测试与无 manager 场景)。 */
51
+ export function emptyRuntime(): RuntimeSnapshot {
52
+ return {
53
+ install: null,
54
+ skill: {
55
+ source: 'bundled',
56
+ version: null,
57
+ root: BUNDLED_SKILL_ROOT,
58
+ files: 0,
59
+ updatedAt: null,
60
+ },
61
+ }
62
+ }
63
+
64
+ /** 声明里的行类型(官方 loader entry 结构)。 */
65
+ type Row = PresetDefinition['plugins'][number]
45
66
 
46
67
  /**
47
- * 由配置拼出注册表声明。
68
+ * 基础与工具面行:身份(persona)/ 项目指令与时钟 / shell 与文件工具 / 后台任务与
69
+ * 定时提醒 / skill 文件系统(本预设加 `customSkillDirs`,可指向手动更新副本)。
70
+ */
71
+ function baseRows(config: AgentPresetReaConfig, runtime: RuntimeSnapshot): Row[] {
72
+ return [
73
+ // 身份:沿用官方装配(非 complete、保留运行时上下文),前缀取配置(默认空串:
74
+ // 空模板照样遮蔽部署级 persona 段,渲染为空后消失,不追加任何自有文案)。
75
+ {
76
+ id: 'persona',
77
+ name: '@deepseek-ai/dsh-persona',
78
+ config: { prefix: config.personaPrefix },
79
+ },
80
+ // 项目指令(AGENTS.md)与逐步时钟上下文(默认 10 分钟一条)。
81
+ {
82
+ id: 'agent-instructions',
83
+ name: '@deepseek-ai/dsh-agent-instructions',
84
+ config: { maxBytes: 65536 },
85
+ },
86
+ { id: 'time-context', name: '@deepseek-ai/dsh-time-context' },
87
+ // shell:一次性执行,执行器在宿主平面;平台门控与上游一致。
88
+ { id: 'tool-bash', name: '@deepseek-ai/dsh-tool-bash', disabled: WINDOWS_ONLY },
89
+ { id: 'tool-pwsh', name: '@deepseek-ai/dsh-tool-pwsh', disabled: POSIX_ONLY },
90
+ // 文件读写、检索与后台任务控制。
91
+ { id: 'tool-fs', name: '@deepseek-ai/dsh-tool-fs' },
92
+ {
93
+ id: 'tool-fs-search',
94
+ name: '@deepseek-ai/dsh-tool-fs-search',
95
+ config: { sampleOverCapGlobResults: false },
96
+ },
97
+ { id: 'tool-jobs', name: '@deepseek-ai/dsh-tool-jobs' },
98
+ { id: 'tool-schedule', name: '@deepseek-ai/dsh-tool-schedule' },
99
+ // 技能:本地目录发现 + 模型面加载器;本预设额外挂上随包 REA 官方 skill 根
100
+ // (customSkillDirs 是 rank 300 的追加根,不动项目/用户/bundled 根)。
101
+ {
102
+ id: 'skill-filesystem',
103
+ name: '@deepseek-ai/dsh-skill-filesystem',
104
+ config: {
105
+ customSkillDirs: reaSkillDirs(
106
+ config,
107
+ runtime.skill.source === 'updated' ? runtime.skill.root : null,
108
+ ),
109
+ },
110
+ },
111
+ { id: 'tool-skill', name: '@deepseek-ai/dsh-tool-skill' },
112
+ // 同会话目标:/goal 命令与模型面目标工具。
113
+ { id: 'command-goal', name: '@deepseek-ai/dsh-command-goal' },
114
+ { id: 'tool-goal', name: '@deepseek-ai/dsh-tool-goal' },
115
+ ]
116
+ }
117
+
118
+ /**
119
+ * 编排与交付面行:计划模式 / 上下文压缩 / 委派与 workflow / 交互与待办 / 网络工具 /
120
+ * **REA MCP 客户端** / 展示与插件管理。
121
+ */
122
+ function orchestrationRows(config: AgentPresetReaConfig, runtime: RuntimeSnapshot): Row[] {
123
+ // 启动方式:显式 mcpCommand > 受管安装入口 > null(行禁用)。
124
+ const launch = reaMcpLaunch(config, runtime.install)
125
+ // 无启动方式时行被禁用,但 config 仍填经典 npx 配方:配置转储里能看到原始配方,
126
+ // 手工把行 enable 回来即回退到「启动期拉取」的老行为——默认路径绝不 spawn 它。
127
+ const mcp = launch ?? {
128
+ command: DEFAULT_MCP_COMMAND,
129
+ args: reaMcpArgs({ ...config, mcpCommand: DEFAULT_MCP_COMMAND }),
130
+ }
131
+ return [
132
+ // 计划模式:状态天然属于单个 agent,条目级 realm 即正确生命周期。
133
+ {
134
+ id: 'planning',
135
+ name: GROUP,
136
+ group: true,
137
+ isolate: { planMode: true },
138
+ config: [
139
+ {
140
+ id: 'plan-mode',
141
+ name: '@deepseek-ai/dsh-plan-mode',
142
+ config: { section: PLAN_MODE_SECTION },
143
+ },
144
+ ],
145
+ },
146
+ // 压缩:token 计量器留在宿主平面,本组只挂读取它的后端与结果裁剪器。
147
+ {
148
+ id: 'compaction',
149
+ name: GROUP,
150
+ group: true,
151
+ isolate: { compaction: true, toolResultPruner: true },
152
+ config: [
153
+ { id: 'compaction-basic', name: '@deepseek-ai/dsh-compaction-basic' },
154
+ { id: 'command-compact', name: '@deepseek-ai/dsh-command-compact' },
155
+ {
156
+ id: 'tool-result-pruner',
157
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner',
158
+ config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 },
159
+ },
160
+ ],
161
+ },
162
+ // 委派与编排:子代理、fork、workflow 整组(编排引擎只在本 realm 内共享)。
163
+ {
164
+ id: 'delegation',
165
+ name: GROUP,
166
+ group: true,
167
+ isolate: { workflowEngine: true },
168
+ config: [
169
+ { id: 'tool-subagent-control', name: '@deepseek-ai/dsh-tool-subagent-control' },
170
+ {
171
+ id: 'tool-subagent-list-agents',
172
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents',
173
+ },
174
+ {
175
+ id: 'tool-subagent',
176
+ name: '@deepseek-ai/dsh-tool-subagent',
177
+ config: { provider: 'spawn', toolName: 'subagent', modelSelectionSettings: true },
178
+ },
179
+ {
180
+ id: 'tool-subagent-fork',
181
+ name: '@deepseek-ai/dsh-tool-subagent',
182
+ config: { provider: 'fork', toolName: 'subagent_fork' },
183
+ },
184
+ {
185
+ id: 'workflow-ptc',
186
+ name: '@deepseek-ai/dsh-workflow-ptc',
187
+ config: { provider: 'spawn' },
188
+ },
189
+ { id: 'tool-workflow', name: '@deepseek-ai/dsh-tool-workflow' },
190
+ ],
191
+ },
192
+ // 其余模型面行。
193
+ { id: 'tool-ask-user', name: '@deepseek-ai/dsh-tool-ask-user' },
194
+ {
195
+ id: 'tool-todo',
196
+ name: '@deepseek-ai/dsh-tool-todo',
197
+ config: { allowParallelInProgress: true },
198
+ },
199
+ {
200
+ id: 'tool-web',
201
+ name: '@deepseek-ai/dsh-tool-web',
202
+ config: { fetch: true, searchTimeoutMs: 60000 },
203
+ },
204
+ // 本预设新增:REA MCP 客户端(stdio),工具以 mcp__<serverName>__<tool> 注册在
205
+ // 本预设作用域;服务名预留按作用域隔离,其他预设不受影响。
206
+ // 未安装 REA 且未显式配 mcpCommand 时整行禁用:绝不在 boot 期 spawn npx
207
+ // (那会跑 npm 安装脚本,卡住即吊死预设激活与名册——见 docs/README.md)。
208
+ {
209
+ id: 'mcp-rea',
210
+ name: '@deepseek-ai/dsh-mcp-client',
211
+ disabled: !config.mcpEnabled || launch === null,
212
+ config: {
213
+ transport: 'stdio',
214
+ serverName: config.mcpServerName,
215
+ command: mcp.command,
216
+ args: mcp.args,
217
+ env: reaMcpEnv(config),
218
+ toolCallTimeoutMs: config.toolCallTimeoutMs,
219
+ failOnStartupError: config.failOnStartupError,
220
+ },
221
+ },
222
+ { id: 'present', name: '@deepseek-ai/dsh-tool-present' },
223
+ // 宿主插件管理:上游 standard 里同样是 disabled 行。
224
+ { id: 'tool-plugin-manager', name: '@deepseek-ai/dsh-plugin-manager/tools', disabled: true },
225
+ ]
226
+ }
227
+
228
+ /**
229
+ * 由配置 + 运行期事实拼出注册表声明。
48
230
  * @param config - 已验证的插件配置。
231
+ * @param runtime - 受管安装与 skill 来源事实(默认「未安装 + 随包 skill」)。
49
232
  * @returns id 固定为 `rea` 的预设声明。
50
233
  */
51
- export function reaPresetDefinition(config: AgentPresetReaConfig): PresetDefinition {
234
+ export function reaPresetDefinition(
235
+ config: AgentPresetReaConfig,
236
+ runtime: RuntimeSnapshot = emptyRuntime(),
237
+ ): PresetDefinition {
52
238
  return {
53
239
  id: REA_PRESET_ID,
54
240
  name: config.name,
55
241
  description: config.description,
56
242
  order: config.order,
57
- plugins: [
58
- // 身份:沿用官方装配(非 complete、保留运行时上下文),前缀取配置(默认空串:
59
- // 空模板照样遮蔽部署级 persona 段,渲染为空后消失,不追加任何自有文案)。
60
- {
61
- id: 'persona',
62
- name: '@deepseek-ai/dsh-persona',
63
- config: { prefix: config.personaPrefix },
64
- },
65
- // 项目指令(AGENTS.md)与逐步时钟上下文(默认 10 分钟一条)。
66
- {
67
- id: 'agent-instructions',
68
- name: '@deepseek-ai/dsh-agent-instructions',
69
- config: { maxBytes: 65536 },
70
- },
71
- { id: 'time-context', name: '@deepseek-ai/dsh-time-context' },
72
- // shell:一次性执行,执行器在宿主平面;平台门控与上游一致。
73
- { id: 'tool-bash', name: '@deepseek-ai/dsh-tool-bash', disabled: WINDOWS_ONLY },
74
- { id: 'tool-pwsh', name: '@deepseek-ai/dsh-tool-pwsh', disabled: POSIX_ONLY },
75
- // 文件读写、检索与后台任务控制。
76
- { id: 'tool-fs', name: '@deepseek-ai/dsh-tool-fs' },
77
- {
78
- id: 'tool-fs-search',
79
- name: '@deepseek-ai/dsh-tool-fs-search',
80
- config: { sampleOverCapGlobResults: false },
81
- },
82
- { id: 'tool-jobs', name: '@deepseek-ai/dsh-tool-jobs' },
83
- { id: 'tool-schedule', name: '@deepseek-ai/dsh-tool-schedule' },
84
- // 技能:本地目录发现 + 模型面加载器;本预设额外挂上随包 REA 官方 skill 根
85
- // (customSkillDirs 是 rank 300 的追加根,不动项目/用户/bundled 根)。
86
- {
87
- id: 'skill-filesystem',
88
- name: '@deepseek-ai/dsh-skill-filesystem',
89
- config: { customSkillDirs: reaSkillDirs(config) },
90
- },
91
- { id: 'tool-skill', name: '@deepseek-ai/dsh-tool-skill' },
92
- // 同会话目标:/goal 命令与模型面目标工具。
93
- { id: 'command-goal', name: '@deepseek-ai/dsh-command-goal' },
94
- { id: 'tool-goal', name: '@deepseek-ai/dsh-tool-goal' },
95
- // 计划模式:状态天然属于单个 agent,条目级 realm 即正确生命周期。
96
- {
97
- id: 'planning',
98
- name: GROUP,
99
- group: true,
100
- isolate: { planMode: true },
101
- config: [
102
- {
103
- id: 'plan-mode',
104
- name: '@deepseek-ai/dsh-plan-mode',
105
- config: { section: PLAN_MODE_SECTION },
106
- },
107
- ],
108
- },
109
- // 压缩:token 计量器留在宿主平面,本组只挂读取它的后端与结果裁剪器。
110
- {
111
- id: 'compaction',
112
- name: GROUP,
113
- group: true,
114
- isolate: { compaction: true, toolResultPruner: true },
115
- config: [
116
- { id: 'compaction-basic', name: '@deepseek-ai/dsh-compaction-basic' },
117
- { id: 'command-compact', name: '@deepseek-ai/dsh-command-compact' },
118
- {
119
- id: 'tool-result-pruner',
120
- name: '@deepseek-ai/dsh-compaction-tool-result-pruner',
121
- config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 },
122
- },
123
- ],
124
- },
125
- // 委派与编排:子代理、fork、workflow 整组(编排引擎只在本 realm 内共享)。
126
- {
127
- id: 'delegation',
128
- name: GROUP,
129
- group: true,
130
- isolate: { workflowEngine: true },
131
- config: [
132
- { id: 'tool-subagent-control', name: '@deepseek-ai/dsh-tool-subagent-control' },
133
- {
134
- id: 'tool-subagent-list-agents',
135
- name: '@deepseek-ai/dsh-tool-subagent-control/list-agents',
136
- },
137
- {
138
- id: 'tool-subagent',
139
- name: '@deepseek-ai/dsh-tool-subagent',
140
- config: { provider: 'spawn', toolName: 'subagent', modelSelectionSettings: true },
141
- },
142
- {
143
- id: 'tool-subagent-fork',
144
- name: '@deepseek-ai/dsh-tool-subagent',
145
- config: { provider: 'fork', toolName: 'subagent_fork' },
146
- },
147
- {
148
- id: 'workflow-ptc',
149
- name: '@deepseek-ai/dsh-workflow-ptc',
150
- config: { provider: 'spawn' },
151
- },
152
- { id: 'tool-workflow', name: '@deepseek-ai/dsh-tool-workflow' },
153
- ],
154
- },
155
- // 其余模型面行。
156
- { id: 'tool-ask-user', name: '@deepseek-ai/dsh-tool-ask-user' },
157
- {
158
- id: 'tool-todo',
159
- name: '@deepseek-ai/dsh-tool-todo',
160
- config: { allowParallelInProgress: true },
161
- },
162
- {
163
- id: 'tool-web',
164
- name: '@deepseek-ai/dsh-tool-web',
165
- config: { fetch: true, searchTimeoutMs: 60000 },
166
- },
167
- // 本预设新增:REA MCP 客户端(stdio),工具以 mcp__<serverName>__<tool> 注册在
168
- // 本预设作用域;服务名预留按作用域隔离,其他预设不受影响。
169
- {
170
- id: 'mcp-rea',
171
- name: '@deepseek-ai/dsh-mcp-client',
172
- disabled: !config.mcpEnabled,
173
- config: {
174
- transport: 'stdio',
175
- serverName: config.mcpServerName,
176
- command: config.mcpCommand,
177
- args: reaMcpArgs(config),
178
- env: reaMcpEnv(config),
179
- toolCallTimeoutMs: config.toolCallTimeoutMs,
180
- failOnStartupError: config.failOnStartupError,
181
- },
182
- },
183
- { id: 'present', name: '@deepseek-ai/dsh-tool-present' },
184
- // 宿主插件管理:上游 standard 里同样是 disabled 行。
185
- { id: 'tool-plugin-manager', name: '@deepseek-ai/dsh-plugin-manager/tools', disabled: true },
186
- ],
243
+ plugins: [...baseRows(config, runtime), ...orchestrationRows(config, runtime)],
187
244
  }
188
245
  }
package/src/dto.ts ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * 宿主半与浏览器半之间的 wire 数据门面(纯类型 + 纯函数,零 node 依赖)。
3
+ *
4
+ * 浏览器半只 `import type` 消费本文件(编译期擦除,不进 client bundle),
5
+ * 两端共用同一份字段定义,避免「宿主改了字段、卡片还在读老名字」的静默漂移。
6
+ * @module @dsh-plus/agent-preset-rea/dto
7
+ */
8
+
9
+ /** 作业种类。 */
10
+ export type JobKind = 'install' | 'skill'
11
+
12
+ /** 作业状态。 */
13
+ export type JobState = 'running' | 'ok' | 'error' | 'cancelled'
14
+
15
+ /** 作业进度(按阶段推进;percent 为进入该阶段时的完成度)。 */
16
+ export interface JobProgressDto {
17
+ step: number
18
+ steps: number
19
+ phase: string
20
+ percent: number
21
+ }
22
+
23
+ /** 作业快照。 */
24
+ export interface JobDto {
25
+ id: number
26
+ kind: JobKind
27
+ state: JobState
28
+ progress: JobProgressDto
29
+ /** 日志尾部(宿主已有界)。 */
30
+ log: string[]
31
+ startedAt: string
32
+ finishedAt: string | null
33
+ version: string | null
34
+ error: string | null
35
+ }
36
+
37
+ /** 受管安装事实。 */
38
+ export interface InstallDto {
39
+ installed: boolean
40
+ /** 已安装版本(未安装为 null)。 */
41
+ version: string | null
42
+ /** 受管安装树位置(无论是否已安装都有值,便于用户核对)。 */
43
+ root: string
44
+ /** 入口脚本(未安装为 null)。 */
45
+ entry: string | null
46
+ }
47
+
48
+ /** skill 来源事实。 */
49
+ export interface SkillDto {
50
+ source: 'bundled' | 'updated'
51
+ version: string | null
52
+ root: string
53
+ files: number
54
+ updatedAt: string | null
55
+ }
56
+
57
+ /** MCP 行形态。 */
58
+ export interface McpDto {
59
+ /** `installed` = 用受管安装入口;`custom` = 用显式 mcpCommand;`missing` = 未安装且无显式命令(行禁用)。 */
60
+ mode: 'installed' | 'custom' | 'missing'
61
+ /** 行是否启用(mcpEnabled && 有启动方式)。 */
62
+ enabled: boolean
63
+ command: string | null
64
+ args: string[]
65
+ }
66
+
67
+ /** `GET /status` 响应。 */
68
+ export interface StatusDto {
69
+ config: {
70
+ reaVersion: string
71
+ proxyPort: number
72
+ mcpEnabled: boolean
73
+ installRoot: string
74
+ }
75
+ install: InstallDto
76
+ skill: SkillDto
77
+ mcp: McpDto
78
+ paths: { installRoot: string; skillRoot: string }
79
+ job: JobDto | null
80
+ }
81
+
82
+ /** 作业类响应(启动/取消)。 */
83
+ export interface JobActionDto {
84
+ job: JobDto | null
85
+ /** 拒绝原因(409/400 时给出人话)。 */
86
+ error?: string
87
+ }