metheus-governance-mcp-cli 0.2.209 → 0.2.210

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.
@@ -1896,6 +1896,17 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
1896
1896
  responseContract.require_actionable_contract === true && Array.isArray(responseContract.allowed_contract_types) && responseContract.allowed_contract_types.length > 0
1897
1897
  ? `Allowed execution contract types for this reply: ${responseContract.allowed_contract_types.join(", ")}.`
1898
1898
  : "",
1899
+ "If you mention any other managed bot @username anywhere in the reply, you must include a contract for that mention.",
1900
+ "Do not mention another managed bot unless the contract explicitly names that bot in assignments or next_responders.",
1901
+ "Without a matching contract, mentioned bots will not act.",
1902
+ "When delegating to another managed bot, use contract.type=\"delegation\" with actionable=true, assignments, and next_responders.",
1903
+ "Delegation contract example: {\"type\":\"delegation\",\"actionable\":true,\"assignments\":[{\"target_bot\":\"ryoai2_bot\",\"task\":\"briefly greet in one line\"}],\"next_responders\":[\"ryoai2_bot\"]}.",
1904
+ ensureArray(responseContract.required_delegation_targets).length > 0
1905
+ ? `This reply must delegate to these exact managed bots now: ${ensureArray(responseContract.required_delegation_targets).map((item) => `@${String(item || "").trim().replace(/^@+/, "")}`).join(", ")}.`
1906
+ : "",
1907
+ String(responseContract.contract_hint || "").trim()
1908
+ ? `Contract requirement hint: ${String(responseContract.contract_hint || "").trim()}`
1909
+ : "",
1899
1910
  "",
1900
1911
  );
1901
1912
  }
@@ -2042,6 +2053,7 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
2042
2053
  lines.push(
2043
2054
  "As the lead bot, your first public reply must be immediately actionable.",
2044
2055
  "If you are delegating, include contract.type=\"delegation\" with concrete assignments for the exact bots you are tasking now.",
2056
+ "If you mention any allowed responder in the reply text, the contract must name that responder in assignments or next_responders.",
2045
2057
  "If you are completing the work yourself now, include contract.type=\"direct_result\".",
2046
2058
  "Do not say you will come back later, wait, or plan first without producing an actionable contract in this same reply.",
2047
2059
  );
@@ -4998,17 +4998,22 @@ export async function processRunnerSelectedRecord({
4998
4998
  const directHumanPeerMap = humanIntentContext?.peerMap instanceof Map
4999
4999
  ? humanIntentContext.peerMap
5000
5000
  : buildConversationPeerMap(bot, normalizedRoute, executionDeps);
5001
- const delegatedBotMentions = (
5002
- effectiveTriggerDecision.requiresDirectReply === true
5003
- && !conversationContext
5004
- && !safeObject(selectedRecord?.parsedArchive).senderIsBot
5005
- )
5006
- ? extractManagedPeerMentionSelectors(
5007
- String(aiResult.reply || "").trim(),
5008
- directHumanPeerMap,
5009
- currentBotSelector,
5001
+ const delegatedBotMentions = extractManagedPeerMentionSelectors(
5002
+ String(aiResult.reply || "").trim(),
5003
+ directHumanPeerMap,
5004
+ currentBotSelector,
5005
+ );
5006
+ const requiredDelegationTargets = uniqueOrdered(
5007
+ (
5008
+ delegatedBotMentions.length > 0
5009
+ ? delegatedBotMentions
5010
+ : requiresPeerDelegationContract
5011
+ ? peerAllowedResponders
5012
+ : []
5010
5013
  )
5011
- : [];
5014
+ .map((item) => normalizeMentionSelector(item))
5015
+ .filter(Boolean),
5016
+ );
5012
5017
  if (delegatedBotMentions.length > 0) {
5013
5018
  allowedActionableTypes = new Set(["delegation"]);
5014
5019
  }
@@ -5021,7 +5026,7 @@ export async function processRunnerSelectedRecord({
5021
5026
  && executionContract.actionable === true
5022
5027
  && (!allowedActionableTypes.size || allowedActionableTypes.has(String(executionContract.type || "").trim().toLowerCase())),
5023
5028
  );
5024
- if (!requiresActionableContract && delegatedBotMentions.length > 0) {
5029
+ if (!requiresActionableContract && requiredDelegationTargets.length > 0) {
5025
5030
  requiresActionableContract = true;
5026
5031
  }
5027
5032
  if (
@@ -5056,25 +5061,27 @@ export async function processRunnerSelectedRecord({
5056
5061
  allow_skip: false,
5057
5062
  must_reply: true,
5058
5063
  require_actionable_contract: true,
5059
- human_intent_mode: effectiveResponseContractPayload.human_intent_mode || ((delegatedBotMentions.length > 0 || requiresPeerDelegationContract) ? "delegated_single_lead" : ""),
5060
- human_lead_bot: delegatedBotMentions.length > 0
5061
- ? currentBotSelector
5062
- : String(effectiveResponseContractPayload.human_lead_bot || "").trim(),
5063
- human_summary_bot: delegatedBotMentions.length > 0
5064
- ? String(delegatedBotMentions[0] || "").trim()
5065
- : String(effectiveResponseContractPayload.human_summary_bot || "").trim(),
5064
+ human_intent_mode: String(effectiveResponseContractPayload.human_intent_mode || "").trim(),
5065
+ human_lead_bot: String(effectiveResponseContractPayload.human_lead_bot || "").trim(),
5066
+ human_summary_bot: String(effectiveResponseContractPayload.human_summary_bot || "").trim(),
5066
5067
  human_allowed_responders: ensureArray(effectiveResponseContractPayload.human_allowed_responders).length
5067
5068
  ? ensureArray(effectiveResponseContractPayload.human_allowed_responders)
5068
5069
  : uniqueOrdered([
5069
5070
  currentBotSelector,
5070
- ...(delegatedBotMentions.length > 0 ? delegatedBotMentions : peerAllowedResponders),
5071
+ ...requiredDelegationTargets,
5071
5072
  ].filter(Boolean)),
5072
- allow_bot_to_bot: delegatedBotMentions.length > 0 || requiresPeerDelegationContract || effectiveResponseContractPayload.human_intent_mode === "delegated_single_lead",
5073
- allowed_contract_types: delegatedBotMentions.length > 0 || requiresPeerDelegationContract
5074
- ? ["delegation", "summary_request", "final_summary"]
5073
+ allow_bot_to_bot: requiredDelegationTargets.length > 0
5074
+ || requiresPeerDelegationContract
5075
+ || effectiveResponseContractPayload.human_intent_mode === "delegated_single_lead",
5076
+ allowed_contract_types: requiredDelegationTargets.length > 0 || requiresPeerDelegationContract
5077
+ ? ["delegation"]
5075
5078
  : ensureArray(effectiveResponseContractPayload.allowed_contract_types).length
5076
5079
  ? ensureArray(effectiveResponseContractPayload.allowed_contract_types)
5077
5080
  : ["direct_result", "summary_request", "final_summary"],
5081
+ required_delegation_targets: requiredDelegationTargets,
5082
+ contract_hint: requiredDelegationTargets.length > 0
5083
+ ? `Your previous reply mentioned ${requiredDelegationTargets.map((item) => `@${String(item || "").trim().replace(/^@+/, "")}`).join(", ")} without a delegation contract. Return contract.type=\"delegation\" with actionable=true, assignments for those exact bots, and matching next_responders.`
5084
+ : "",
5078
5085
  },
5079
5086
  };
5080
5087
  effectiveResponseContractPayload = safeObject(forcedContractPayload.response_contract);
@@ -5138,7 +5145,9 @@ export async function processRunnerSelectedRecord({
5138
5145
  if (requiresActionableContract) {
5139
5146
  const validContract = hasValidActionableContract;
5140
5147
  if (!validContract) {
5141
- const reason = "reply did not produce an actionable execution contract";
5148
+ const reason = requiredDelegationTargets.length > 0
5149
+ ? `reply mentioned managed peer bot(s) ${requiredDelegationTargets.map((item) => `@${String(item || "").trim().replace(/^@+/, "")}`).join(", ")} without a required delegation contract`
5150
+ : "reply did not produce an actionable execution contract";
5142
5151
  const directHumanExecutionFailure = effectiveTriggerDecision.requiresDirectReply === true
5143
5152
  && !conversationContext
5144
5153
  && !safeObject(selectedRecord?.parsedArchive).senderIsBot;
@@ -4386,10 +4386,11 @@ export async function runSelftestRunnerScenarios(push, deps) {
4386
4386
  push("delegated_single_lead_human_opening_creates_expandable_contract", false, String(err?.message || err));
4387
4387
  }
4388
4388
 
4389
- try {
4390
- let aiCalls = 0;
4391
- const deliveredConversation = [];
4392
- const processed = await processRunnerSelectedRecord({
4389
+ try {
4390
+ let aiCalls = 0;
4391
+ const deliveredConversation = [];
4392
+ let forcedContractPayload = null;
4393
+ const processed = await processRunnerSelectedRecord({
4393
4394
  routeKey: "direct-human-delegation-contract-upgrade-key",
4394
4395
  normalizedRoute: normalizeRunnerRoute({
4395
4396
  name: "telegram-monitor-direct-human-delegation-contract-upgrade",
@@ -4464,15 +4465,16 @@ export async function runSelftestRunnerScenarios(push, deps) {
4464
4465
  timeoutSeconds: 30,
4465
4466
  actor: { user_id: "user-1" },
4466
4467
  },
4467
- deps: {
4468
- saveRunnerRouteState: () => {},
4469
- startRunnerTypingHeartbeat: () => ({ async stop() {} }),
4470
- runRunnerAIExecution: async ({ inputPayload }) => {
4471
- aiCalls += 1;
4472
- if (safeObject(inputPayload?.response_contract).require_actionable_contract === true) {
4473
- return {
4474
- skip: false,
4475
- reply: "@RyoAI3_bot briefly greet everyone in this room and state your role in one line.",
4468
+ deps: {
4469
+ saveRunnerRouteState: () => {},
4470
+ startRunnerTypingHeartbeat: () => ({ async stop() {} }),
4471
+ runRunnerAIExecution: async ({ inputPayload }) => {
4472
+ aiCalls += 1;
4473
+ if (safeObject(inputPayload?.response_contract).require_actionable_contract === true) {
4474
+ forcedContractPayload = inputPayload;
4475
+ return {
4476
+ skip: false,
4477
+ reply: "@RyoAI3_bot briefly greet everyone in this room and state your role in one line.",
4476
4478
  replyToMessageID: 0,
4477
4479
  contract: {
4478
4480
  type: "delegation",
@@ -4530,16 +4532,17 @@ export async function runSelftestRunnerScenarios(push, deps) {
4530
4532
  && Array.isArray(deliveredConversation[0]?.allowedResponderSelectors)
4531
4533
  && deliveredConversation[0].allowedResponderSelectors.includes("ryoai3_bot")
4532
4534
  && String(deliveredConversation[0]?.executionContract?.type || "") === "delegation",
4533
- `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} mode=${String(deliveredConversation[0]?.mode || "(none)")} contract=${String(deliveredConversation[0]?.executionContract?.type || "(none)")}`,
4534
- );
4535
- } catch (err) {
4536
- push("direct_human_public_delegate_reply_is_upgraded_to_actionable_contract", false, String(err?.message || err));
4537
- }
4535
+ `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} mode=${String(deliveredConversation[0]?.mode || "(none)")} contract=${String(deliveredConversation[0]?.executionContract?.type || "(none)")} required_targets=${JSON.stringify(safeObject(forcedContractPayload?.response_contract).required_delegation_targets || [])}`,
4536
+ );
4537
+ } catch (err) {
4538
+ push("direct_human_public_delegate_reply_is_upgraded_to_actionable_contract", false, String(err?.message || err));
4539
+ }
4538
4540
 
4539
- try {
4540
- let aiCalls = 0;
4541
- const deliveredConversation = [];
4542
- const processed = await processRunnerSelectedRecord({
4541
+ try {
4542
+ let aiCalls = 0;
4543
+ const deliveredConversation = [];
4544
+ let forcedContractPayload = null;
4545
+ const processed = await processRunnerSelectedRecord({
4543
4546
  routeKey: "direct-human-public-delegate-repairs-lead-bot-key",
4544
4547
  normalizedRoute: normalizeRunnerRoute({
4545
4548
  name: "telegram-monitor-direct-human-public-delegate-repairs-lead-bot",
@@ -4686,10 +4689,11 @@ export async function runSelftestRunnerScenarios(push, deps) {
4686
4689
  push("direct_human_public_delegate_repairs_lead_bot_selector_for_archive_contract", false, String(err?.message || err));
4687
4690
  }
4688
4691
 
4689
- try {
4690
- let aiCalls = 0;
4691
- const deliveredConversation = [];
4692
- const processed = await processRunnerSelectedRecord({
4692
+ try {
4693
+ let aiCalls = 0;
4694
+ const deliveredConversation = [];
4695
+ let forcedContractPayload = null;
4696
+ const processed = await processRunnerSelectedRecord({
4693
4697
  routeKey: "direct-human-public-delegate-fallback-uses-response-allowed-responders-key",
4694
4698
  normalizedRoute: normalizeRunnerRoute({
4695
4699
  name: "telegram-monitor-direct-human-public-delegate-fallback-uses-response-allowed-responders",
@@ -4830,10 +4834,11 @@ export async function runSelftestRunnerScenarios(push, deps) {
4830
4834
  push("direct_human_public_delegate_fallback_uses_response_allowed_responders", false, String(err?.message || err));
4831
4835
  }
4832
4836
 
4833
- try {
4834
- let aiCalls = 0;
4835
- const deliveredConversation = [];
4836
- const processed = await processRunnerSelectedRecord({
4837
+ try {
4838
+ let aiCalls = 0;
4839
+ const deliveredConversation = [];
4840
+ let forcedContractPayload = null;
4841
+ const processed = await processRunnerSelectedRecord({
4837
4842
  routeKey: "direct-human-public-summary-fallback-contract-key",
4838
4843
  normalizedRoute: normalizeRunnerRoute({
4839
4844
  name: "telegram-monitor-direct-human-public-summary-fallback-contract",
@@ -4910,13 +4915,14 @@ export async function runSelftestRunnerScenarios(push, deps) {
4910
4915
  },
4911
4916
  deps: {
4912
4917
  saveRunnerRouteState: () => {},
4913
- startRunnerTypingHeartbeat: () => ({ async stop() {} }),
4914
- runRunnerAIExecution: async ({ inputPayload }) => {
4915
- aiCalls += 1;
4916
- if (safeObject(inputPayload?.response_contract).require_actionable_contract === true) {
4917
- return {
4918
- skip: false,
4919
- reply: "@RyoAI3_bot briefly answer now.",
4918
+ startRunnerTypingHeartbeat: () => ({ async stop() {} }),
4919
+ runRunnerAIExecution: async ({ inputPayload }) => {
4920
+ aiCalls += 1;
4921
+ if (safeObject(inputPayload?.response_contract).require_actionable_contract === true) {
4922
+ forcedContractPayload = inputPayload;
4923
+ return {
4924
+ skip: false,
4925
+ reply: "@RyoAI3_bot briefly answer now.",
4920
4926
  replyToMessageID: 0,
4921
4927
  contract: {
4922
4928
  type: "summary_request",
@@ -4963,26 +4969,26 @@ export async function runSelftestRunnerScenarios(push, deps) {
4963
4969
  ],
4964
4970
  },
4965
4971
  });
4966
- push(
4967
- "direct_human_public_summary_request_fallback_builds_actionable_contract",
4968
- processed.kind === "replied"
4969
- && aiCalls >= 1
4970
- && String(deliveredConversation[0]?.mode || "") === "public_multi_bot"
4971
- && String(deliveredConversation[0]?.leadBotUsername || "") === "ryoai_bot"
4972
- && Array.isArray(deliveredConversation[0]?.allowedResponderSelectors)
4973
- && deliveredConversation[0].allowedResponderSelectors.includes("ryoai3_bot")
4974
- && String(deliveredConversation[0]?.executionContract?.type || "") === "summary_request",
4975
- `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} lead=${String(deliveredConversation[0]?.leadBotUsername || "(none)")} contract=${String(deliveredConversation[0]?.executionContract?.type || "(none)")} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
4976
- );
4977
- } catch (err) {
4978
- push("direct_human_public_summary_request_fallback_builds_actionable_contract", false, String(err?.message || err));
4979
- }
4972
+ push(
4973
+ "direct_human_public_peer_mention_rejects_summary_request_without_delegation",
4974
+ processed.kind === "skipped"
4975
+ && aiCalls >= 1
4976
+ && deliveredConversation.length === 0
4977
+ && ensureArray(safeObject(forcedContractPayload?.response_contract).required_delegation_targets).includes("ryoai3_bot")
4978
+ && String(safeObject(forcedContractPayload?.response_contract).contract_hint || "").trim().length > 0
4979
+ && String(processed.skippedRecord?.reason || "").includes("delegation contract"),
4980
+ `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} required_targets=${JSON.stringify(safeObject(forcedContractPayload?.response_contract).required_delegation_targets || [])} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
4981
+ );
4982
+ } catch (err) {
4983
+ push("direct_human_public_peer_mention_rejects_summary_request_without_delegation", false, String(err?.message || err));
4984
+ }
4980
4985
 
4981
- try {
4982
- let aiCalls = 0;
4983
- let deliveryCalls = 0;
4984
- let deliveredText = "";
4985
- const processed = await processRunnerSelectedRecord({
4986
+ try {
4987
+ let aiCalls = 0;
4988
+ let deliveryCalls = 0;
4989
+ let deliveredText = "";
4990
+ let forcedContractPayload = null;
4991
+ const processed = await processRunnerSelectedRecord({
4986
4992
  routeKey: "delegated-single-lead-dead-end-key",
4987
4993
  normalizedRoute: normalizeRunnerRoute({
4988
4994
  name: "telegram-monitor-delegated-single-lead-dead-end",
@@ -5057,14 +5063,17 @@ export async function runSelftestRunnerScenarios(push, deps) {
5057
5063
  timeoutSeconds: 30,
5058
5064
  actor: { user_id: "user-1" },
5059
5065
  },
5060
- deps: {
5061
- saveRunnerRouteState: () => {},
5062
- startRunnerTypingHeartbeat: () => ({ async stop() {} }),
5063
- runRunnerAIExecution: async () => {
5064
- aiCalls += 1;
5065
- return {
5066
- skip: false,
5067
- reply: "I will analyze first and come back later.",
5066
+ deps: {
5067
+ saveRunnerRouteState: () => {},
5068
+ startRunnerTypingHeartbeat: () => ({ async stop() {} }),
5069
+ runRunnerAIExecution: async ({ inputPayload }) => {
5070
+ aiCalls += 1;
5071
+ if (safeObject(inputPayload?.response_contract).require_actionable_contract === true) {
5072
+ forcedContractPayload = inputPayload;
5073
+ }
5074
+ return {
5075
+ skip: false,
5076
+ reply: "I will analyze first and come back later.",
5068
5077
  replyToMessageID: 0,
5069
5078
  };
5070
5079
  },
@@ -5100,16 +5109,19 @@ export async function runSelftestRunnerScenarios(push, deps) {
5100
5109
  ],
5101
5110
  },
5102
5111
  });
5103
- push(
5104
- "delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup",
5105
- processed.kind === "skipped"
5106
- && aiCalls === 2
5107
- && !String(deliveredText || "").trim(),
5108
- `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} reply=${String(deliveredText || "(none)")}`,
5109
- );
5110
- } catch (err) {
5111
- push("delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup", false, String(err?.message || err));
5112
- }
5112
+ push(
5113
+ "delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup",
5114
+ processed.kind === "skipped"
5115
+ && aiCalls === 2
5116
+ && !String(deliveredText || "").trim()
5117
+ && ensureArray(safeObject(forcedContractPayload?.response_contract).required_delegation_targets).includes("ryoai2_bot")
5118
+ && ensureArray(safeObject(forcedContractPayload?.response_contract).required_delegation_targets).includes("ryoai3_bot")
5119
+ && String(safeObject(forcedContractPayload?.response_contract).contract_hint || "").trim().length > 0,
5120
+ `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} reply=${String(deliveredText || "(none)")} required_targets=${JSON.stringify(safeObject(forcedContractPayload?.response_contract).required_delegation_targets || [])} hint=${String(safeObject(forcedContractPayload?.response_contract).contract_hint || "(none)")}`,
5121
+ );
5122
+ } catch (err) {
5123
+ push("delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup", false, String(err?.message || err));
5124
+ }
5113
5125
 
5114
5126
  try {
5115
5127
  let aiCalls = 0;
@@ -9966,14 +9978,51 @@ export async function runSelftestRunnerScenarios(push, deps) {
9966
9978
  && !prompt.includes("Archived Note"),
9967
9979
  `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} contexts=${projectContexts.map((item) => item.title).join(",") || "(none)"} prompt_has_active_context=${String(prompt.includes("Active project context"))}`,
9968
9980
  );
9969
- } catch (err) {
9970
- push("active_project_context_is_injected_into_runner_prompt", false, String(err?.message || err));
9971
- }
9972
-
9973
- try {
9974
- const createCalls = [];
9975
- let lastSavedState = null;
9976
- const workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), "metheus-runner-selftest-context-suggest-"));
9981
+ } catch (err) {
9982
+ push("active_project_context_is_injected_into_runner_prompt", false, String(err?.message || err));
9983
+ }
9984
+
9985
+ try {
9986
+ const prompt = buildLocalBotPrompt({
9987
+ bot: {
9988
+ name: "RyoAI_bot",
9989
+ username: "RyoAI_bot",
9990
+ role: "monitor",
9991
+ },
9992
+ trigger: {
9993
+ body: "@RyoAI_bot ask @RyoAI2_bot to greet in one line",
9994
+ },
9995
+ response_contract: {
9996
+ is_current_bot_candidate: true,
9997
+ require_actionable_contract: true,
9998
+ allowed_contract_types: ["delegation"],
9999
+ required_delegation_targets: ["ryoai2_bot"],
10000
+ contract_hint: "Previous reply mentioned @ryoai2_bot without a delegation contract.",
10001
+ },
10002
+ destination: {
10003
+ label: "Main Room",
10004
+ chat_id: "-100123",
10005
+ },
10006
+ project: {
10007
+ id: selftestProjectID,
10008
+ },
10009
+ }, { terse: true });
10010
+ push(
10011
+ "local_bot_prompt_requires_contract_for_peer_mentions",
10012
+ prompt.includes("Without a matching contract, mentioned bots will not act.")
10013
+ && prompt.includes("@ryoai2_bot")
10014
+ && prompt.includes("contract.type=\"delegation\"")
10015
+ && prompt.includes("Previous reply mentioned @ryoai2_bot without a delegation contract."),
10016
+ prompt,
10017
+ );
10018
+ } catch (err) {
10019
+ push("local_bot_prompt_requires_contract_for_peer_mentions", false, String(err?.message || err));
10020
+ }
10021
+
10022
+ try {
10023
+ const createCalls = [];
10024
+ let lastSavedState = null;
10025
+ const workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), "metheus-runner-selftest-context-suggest-"));
9977
10026
  const processed = await processRunnerSelectedRecord({
9978
10027
  routeKey: "context-suggest-human-rule-key",
9979
10028
  normalizedRoute: normalizeRunnerRoute({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.209",
3
+ "version": "0.2.210",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [