dsh-plugin-t-expert 0.2.9 → 0.2.12
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 +72 -11
- package/data/experts/engineering/engineering-deepseek-harness-project-expert.md +29 -3
- package/lib/bootstrap.js +314 -45
- package/lib/catalog.js +24 -3
- package/lib/client.js +131 -127
- package/lib/command.js +18 -5
- package/lib/i18n.js +18 -2
- package/lib/index.js +426 -80
- package/lib/plan-check.js +36 -54
- package/lib/remote-schemas.js +156 -0
- package/lib/remote.js +29 -133
- package/lib/skill.js +5 -2
- package/lib/squads.js +154 -35
- package/lib/teams/harness-compat.js +36 -0
- package/lib/teams/index.js +11 -3
- package/lib/teams/members.js +14 -5
- package/lib/teams/snapshot.js +7 -4
- package/lib/teams/tools.js +35 -18
- package/package.json +9 -7
- package/skills/dsh-harness-project/SKILL.md +27 -0
- package/skills/t-expert-manager/SKILL.md +11 -2
- package/skills/t-expert-manager/references/ops-reference.md +2 -2
package/lib/command.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
/**
|
|
2
3
|
* `/t` —— T专家 的小队短命令。
|
|
3
4
|
*
|
|
@@ -161,14 +162,26 @@ export function renderTeamList(profiles) {
|
|
|
161
162
|
|
|
162
163
|
/**
|
|
163
164
|
* 注册 `/t`。
|
|
164
|
-
* @param ctx
|
|
165
|
-
* @param options
|
|
166
|
-
* @param options.
|
|
165
|
+
* @param ctx 宿主上下文(需要 `effect` / `logger` 等完整能力)
|
|
166
|
+
* @param {object} options 注册选项
|
|
167
|
+
* @param {string} options.teamsFile teams.json 路径(通常与名册同目录)
|
|
168
|
+
* @param {() => boolean} options.hasEngine 探测内置团队引擎是否在位的函数
|
|
169
|
+
* @param {() => string} [options.engineError] 引擎不可用时的原因(报给用户)
|
|
170
|
+
* @param {object} [options.commands] 已解析好的 commands 服务(可选服务的时序修复,见下)
|
|
167
171
|
*/
|
|
168
172
|
export function registerTeamCommand(ctx, options) {
|
|
169
173
|
const teamsFile = options.teamsFile;
|
|
170
174
|
const hasEngine = options.hasEngine;
|
|
171
|
-
|
|
175
|
+
// ⚠️ 2026-09-13:`commands` 是**可选服务**,真实宿主里它**晚于本插件 apply** 才就绪;
|
|
176
|
+
// 而 `ctx.get("commands")` 在那一刻是 undefined,且 cordis 的 `provide` **不回溯通知**已跑过的代码
|
|
177
|
+
// —— 于是 `/t` 永远不会注册。调用方已用 `ctx.inject(["commands"], …)` 等到就绪后把服务传进来;
|
|
178
|
+
// 这里再兜底懒查一次(直连调用/测试),两条路都不做属性访问。
|
|
179
|
+
const commands = options.commands ?? ctx.get?.("commands");
|
|
180
|
+
if (typeof commands?.register !== "function") {
|
|
181
|
+
ctx.logger?.warn?.("[t-team] 没有可用的 commands 服务:/t 命令不注册。");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
ctx.effect(() => commands.register({
|
|
172
185
|
name: COMMAND_NAME,
|
|
173
186
|
description: "用 T专家 小队执行一个目标(底层走 T专家 内置的多智能体团队引擎)",
|
|
174
187
|
input: { hint: "<小队名|别名> <目标>" },
|
|
@@ -228,4 +241,4 @@ export function registerTeamCommand(ctx, options) {
|
|
|
228
241
|
};
|
|
229
242
|
},
|
|
230
243
|
}), "t-team: /t command");
|
|
231
|
-
}
|
|
244
|
+
}
|
package/lib/i18n.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
/** T专家 host 侧文案与列表/结果渲染。 */
|
|
2
3
|
|
|
3
4
|
export const NS = "t-team";
|
|
@@ -20,6 +21,7 @@ const ZH = {
|
|
|
20
21
|
"error.specsTooMany": "一次最多召唤 {limit} 位专家",
|
|
21
22
|
"error.specInvalid": "experts[{index}] 需要 expert 与 task 两个字段",
|
|
22
23
|
"error.settingsMissing": "T专家 设置段尚未注册",
|
|
24
|
+
"error.settingsServiceMissing": "宿主没有 settings 服务:T专家 的「专家启停」不可用(名册与召唤相关能力需要它记录已启用专家)。这是宿主装配问题,不是配置错误。",
|
|
23
25
|
"error.customUnknownSlug": "未知专家 slug:{slugs}(这些 slug 不在当前名册里;先用 list_t_experts 取准确的 slug)",
|
|
24
26
|
"error.customSlugInvalid": "slug 只能用 a-z、0-9 与连字符,且以字母或数字开头:\"{slug}\"",
|
|
25
27
|
"error.customSlugTaken": "slug「{slug}」已被内置或自建专家占用",
|
|
@@ -66,6 +68,7 @@ const EN = {
|
|
|
66
68
|
"error.specsTooMany": "At most {limit} experts per call",
|
|
67
69
|
"error.specInvalid": "experts[{index}] requires both expert and task",
|
|
68
70
|
"error.settingsMissing": "T Expert settings section is not registered yet",
|
|
71
|
+
"error.settingsServiceMissing": "The host has no settings service: T Expert's enable/disable state is unavailable (the roster and summoning need it to remember which experts are enabled). This is a host wiring problem, not a configuration error.",
|
|
69
72
|
"error.customUnknownSlug": "Unknown expert slug(s): {slugs} (not in the current roster; call list_t_experts for exact slugs)",
|
|
70
73
|
"error.customSlugInvalid": "slug may only use a-z, 0-9 and hyphens, starting with a letter or digit: \"{slug}\"",
|
|
71
74
|
"error.categoryOfficial": "\"{division}\" is an official division: its name and existence follow the built-in roster sync, so only custom divisions can be changed",
|
|
@@ -104,10 +107,23 @@ export function t(locale, key, params = {}) {
|
|
|
104
107
|
return text;
|
|
105
108
|
}
|
|
106
109
|
|
|
107
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* 从宿主 locale 设置读语言,缺失或异常回退 zh。
|
|
112
|
+
*
|
|
113
|
+
* ⚠️ `settings` 是**可选服务**,必须用 `ctx.get("settings")` 懒查,不要写成 `ctx.settings`
|
|
114
|
+
* 属性访问:它不在本插件的静态 `inject` 里,而宿主**没提供**这个服务时,属性访问会被
|
|
115
|
+
* cordis 抛 `cannot get property "settings" without inject`,只剩 try/catch 兜底、
|
|
116
|
+
* 静默退中文(2026-09-13 用真 cordis 4.0.2 实测:宿主**有**这个服务时属性访问读得到,
|
|
117
|
+
* 所以这类 bug 只在"服务不全"的宿主上现形,正常机器上不会露头)。
|
|
118
|
+
* 与 lib/index.js 里 workspaceRegistry / agents 的取值方式保持一致。
|
|
119
|
+
*
|
|
120
|
+
* 这里是**执行期**读取(工具调用那一刻),不是 apply 期探测,所以 `get` 是正确用法:
|
|
121
|
+
* 那一刻 settings 若存在一定已经就绪;不存在就退中文,不会挂起本插件。
|
|
122
|
+
*/
|
|
108
123
|
export function readLocale(ctx) {
|
|
109
124
|
try {
|
|
110
|
-
const
|
|
125
|
+
const settings = typeof ctx?.get === "function" ? ctx.get("settings") : undefined;
|
|
126
|
+
const section = settings?.get?.("locale");
|
|
111
127
|
const preference = section?.preference;
|
|
112
128
|
if (typeof preference === "string" && preference.toLowerCase().startsWith("en")) return "en";
|
|
113
129
|
} catch {
|