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; it means team-management documentation is incomplete. Continue by reading each tool’s description/arguments
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 不可用;这表示团队管理文档不足。应继续阅读每个工具的 description/参数并使用
78
+ - 注意:没有手册 **不代表** toolset 不可用;运行时手册会自动生成基础草稿(至少包含 tools 列表章节)供临时使用
79
+ - 自动草稿只是脚手架:团队管理者必须与人类用户确认意图与边界后,再改写成准确手册
79
80
  - 团队管理者应在 MCP 配置验证通过后:先精读该 server 各工具说明,再与人类用户讨论本 rtws 的使用意图,最后把典型用法与主要意图方向写入 `servers.<serverId>.manual`
80
81
 
81
82
  ## ripgrep 依赖(检测与安装)
@@ -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.filter((entry) => entry.manualState.kind !== 'missing');
3514
+ const entries = snapshot.entries;
3406
3515
  if (entries.length === 0) {
3407
3516
  return (header +
3408
3517
  fmtList([
3409
3518
  language === 'zh'
3410
- ? '当前所有 MCP toolset 都没有配置 `manual`。这不代表不可用;只代表团队管理者没有提供使用章节。请继续依据工具自身 description/参数定义来使用,并提醒团队管理者补齐手册。'
3411
- : 'No MCP toolset currently provides `manual`. This does not mean unavailable; it only means the team manager has not provided usage chapters yet. Continue by reading each tool description/argument schema, and ask the team manager to fill manuals.',
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
- loadedToolNamesPreview: loadedTools.slice(0, 6).map((t) => t.name),
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
- if (mcpProblems.length === 0 && fallbackOnlyInvalidServers.length === 0) {
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 totalIssues = mcpProblems.length + fallbackOnlyInvalidServers.length;
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 配置问题会导致 server/toolset 加载失败、部分工具不可用或运行时异常。',
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 and cause runtime tool failures.',
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');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dominds",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "DevOps Mindsets — Sustainable Agentic Product Lifecycle",
5
5
  "type": "commonjs",
6
6
  "private": false,