@ifrankwang/openspec-agents 0.150.0 → 0.150.2
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/.dsh-plugin/opx-tools.mjs +49 -1
- package/.mcp-server/cli.mjs +1 -1
- package/assets/skills/orchestrator/SKILL.md +0 -1
- package/dsh/cordis.patch.yml +5 -12
- package/package.json +1 -1
- package/src/adapters/deepseek-harness/index.ts +51 -26
- package/src/adapters/deepseek-harness/plugin.ts +81 -1
- package/src/types/dsh-runtime.d.ts +19 -1
|
@@ -9033,7 +9033,11 @@ function withAgentArg(parameters) {
|
|
|
9033
9033
|
|
|
9034
9034
|
// src/adapters/deepseek-harness/plugin.ts
|
|
9035
9035
|
var Config = z.object({
|
|
9036
|
-
unattended: z.boolean().default(true)
|
|
9036
|
+
unattended: z.boolean().default(true),
|
|
9037
|
+
subagents: z.array(z.object({
|
|
9038
|
+
toolName: z.string(),
|
|
9039
|
+
agentPreset: z.string()
|
|
9040
|
+
})).default([])
|
|
9037
9041
|
});
|
|
9038
9042
|
var name = "openspec-opx-tools";
|
|
9039
9043
|
var inject = ["tools"];
|
|
@@ -9051,6 +9055,50 @@ function apply(ctx, config = {}) {
|
|
|
9051
9055
|
}
|
|
9052
9056
|
}));
|
|
9053
9057
|
}
|
|
9058
|
+
mountSubagentTools(ctx, config.subagents ?? []);
|
|
9059
|
+
}
|
|
9060
|
+
var SUBAGENT_TOOL_PACKAGE = "@deepseek-ai/dsh-tool-subagent";
|
|
9061
|
+
var PRESET_READY_TIMEOUT_MS = 3000;
|
|
9062
|
+
var PRESET_READY_POLL_MS = 50;
|
|
9063
|
+
async function waitForPreset(registry, presetId, timeoutMs = PRESET_READY_TIMEOUT_MS) {
|
|
9064
|
+
const deadline = Date.now() + timeoutMs;
|
|
9065
|
+
while (Date.now() < deadline) {
|
|
9066
|
+
try {
|
|
9067
|
+
await registry.readDocument(presetId);
|
|
9068
|
+
return true;
|
|
9069
|
+
} catch {
|
|
9070
|
+
await new Promise((resolve) => setTimeout(resolve, PRESET_READY_POLL_MS));
|
|
9071
|
+
}
|
|
9072
|
+
}
|
|
9073
|
+
return false;
|
|
9074
|
+
}
|
|
9075
|
+
function mountSubagentTools(ctx, specs) {
|
|
9076
|
+
if (specs.length === 0 || typeof ctx.inject !== "function")
|
|
9077
|
+
return;
|
|
9078
|
+
ctx.inject(["agentPresets"], async (injected) => {
|
|
9079
|
+
let subagentTool;
|
|
9080
|
+
try {
|
|
9081
|
+
subagentTool = await import(SUBAGENT_TOOL_PACKAGE);
|
|
9082
|
+
} catch (error) {
|
|
9083
|
+
injected.logger?.warn?.(`openspec: 无法加载 ${SUBAGENT_TOOL_PACKAGE},子代理委派工具未挂载:${String(error)}`);
|
|
9084
|
+
return;
|
|
9085
|
+
}
|
|
9086
|
+
for (const spec of specs) {
|
|
9087
|
+
if (!await waitForPreset(injected.agentPresets, spec.agentPreset)) {
|
|
9088
|
+
injected.logger?.warn?.(`openspec: agent preset "${spec.agentPreset}" 未在 ${PRESET_READY_TIMEOUT_MS}ms 内注册,跳过子代理工具 ${spec.toolName}`);
|
|
9089
|
+
continue;
|
|
9090
|
+
}
|
|
9091
|
+
try {
|
|
9092
|
+
await injected.plugin(subagentTool, {
|
|
9093
|
+
provider: "spawn",
|
|
9094
|
+
toolName: spec.toolName,
|
|
9095
|
+
agentPreset: spec.agentPreset
|
|
9096
|
+
});
|
|
9097
|
+
} catch (error) {
|
|
9098
|
+
injected.logger?.warn?.(`openspec: 子代理工具 ${spec.toolName} 挂载失败:${String(error)}`);
|
|
9099
|
+
}
|
|
9100
|
+
}
|
|
9101
|
+
});
|
|
9054
9102
|
}
|
|
9055
9103
|
export {
|
|
9056
9104
|
Config,
|
package/.mcp-server/cli.mjs
CHANGED
|
@@ -30629,7 +30629,7 @@ async function ensureDefaultUnattended(args, ctx) {
|
|
|
30629
30629
|
}
|
|
30630
30630
|
} catch {}
|
|
30631
30631
|
}
|
|
30632
|
-
var PKG_VERSION = "0.150.
|
|
30632
|
+
var PKG_VERSION = "0.150.2";
|
|
30633
30633
|
function buildMcpServer(worktree, opts = {}) {
|
|
30634
30634
|
const mcp = new McpServer({ name: "openspec-agents", version: PKG_VERSION });
|
|
30635
30635
|
for (const [name, spec] of Object.entries(TOOL_SPECS)) {
|
|
@@ -45,7 +45,6 @@ capabilities: ["orchestrator"]
|
|
|
45
45
|
- 每次子代理返回后,调用状态查询工具获取权威「下一步」指令并严格遵循;推进被拦时按工具给出的阻塞原因与修复建议处理,不自行推断其他动作。DSH 形态下「返回」指收到子代理完成通知,不是分派工具的即时返回(见「分派范式」的 DSH 异步委派)
|
|
46
46
|
- 分派/推进决策一律以工具返回为准:工具已给出明确分派指令时直接分派,不得先读状态文件交叉验证;仅门禁拒绝或工具给出修复建议时才读取状态文件核对
|
|
47
47
|
- 分派子代理前先查询状态确认当前阶段/层,确保不跳阶段或错层分派;工具视图呈现 worktree 未就绪时不得分派
|
|
48
|
-
- 不过度沟通:任务组内部不停下来向用户汇报,持续执行直到阻塞或完成
|
|
49
48
|
- 断点续传:子代理因步骤限制中断后重新分派即可继续,无需保存已完成子任务列表
|
|
50
49
|
- 工具列出多个子代理时并排分派(单条消息中同时发送),不串行等待
|
|
51
50
|
- 分派前校验分派 prompt:按「禁止事项」中禁止转述的动态内容清单逐项检查,校验通过后再分派
|
package/dsh/cordis.patch.yml
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
name: '@ifrankwang/openspec-agents/.dsh-plugin/opx-tools.mjs'
|
|
13
13
|
config:
|
|
14
14
|
unattended: true
|
|
15
|
+
subagents:
|
|
16
|
+
- toolName: openspec_developer
|
|
17
|
+
agentPreset: openspec-developer
|
|
18
|
+
- toolName: openspec_reviewer
|
|
19
|
+
agentPreset: openspec-reviewer
|
|
15
20
|
- id: openspec-skills
|
|
16
21
|
name: '@deepseek-ai/dsh-skill-filesystem'
|
|
17
22
|
config:
|
|
@@ -105,12 +110,6 @@
|
|
|
105
110
|
thresholdChars: 8192
|
|
106
111
|
headChars: 4096
|
|
107
112
|
tailChars: 1024
|
|
108
|
-
- id: openspec-subagent-developer
|
|
109
|
-
name: '@deepseek-ai/dsh-tool-subagent'
|
|
110
|
-
config:
|
|
111
|
-
provider: spawn
|
|
112
|
-
toolName: openspec_developer
|
|
113
|
-
agentPreset: openspec-developer
|
|
114
113
|
- id: openspec-preset-reviewer
|
|
115
114
|
name: '@deepseek-ai/dsh-agent-preset'
|
|
116
115
|
config:
|
|
@@ -375,10 +374,4 @@
|
|
|
375
374
|
thresholdChars: 8192
|
|
376
375
|
headChars: 4096
|
|
377
376
|
tailChars: 1024
|
|
378
|
-
- id: openspec-subagent-reviewer
|
|
379
|
-
name: '@deepseek-ai/dsh-tool-subagent'
|
|
380
|
-
config:
|
|
381
|
-
provider: spawn
|
|
382
|
-
toolName: openspec_reviewer
|
|
383
|
-
agentPreset: openspec-reviewer
|
|
384
377
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifrankwang/openspec-agents",
|
|
3
|
-
"version": "0.150.
|
|
3
|
+
"version": "0.150.2",
|
|
4
4
|
"description": "OpenSpec companion plugin for AI coding agents (Claude Code, Codex, ZCode, DeepSeek Harness, OpenCode): a stricter proposal standard plus multi-agent implementation and review, gated to production-grade standards",
|
|
5
5
|
"author": "ifrankwang",
|
|
6
6
|
"license": "MIT",
|
|
@@ -68,7 +68,14 @@ export const DSH_NATIVE_TOOLS_ROW_ID = "openspec-opx-tools"
|
|
|
68
68
|
*/
|
|
69
69
|
export const DSH_SKILLS_DIR_SEGMENTS = ["assets", "skills"] as const
|
|
70
70
|
|
|
71
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* 原生工具插件与 skill 根的基础 patch。
|
|
73
|
+
*
|
|
74
|
+
* 子代理委派工具**不写成静态 patch 行**:DSH 加载器对同一层的条目并行激活,静态工具行会在
|
|
75
|
+
* preset 声明行注册完成之前校验 `agentPreset`,报 `Unknown agent preset`。改为把
|
|
76
|
+
* toolName ↔ preset id 清单放进插件配置,由插件在 preset 就绪后动态挂载委派工具
|
|
77
|
+
* (见 plugin.ts 的 mountSubagentTools),顺序由代码保证。
|
|
78
|
+
*/
|
|
72
79
|
const DSH_BASE_PATCH_YAML = `# DeepSeek Harness (DSH) bundle patch: expose OpenSpec orchestration tools and skills.
|
|
73
80
|
# The patch is applied as a bundle layer under dsh.profile.bundles.
|
|
74
81
|
# baseUrl 指向 profile 根目录;bundle 安装后位于 profile 的 node_modules 下,
|
|
@@ -205,15 +212,25 @@ function dshSubagentPresetPlugins(editAllowed: boolean): Record<string, unknown>
|
|
|
205
212
|
]
|
|
206
213
|
}
|
|
207
214
|
|
|
215
|
+
/** 子代理委派规格:工具名 + 引用的 preset id(写入插件配置,供动态挂载使用)。 */
|
|
216
|
+
export interface DshSubagentSpec {
|
|
217
|
+
toolName: string
|
|
218
|
+
agentPreset: string
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** 解析一个子代理的 preset 声明与委派规格。 */
|
|
222
|
+
interface DshSubagentDefinition {
|
|
223
|
+
spec: DshSubagentSpec
|
|
224
|
+
presetEntry: DshSubagentEntry
|
|
225
|
+
}
|
|
226
|
+
|
|
208
227
|
/**
|
|
209
|
-
* 从 assets/agents/*.md 收集 DSH 子代理:每个物理子代理生成一个 Agent Preset
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* preset 行必须排在工具行之前:工具行在加载时校验 `agentPreset` 是否已声明。
|
|
228
|
+
* 从 assets/agents/*.md 收集 DSH 子代理:每个物理子代理生成一个 Agent Preset 声明行,
|
|
229
|
+
* 以及一份「工具名 + preset id」规格(交给插件动态挂载委派工具)。
|
|
213
230
|
*/
|
|
214
|
-
function
|
|
231
|
+
function collectDshSubagents(): DshSubagentDefinition[] {
|
|
215
232
|
const agentsRoot = resolve("assets", "agents")
|
|
216
|
-
const
|
|
233
|
+
const definitions: DshSubagentDefinition[] = []
|
|
217
234
|
for (const file of readdirSync(agentsRoot)) {
|
|
218
235
|
if (!file.endsWith(".md")) continue
|
|
219
236
|
if (EXCLUDED_AGENTS.has(file)) continue
|
|
@@ -224,8 +241,9 @@ function collectDshSubagentEntries(): DshSubagentEntry[] {
|
|
|
224
241
|
const persona = [DSH_SUBAGENT_TOOL_ACCESS_PREAMBLE, description, body.trim()].filter(Boolean).join("\n\n")
|
|
225
242
|
const suffix = dshAgentSuffix(name)
|
|
226
243
|
const presetId = `openspec-${suffix.replace(/_/g, "-")}`
|
|
227
|
-
|
|
228
|
-
{
|
|
244
|
+
definitions.push({
|
|
245
|
+
spec: { toolName: `openspec_${suffix}`, agentPreset: presetId },
|
|
246
|
+
presetEntry: {
|
|
229
247
|
id: `openspec-preset-${suffix}`,
|
|
230
248
|
name: "@deepseek-ai/dsh-agent-preset",
|
|
231
249
|
config: {
|
|
@@ -238,30 +256,37 @@ function collectDshSubagentEntries(): DshSubagentEntry[] {
|
|
|
238
256
|
],
|
|
239
257
|
},
|
|
240
258
|
},
|
|
241
|
-
|
|
242
|
-
id: `openspec-subagent-${suffix}`,
|
|
243
|
-
name: "@deepseek-ai/dsh-tool-subagent",
|
|
244
|
-
config: {
|
|
245
|
-
provider: "spawn",
|
|
246
|
-
toolName: `openspec_${suffix}`,
|
|
247
|
-
agentPreset: presetId,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
)
|
|
259
|
+
})
|
|
251
260
|
}
|
|
252
|
-
return
|
|
261
|
+
return definitions
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** 把子代理规格投影为插件配置里的 `subagents` 块(缩进对齐 openspec-opx-tools 行的 config)。 */
|
|
265
|
+
function subagentsConfigYaml(specs: DshSubagentSpec[]): string {
|
|
266
|
+
if (specs.length === 0) return " subagents: []"
|
|
267
|
+
const dumped = yaml.dump(specs, { lineWidth: -1 }).trimEnd().split("\n")
|
|
268
|
+
return [" subagents:", ...dumped.map((line) => ` ${line}`)].join("\n")
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** 基础 patch:原生工具插件行带上子代理委派规格,供插件在 preset 就绪后动态挂载。 */
|
|
272
|
+
function buildBasePatchYaml(specs: DshSubagentSpec[]): string {
|
|
273
|
+
return DSH_BASE_PATCH_YAML.replace(
|
|
274
|
+
" unattended: true",
|
|
275
|
+
` unattended: true\n${subagentsConfigYaml(specs)}`,
|
|
276
|
+
)
|
|
253
277
|
}
|
|
254
278
|
|
|
255
|
-
/** 生成完整的 DSH cordis patch 内容:基础原生工具插件行 + skill 根 + 每个子代理的 preset
|
|
279
|
+
/** 生成完整的 DSH cordis patch 内容:基础原生工具插件行 + skill 根 + 每个子代理的 preset 声明。 */
|
|
256
280
|
export function buildDshPatchContent(): string {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
281
|
+
const definitions = collectDshSubagents()
|
|
282
|
+
const base = buildBasePatchYaml(definitions.map((definition) => definition.spec))
|
|
283
|
+
if (definitions.length === 0) return base
|
|
284
|
+
const presetsYaml = yaml
|
|
285
|
+
.dump(definitions.map((definition) => definition.presetEntry), { schema: DSH_YAML_SCHEMA, lineWidth: -1 })
|
|
261
286
|
.split("\n")
|
|
262
287
|
.map((line) => (line ? ` ${line}` : line))
|
|
263
288
|
.join("\n")
|
|
264
|
-
return `${
|
|
289
|
+
return `${base.trimEnd()}\n${presetsYaml}\n`
|
|
265
290
|
}
|
|
266
291
|
|
|
267
292
|
export type DeepSeekHarnessPluginBuildResult = PluginPackageResult
|
|
@@ -25,6 +25,19 @@ import { buildNativeToolDefinitions, type DshToolExec } from "./native-tools.ts"
|
|
|
25
25
|
const Config = z.object({
|
|
26
26
|
/** 默认无人值守:会话已初始化且未显式设置时自动开启。默认 true,与 MCP 侧 --unattended 同口径。 */
|
|
27
27
|
unattended: z.boolean().default(true),
|
|
28
|
+
/**
|
|
29
|
+
* 子代理委派规格(工具名 + 引用的 preset id),由构建期写入 patch。
|
|
30
|
+
* 委派工具不写成静态 patch 行:DSH 加载器并行激活同层条目,静态工具行会在 preset 注册前
|
|
31
|
+
* 校验 `agentPreset` 报 Unknown agent preset;改由插件在 preset 就绪后动态挂载。
|
|
32
|
+
*/
|
|
33
|
+
subagents: z
|
|
34
|
+
.array(
|
|
35
|
+
z.object({
|
|
36
|
+
toolName: z.string(),
|
|
37
|
+
agentPreset: z.string(),
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
40
|
+
.default([]),
|
|
28
41
|
})
|
|
29
42
|
|
|
30
43
|
/** cordis 插件名。 */
|
|
@@ -39,7 +52,10 @@ const inject = ["tools"]
|
|
|
39
52
|
* worktree 每次调用从 `exec.agent.session.header.cwd` 取会话项目目录(该字段缺失即报错,不静默回落进程 cwd);
|
|
40
53
|
* `exec.signal` 在每次调用入口检查取消;调用者身份由 `_agent` 入参声明(缺省=编排主代理视角)。
|
|
41
54
|
*/
|
|
42
|
-
function apply(
|
|
55
|
+
function apply(
|
|
56
|
+
ctx: any,
|
|
57
|
+
config: { unattended?: boolean; subagents?: Array<{ toolName: string; agentPreset: string }> } = {},
|
|
58
|
+
): void {
|
|
43
59
|
const unattended = config.unattended !== false
|
|
44
60
|
// 进程 cwd 仅用于「无 agent 上下文的非 agent 调用」兜底;agent 调用缺会话目录时工具直接报错。
|
|
45
61
|
const processCwd = process.cwd()
|
|
@@ -56,6 +72,70 @@ function apply(ctx: any, config: { unattended?: boolean } = {}): void {
|
|
|
56
72
|
}),
|
|
57
73
|
)
|
|
58
74
|
}
|
|
75
|
+
mountSubagentTools(ctx, config.subagents ?? [])
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** 子代理委派工具所属的官方包(保持 external,由 DSH 安装目录在运行时解析)。 */
|
|
79
|
+
const SUBAGENT_TOOL_PACKAGE = "@deepseek-ai/dsh-tool-subagent"
|
|
80
|
+
|
|
81
|
+
/** 等待 preset 声明注册完成的上限:注册在启动阶段完成,正常在毫秒级。 */
|
|
82
|
+
const PRESET_READY_TIMEOUT_MS = 3000
|
|
83
|
+
const PRESET_READY_POLL_MS = 50
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 轮询等待 preset 声明注册完成。
|
|
87
|
+
*
|
|
88
|
+
* `agentPresets.readDocument(id)` 直接读内存声明表:返回成功即表示 preset 行已激活,
|
|
89
|
+
* 此时再挂载委派工具,工具行的加载期校验必然通过。
|
|
90
|
+
*/
|
|
91
|
+
async function waitForPreset(registry: any, presetId: string, timeoutMs = PRESET_READY_TIMEOUT_MS): Promise<boolean> {
|
|
92
|
+
const deadline = Date.now() + timeoutMs
|
|
93
|
+
while (Date.now() < deadline) {
|
|
94
|
+
try {
|
|
95
|
+
await registry.readDocument(presetId)
|
|
96
|
+
return true
|
|
97
|
+
} catch {
|
|
98
|
+
await new Promise((resolve) => setTimeout(resolve, PRESET_READY_POLL_MS))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 在 preset 就绪后动态挂载子代理委派工具。
|
|
106
|
+
*
|
|
107
|
+
* 与静态 patch 行的差异只有挂载时机:本函数先等 `agentPresets` 服务可用、再逐个确认 preset
|
|
108
|
+
* 已注册,最后才挂 `@deepseek-ai/dsh-tool-subagent` 实例——消除「工具行先于 preset 行激活」
|
|
109
|
+
* 的加载竞态(DSH 对同层条目并行激活,desktop 多插件下稳定触发)。
|
|
110
|
+
*/
|
|
111
|
+
function mountSubagentTools(ctx: any, specs: Array<{ toolName: string; agentPreset: string }>): void {
|
|
112
|
+
if (specs.length === 0 || typeof ctx.inject !== "function") return
|
|
113
|
+
ctx.inject(["agentPresets"], async (injected: any) => {
|
|
114
|
+
let subagentTool: any
|
|
115
|
+
try {
|
|
116
|
+
subagentTool = await import(SUBAGENT_TOOL_PACKAGE)
|
|
117
|
+
} catch (error) {
|
|
118
|
+
injected.logger?.warn?.(`openspec: 无法加载 ${SUBAGENT_TOOL_PACKAGE},子代理委派工具未挂载:${String(error)}`)
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
for (const spec of specs) {
|
|
122
|
+
if (!(await waitForPreset(injected.agentPresets, spec.agentPreset))) {
|
|
123
|
+
injected.logger?.warn?.(
|
|
124
|
+
`openspec: agent preset "${spec.agentPreset}" 未在 ${PRESET_READY_TIMEOUT_MS}ms 内注册,跳过子代理工具 ${spec.toolName}`,
|
|
125
|
+
)
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
await injected.plugin(subagentTool, {
|
|
130
|
+
provider: "spawn",
|
|
131
|
+
toolName: spec.toolName,
|
|
132
|
+
agentPreset: spec.agentPreset,
|
|
133
|
+
})
|
|
134
|
+
} catch (error) {
|
|
135
|
+
injected.logger?.warn?.(`openspec: 子代理工具 ${spec.toolName} 挂载失败:${String(error)}`)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
})
|
|
59
139
|
}
|
|
60
140
|
|
|
61
141
|
export { Config, apply, inject, name }
|
|
@@ -154,9 +154,27 @@ declare module "@deepseek-ai/dsh-tools" {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
declare module "@deepseek-ai/cordis" {
|
|
157
|
-
/**
|
|
157
|
+
/** 本项目插件用到的 cordis 能力:工具注册表、依赖注入与子插件挂载;其余服务不消费。 */
|
|
158
158
|
export interface Context {
|
|
159
159
|
tools: import("@deepseek-ai/dsh-tools").ToolRegistry
|
|
160
|
+
/**
|
|
161
|
+
* 依赖就绪后执行回调。本插件用它等 `agentPresets` 服务可用,再动态挂载子代理委派工具
|
|
162
|
+
* (DSH 对同层 patch 条目并行激活,静态工具行会先于 preset 声明校验而失败)。
|
|
163
|
+
*/
|
|
164
|
+
inject(deps: readonly string[], callback: (ctx: Context) => unknown): unknown
|
|
165
|
+
/** 挂载子插件。本插件用它挂载官方 `@deepseek-ai/dsh-tool-subagent` 实例。 */
|
|
166
|
+
plugin(plugin: unknown, config?: unknown): unknown
|
|
160
167
|
[key: string]: any
|
|
161
168
|
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
declare module "@deepseek-ai/dsh-tool-subagent" {
|
|
172
|
+
/**
|
|
173
|
+
* 官方子代理委派工具插件(cordis 插件形态:命名导出 name/inject/Config/apply)。
|
|
174
|
+
* 本插件在 preset 就绪后动态挂载它,故只需声明挂载所需的公开形状。
|
|
175
|
+
*/
|
|
176
|
+
export const name: string
|
|
177
|
+
export const inject: readonly string[]
|
|
178
|
+
export const Config: unknown
|
|
179
|
+
export function apply(ctx: unknown, config?: unknown): void
|
|
162
180
|
}
|