dominds 0.9.1 → 0.9.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.
|
@@ -48,6 +48,17 @@ function resolveMemberDiligencePushMax(team, agentId) {
|
|
|
48
48
|
}
|
|
49
49
|
return diligence_1.DEFAULT_DILIGENCE_PUSH_MAX;
|
|
50
50
|
}
|
|
51
|
+
function emitDiligenceBudgetEvent(dlg, options) {
|
|
52
|
+
const maxInjectCount = Math.max(0, Math.floor(options.maxInjectCount));
|
|
53
|
+
const remainingCount = Math.max(0, Math.floor(options.nextRemainingBudget));
|
|
54
|
+
(0, evt_registry_1.postDialogEvent)(dlg, {
|
|
55
|
+
type: 'diligence_budget_evt',
|
|
56
|
+
maxInjectCount,
|
|
57
|
+
injectedCount: Math.max(0, maxInjectCount - remainingCount),
|
|
58
|
+
remainingCount,
|
|
59
|
+
disableDiligencePush: dlg.disableDiligencePush,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
51
62
|
function resolveUpNextPrompt(dlg) {
|
|
52
63
|
const upNext = dlg.takeUpNext();
|
|
53
64
|
if (!upNext) {
|
|
@@ -733,6 +744,12 @@ async function maybeContinueWithDiligencePrompt(args) {
|
|
|
733
744
|
kind: 'patch',
|
|
734
745
|
patch: { diligencePushRemainingBudget: dlg.diligencePushRemainingBudget },
|
|
735
746
|
}));
|
|
747
|
+
if (prepared.kind !== 'disabled') {
|
|
748
|
+
emitDiligenceBudgetEvent(dlg, {
|
|
749
|
+
maxInjectCount: prepared.maxInjectCount,
|
|
750
|
+
nextRemainingBudget: prepared.nextRemainingBudget,
|
|
751
|
+
});
|
|
752
|
+
}
|
|
736
753
|
if (prepared.kind === 'budget_exhausted') {
|
|
737
754
|
await (0, runtime_utils_1.suspendForKeepGoingBudgetExhausted)({
|
|
738
755
|
dlg,
|
|
@@ -75,7 +75,8 @@
|
|
|
75
75
|
- `mcp_admin`: MCP operations (`mcp_restart` / `mcp_release`), plus env tools (`env_get` / `env_set` / `env_unset`)
|
|
76
76
|
- MCP-declared toolsets: dynamically mapped from `.minds/mcp.yaml` `servers.<serverId>` (toolset name = `serverId`). Exact capabilities depend on each MCP server’s exposed tools; use `team_mgmt_manual({ topics: ["toolsets"] })` to view the current mapping snapshot
|
|
77
77
|
- Optional per-toolset manual can be placed at `servers.<serverId>.manual` using `content` (overview) and `sections` (chapters)
|
|
78
|
-
- Missing manual does **not** mean the toolset is unavailable;
|
|
78
|
+
- Missing manual does **not** mean the toolset is unavailable; runtime manual will auto-generate a baseline draft (at least a tools-list section) for temporary use
|
|
79
|
+
- Auto-generated draft is only a scaffold: team manager must confirm intent/boundaries with the human user, then replace it with accurate manual content
|
|
79
80
|
- Team managers should, after MCP validation passes, carefully read each exposed tool description, align with the human user on intended rtws usage, then write `servers.<serverId>.manual` with typical usage patterns and primary intent directions
|
|
80
81
|
|
|
81
82
|
## ripgrep Dependency (Detection & Install)
|
|
@@ -75,7 +75,8 @@
|
|
|
75
75
|
- `mcp_admin`:MCP 运维(`mcp_restart` / `mcp_release`),并包含环境变量工具(`env_get` / `env_set` / `env_unset`)
|
|
76
76
|
- MCP 声明型 toolset:来源于 `.minds/mcp.yaml` 的 `servers.<serverId>` 动态映射(toolset 名称 = `serverId`)。具体能力以该 MCP server 实际暴露工具为准;可在 `team_mgmt_manual({ topics: ["toolsets"] })` 查看当前映射快照
|
|
77
77
|
- 可选:在 `servers.<serverId>.manual` 放手册内容,支持 `content`(总说明)+ `sections`(章节)
|
|
78
|
-
- 注意:没有手册 **不代表** toolset
|
|
78
|
+
- 注意:没有手册 **不代表** toolset 不可用;运行时手册会自动生成基础草稿(至少包含 tools 列表章节)供临时使用
|
|
79
|
+
- 自动草稿只是脚手架:团队管理者必须与人类用户确认意图与边界后,再改写成准确手册
|
|
79
80
|
- 团队管理者应在 MCP 配置验证通过后:先精读该 server 各工具说明,再与人类用户讨论本 rtws 的使用意图,最后把典型用法与主要意图方向写入 `servers.<serverId>.manual`
|
|
80
81
|
|
|
81
82
|
## ripgrep 依赖(检测与安装)
|
package/dist/tools/team_mgmt.js
CHANGED
|
@@ -3396,23 +3396,141 @@ function describeMcpManualState(language, state) {
|
|
|
3396
3396
|
? '手册=缺失(不影响 toolset 可用性;这是团队管理配置不足,请根据每个工具 description/参数自行判断使用)'
|
|
3397
3397
|
: 'manual=missing (toolset availability is unaffected; this is a team-management gap, so rely on each tool description/arguments and proceed)';
|
|
3398
3398
|
}
|
|
3399
|
+
function inferAutoGeneratedMcpIntentDirections(language, toolNames) {
|
|
3400
|
+
const names = toolNames.map((name) => name.toLowerCase());
|
|
3401
|
+
const out = [];
|
|
3402
|
+
const pushUnique = (line) => {
|
|
3403
|
+
if (!out.includes(line))
|
|
3404
|
+
out.push(line);
|
|
3405
|
+
};
|
|
3406
|
+
const has = (needle) => names.some((name) => name.includes(needle));
|
|
3407
|
+
if (has('browser') || has('page') || has('playwright') || has('screenshot')) {
|
|
3408
|
+
pushUnique(language === 'zh'
|
|
3409
|
+
? '网页/浏览器自动化:用于页面操作、采样、信息抓取与可视化回归辅助。'
|
|
3410
|
+
: 'Web/browser automation: page actions, sampling, information extraction, and visual-regression assistance.');
|
|
3411
|
+
}
|
|
3412
|
+
if (has('git') || has('repo') || has('diff') || has('pr') || has('commit')) {
|
|
3413
|
+
pushUnique(language === 'zh'
|
|
3414
|
+
? '仓库协作与变更分析:用于读取仓库状态、比较差异、辅助代码审查。'
|
|
3415
|
+
: 'Repository collaboration and change analysis: inspect repo state, compare diffs, and support review workflows.');
|
|
3416
|
+
}
|
|
3417
|
+
if (has('sql') || has('db') || has('query') || has('table') || has('postgres')) {
|
|
3418
|
+
pushUnique(language === 'zh'
|
|
3419
|
+
? '数据查询/诊断:用于结构化检索与数据一致性排查。'
|
|
3420
|
+
: 'Data query/diagnostics: structured retrieval and data-consistency investigation.');
|
|
3421
|
+
}
|
|
3422
|
+
if (has('k8s') || has('kubectl') || has('deploy') || has('cluster') || has('helm')) {
|
|
3423
|
+
pushUnique(language === 'zh'
|
|
3424
|
+
? '部署与运行状态诊断:用于集群状态检查、发布过程观测与故障定位。'
|
|
3425
|
+
: 'Deployment/runtime diagnostics: cluster-state checks, release observation, and incident localization.');
|
|
3426
|
+
}
|
|
3427
|
+
if (has('ticket') || has('issue') || has('jira') || has('linear')) {
|
|
3428
|
+
pushUnique(language === 'zh'
|
|
3429
|
+
? '任务流转协作:用于工单读取、状态同步与流程追踪。'
|
|
3430
|
+
: 'Ticket/workflow collaboration: ticket lookup, state synchronization, and process tracking.');
|
|
3431
|
+
}
|
|
3432
|
+
if (out.length === 0) {
|
|
3433
|
+
out.push(language === 'zh'
|
|
3434
|
+
? '未识别出明确领域特征:建议按工具 description/参数逐个确认用途,并与人类用户共同定义边界。'
|
|
3435
|
+
: 'No clear domain signature detected: review each tool description/arguments and define boundaries jointly with the human user.');
|
|
3436
|
+
}
|
|
3437
|
+
return out;
|
|
3438
|
+
}
|
|
3439
|
+
function renderAutoGeneratedMcpManualDraftSection(language, entry) {
|
|
3440
|
+
const lines = [];
|
|
3441
|
+
const statusText = entry.status === 'registered'
|
|
3442
|
+
? language === 'zh'
|
|
3443
|
+
? '已加载'
|
|
3444
|
+
: 'loaded'
|
|
3445
|
+
: entry.status === 'declared_unloaded'
|
|
3446
|
+
? language === 'zh'
|
|
3447
|
+
? '已声明但未加载'
|
|
3448
|
+
: 'declared but not loaded'
|
|
3449
|
+
: language === 'zh'
|
|
3450
|
+
? '声明无效'
|
|
3451
|
+
: 'invalid declaration';
|
|
3452
|
+
const transportText = entry.transport === 'invalid' ? 'invalid' : entry.transport === 'stdio' ? 'stdio' : 'http';
|
|
3453
|
+
lines.push(`\n### toolset \`${entry.serverId}\``);
|
|
3454
|
+
lines.push(...fmtList([
|
|
3455
|
+
language === 'zh'
|
|
3456
|
+
? '检测到 `servers.<serverId>.manual` 缺失,以下为自动生成的基础手册草稿(供临时使用)。'
|
|
3457
|
+
: '`servers.<serverId>.manual` is missing. Below is an auto-generated baseline manual draft (temporary use).',
|
|
3458
|
+
language === 'zh'
|
|
3459
|
+
? `运行时状态:status=${statusText},transport=${transportText}。`
|
|
3460
|
+
: `Runtime status: status=${statusText}, transport=${transportText}.`,
|
|
3461
|
+
language === 'zh'
|
|
3462
|
+
? '关键提醒:该草稿不等于最终规范。团队管理者必须与人类用户确认本 rtws 的真实意图后,再写入更准确的正式手册。'
|
|
3463
|
+
: 'Critical reminder: this draft is not the final policy. Team manager must confirm actual rtws intent with the human user, then author a more accurate final manual.',
|
|
3464
|
+
])
|
|
3465
|
+
.trimEnd()
|
|
3466
|
+
.split('\n'));
|
|
3467
|
+
lines.push(...fmtList([
|
|
3468
|
+
language === 'zh'
|
|
3469
|
+
? '章节:tools 列表(运行时快照)'
|
|
3470
|
+
: 'Section: Tools list (runtime snapshot)',
|
|
3471
|
+
])
|
|
3472
|
+
.trimEnd()
|
|
3473
|
+
.split('\n'));
|
|
3474
|
+
if ((entry.loadedToolNames?.length ?? 0) > 0) {
|
|
3475
|
+
const tools = entry.loadedToolNames ?? [];
|
|
3476
|
+
lines.push(...fmtCodeBlock('text', tools.map((tool) => `- ${tool}`))
|
|
3477
|
+
.trimEnd()
|
|
3478
|
+
.split('\n'));
|
|
3479
|
+
}
|
|
3480
|
+
else {
|
|
3481
|
+
lines.push(...fmtList([
|
|
3482
|
+
language === 'zh'
|
|
3483
|
+
? '当前无法给出已加载 tools 清单(通常因为该 server 尚未加载)。先运行 `team_mgmt_validate_mcp_cfg({})`,必要时再 `mcp_restart`。'
|
|
3484
|
+
: 'Loaded tools are not currently available (usually because this server is not loaded yet). Run `team_mgmt_validate_mcp_cfg({})`, then `mcp_restart` if needed.',
|
|
3485
|
+
])
|
|
3486
|
+
.trimEnd()
|
|
3487
|
+
.split('\n'));
|
|
3488
|
+
}
|
|
3489
|
+
lines.push(...fmtList([
|
|
3490
|
+
language === 'zh'
|
|
3491
|
+
? '章节:主要意图方向(自动推测,待确认)'
|
|
3492
|
+
: 'Section: Primary intent directions (auto-inferred, pending confirmation)',
|
|
3493
|
+
])
|
|
3494
|
+
.trimEnd()
|
|
3495
|
+
.split('\n'));
|
|
3496
|
+
lines.push(...fmtList(inferAutoGeneratedMcpIntentDirections(language, entry.loadedToolNames ?? []))
|
|
3497
|
+
.trimEnd()
|
|
3498
|
+
.split('\n'));
|
|
3499
|
+
lines.push(...fmtList([
|
|
3500
|
+
language === 'zh'
|
|
3501
|
+
? '团队管理者后续动作:精读每个工具说明 -> 与人类用户确认意图与边界 -> 回写 `servers.<serverId>.manual.content + sections`。'
|
|
3502
|
+
: 'Team-manager follow-up: read each tool description carefully -> confirm intent/boundaries with the human user -> write back to `servers.<serverId>.manual.content + sections`.',
|
|
3503
|
+
])
|
|
3504
|
+
.trimEnd()
|
|
3505
|
+
.split('\n'));
|
|
3506
|
+
return lines.join('\n') + '\n';
|
|
3507
|
+
}
|
|
3399
3508
|
function renderMcpToolsetManualDetailsSection(language, snapshot) {
|
|
3400
3509
|
const header = language === 'zh'
|
|
3401
3510
|
? fmtSubHeader('MCP toolset 手册(来自 `.minds/mcp.yaml` 的 `servers.<serverId>.manual`)')
|
|
3402
3511
|
: fmtSubHeader('MCP Toolset Manuals (from `.minds/mcp.yaml` `servers.<serverId>.manual`)');
|
|
3403
3512
|
if (snapshot.kind !== 'loaded')
|
|
3404
3513
|
return '';
|
|
3405
|
-
const entries = snapshot.entries
|
|
3514
|
+
const entries = snapshot.entries;
|
|
3406
3515
|
if (entries.length === 0) {
|
|
3407
3516
|
return (header +
|
|
3408
3517
|
fmtList([
|
|
3409
3518
|
language === 'zh'
|
|
3410
|
-
? '
|
|
3411
|
-
: '
|
|
3519
|
+
? '当前没有 MCP toolset 可展示。'
|
|
3520
|
+
: 'There are currently no MCP toolsets to display.',
|
|
3412
3521
|
]));
|
|
3413
3522
|
}
|
|
3414
|
-
let out = header
|
|
3523
|
+
let out = header +
|
|
3524
|
+
fmtList([
|
|
3525
|
+
language === 'zh'
|
|
3526
|
+
? '若 `servers.<serverId>.manual` 已配置,显示正式手册;若缺失,则自动生成基础草稿(含 tools 列表与意图方向草稿)供临时使用。'
|
|
3527
|
+
: 'If `servers.<serverId>.manual` is configured, the formal manual is shown; if missing, an auto-generated baseline draft (including tools list and intent directions draft) is provided for temporary use.',
|
|
3528
|
+
]);
|
|
3415
3529
|
for (const entry of entries) {
|
|
3530
|
+
if (entry.manualState.kind === 'missing') {
|
|
3531
|
+
out += renderAutoGeneratedMcpManualDraftSection(language, entry);
|
|
3532
|
+
continue;
|
|
3533
|
+
}
|
|
3416
3534
|
if (entry.manualState.kind === 'invalid') {
|
|
3417
3535
|
out += `\n### toolset \`${entry.serverId}\`\n`;
|
|
3418
3536
|
out += fmtList([
|
|
@@ -3506,12 +3624,14 @@ async function readMcpToolsetMappingSnapshot() {
|
|
|
3506
3624
|
const transport = parsed.config.servers[serverId]?.transport ?? 'invalid';
|
|
3507
3625
|
const loadedTools = registeredToolsets[serverId];
|
|
3508
3626
|
if (loadedTools) {
|
|
3627
|
+
const loadedToolNames = loadedTools.map((t) => t.name);
|
|
3509
3628
|
entries.push({
|
|
3510
3629
|
serverId,
|
|
3511
3630
|
transport,
|
|
3512
3631
|
status: 'registered',
|
|
3513
3632
|
loadedToolCount: loadedTools.length,
|
|
3514
|
-
|
|
3633
|
+
loadedToolNames,
|
|
3634
|
+
loadedToolNamesPreview: loadedToolNames.slice(0, 6),
|
|
3515
3635
|
manualState,
|
|
3516
3636
|
});
|
|
3517
3637
|
continue;
|
|
@@ -3964,6 +4084,7 @@ exports.teamMgmtValidateMcpCfgTool = {
|
|
|
3964
4084
|
let mcpRaw = null;
|
|
3965
4085
|
let declaredServerCount = 0;
|
|
3966
4086
|
let fallbackInvalidServers = [];
|
|
4087
|
+
let fallbackInvalidToolsetManuals = [];
|
|
3967
4088
|
try {
|
|
3968
4089
|
const st = await promises_1.default.stat(mcpYamlAbs);
|
|
3969
4090
|
if (!st.isFile()) {
|
|
@@ -3994,6 +4115,8 @@ exports.teamMgmtValidateMcpCfgTool = {
|
|
|
3994
4115
|
}
|
|
3995
4116
|
declaredServerCount = parsed.serverIdsInYamlOrder.length;
|
|
3996
4117
|
fallbackInvalidServers = parsed.invalidServers;
|
|
4118
|
+
const manualInfo = parseMcpManualByServer(mcpRaw);
|
|
4119
|
+
fallbackInvalidToolsetManuals = [...manualInfo.invalidByServerId.entries()].map(([serverId, errorText]) => ({ serverId, errorText }));
|
|
3997
4120
|
}
|
|
3998
4121
|
catch (err) {
|
|
3999
4122
|
if (!(isFsErrWithCode(err) && err.code === 'ENOENT')) {
|
|
@@ -4009,7 +4132,18 @@ exports.teamMgmtValidateMcpCfgTool = {
|
|
|
4009
4132
|
fallbackOnlyInvalidServers.push(s);
|
|
4010
4133
|
}
|
|
4011
4134
|
}
|
|
4012
|
-
|
|
4135
|
+
const fallbackOnlyInvalidToolsetManuals = [];
|
|
4136
|
+
for (const s of fallbackInvalidToolsetManuals) {
|
|
4137
|
+
const hasMatchingProblem = mcpProblems.some((p) => p.kind === 'mcp_server_error' &&
|
|
4138
|
+
p.detail.serverId === s.serverId &&
|
|
4139
|
+
p.detail.errorText.includes(firstNonEmptyLine(s.errorText)));
|
|
4140
|
+
if (!hasMatchingProblem) {
|
|
4141
|
+
fallbackOnlyInvalidToolsetManuals.push(s);
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
if (mcpProblems.length === 0 &&
|
|
4145
|
+
fallbackOnlyInvalidServers.length === 0 &&
|
|
4146
|
+
fallbackOnlyInvalidToolsetManuals.length === 0) {
|
|
4013
4147
|
const msg = language === 'zh'
|
|
4014
4148
|
? fmtHeader('mcp.yaml 校验通过') +
|
|
4015
4149
|
fmtList([
|
|
@@ -4064,19 +4198,29 @@ exports.teamMgmtValidateMcpCfgTool = {
|
|
|
4064
4198
|
issueLines.push(` serverId: ${s.serverId}`);
|
|
4065
4199
|
issueLines.push(' ' + s.errorText.split('\n').join('\n '));
|
|
4066
4200
|
}
|
|
4067
|
-
const
|
|
4201
|
+
for (const s of fallbackOnlyInvalidToolsetManuals) {
|
|
4202
|
+
issueLines.push(`- [error] ${MCP_SERVER_PROBLEM_PREFIX}${s.serverId}/toolset_manual_error`);
|
|
4203
|
+
issueLines.push(` serverId: ${s.serverId}`);
|
|
4204
|
+
issueLines.push(language === 'zh'
|
|
4205
|
+
? ' toolset manual: servers.<serverId>.manual 声明无效'
|
|
4206
|
+
: ' toolset manual: servers.<serverId>.manual invalid declaration');
|
|
4207
|
+
issueLines.push(' ' + s.errorText.split('\n').join('\n '));
|
|
4208
|
+
}
|
|
4209
|
+
const totalIssues = mcpProblems.length +
|
|
4210
|
+
fallbackOnlyInvalidServers.length +
|
|
4211
|
+
fallbackOnlyInvalidToolsetManuals.length;
|
|
4068
4212
|
const msg = language === 'zh'
|
|
4069
4213
|
? fmtHeader('mcp.yaml 校验失败') +
|
|
4070
4214
|
fmtList([
|
|
4071
4215
|
`\`${MCP_YAML_REL}\`:❌ 检测到 ${totalIssues} 个问题(详见 Problems 面板)`,
|
|
4072
|
-
'说明:MCP
|
|
4216
|
+
'说明:MCP 配置问题(含 toolset manual 声明错误)会导致 server/toolset 加载失败、工具手册缺失/错误或运行时异常。',
|
|
4073
4217
|
]) +
|
|
4074
4218
|
'\n' +
|
|
4075
4219
|
issueLines.join('\n')
|
|
4076
4220
|
: fmtHeader('mcp.yaml Validation Failed') +
|
|
4077
4221
|
fmtList([
|
|
4078
4222
|
`\`${MCP_YAML_REL}\`: ❌ ${totalIssues} issue(s) detected (see Problems panel)`,
|
|
4079
|
-
'Note: MCP config issues can block server/toolset loading
|
|
4223
|
+
'Note: MCP config issues (including toolset manual declaration errors) can block server/toolset loading, produce bad/missing manual guidance, or cause runtime tool failures.',
|
|
4080
4224
|
]) +
|
|
4081
4225
|
'\n' +
|
|
4082
4226
|
issueLines.join('\n');
|