metheus-governance-mcp-cli 0.2.289 → 0.2.290

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.
Files changed (3) hide show
  1. package/README.md +2 -4
  2. package/cli.mjs +47 -26
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -379,7 +379,7 @@ Behavior:
379
379
  - `bot room-audit` now suggests executable runner routes for the managed server+local intersection. Room visibility is still reported, but a bot no longer has to appear in the admin list before route automation can prepare it.
380
380
  - `bot room-audit` defaults to `monitor` only unless you pass `--role` or `--roles`.
381
381
  - `bot room-audit --apply true` writes missing suggested routes into `~/.metheus/bot-runner.json` and disables overlapping enabled routes in the same project/provider/destination/bot scope that are outside the selected role set.
382
- - `runner project up` is the one-command direct CLI path for Telegram project operations: it runs the same room audit, applies the selected role routes, and starts detached polling by default unless you explicitly pass `--start false`.
382
+ - `runner project up` is the direct CLI preparation path for Telegram project operations: it runs the same room audit and applies the selected role routes. Use `runner start-detached` for persistent polling, or let the TUI call `runner.project_up` to bootstrap detached polling in one step.
383
383
  - `runner project up` can be narrowed with `--bot-name`, `--bot-id`, `--role`, or `--roles <csv>` when you do not want every suggested role route for that room.
384
384
  - `bot remove` without flags starts a guided numbered flow: provider -> bot entry -> confirm removal.
385
385
  - Telegram stores one bot file per entry under `~/.metheus/telegram-bots/<ServerBotName>.env` with generic fields:
@@ -421,7 +421,6 @@ metheus-governance-mcp-cli bot remove --provider telegram --bot-name <server_bot
421
421
  metheus-governance-mcp-cli bot verify --provider telegram --bot-name <server_bot_name> --json true
422
422
  metheus-governance-mcp-cli bot room-audit --provider telegram --project-id <project_uuid> --destination-label <room_label> --json true
423
423
  metheus-governance-mcp-cli bot room-audit --provider telegram --project-id <project_uuid> --destination-label <room_label> --apply true --json true
424
- metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label>
425
424
  metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label> --start false
426
425
  metheus-governance-mcp-cli runner start-detached --project-id <project_uuid> --provider telegram --destination-label <room_label>
427
426
  metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label> --bot-name <server_bot_name> --roles monitor,review --start false
@@ -556,7 +555,7 @@ metheus-governance-mcp-cli runner start --route-name telegram-monitor --concurre
556
555
  Route management:
557
556
  - `runner route add` creates one executable route by selecting the project, provider, role, server bot, and project chat destination in order.
558
557
  - `runner route add` now auto-uses the suggested route name, `5000` ms poll interval, and `enabled=true` unless you pass explicit flags or edit the route later.
559
- - `runner project up` is the shortest practical route bootstrap path for Telegram: it audits one project destination, writes any missing suggested routes, and starts detached polling by default unless you explicitly pass `--start false`.
558
+ - `runner project up` is the shortest practical direct CLI preparation path for Telegram: it audits one project destination and writes any missing suggested routes. Start persistent polling separately with `runner start-detached`, or use the TUI/local tool path that bootstraps detached polling for you.
560
559
  - if room visibility probe fails but one or more enabled routes already exist for that project destination, `runner project up` now treats the probe failure as a warning and can still start those existing routes.
561
560
  - `runner project up --dry-run-delivery true` lets the started runner validate route execution without sending a real provider message.
562
561
  - In public Telegram bot conversations, the stored route role is treated as a hint only. Live room context, the current human request, and recent bot replies take priority over the stored route role hint when the local AI client decides how to answer.
@@ -569,7 +568,6 @@ Route management:
569
568
  Recommended operational path:
570
569
 
571
570
  ```bash
572
- metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label>
573
571
  metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label> --start false
574
572
  metheus-governance-mcp-cli runner start-detached --project-id <project_uuid> --provider telegram --destination-label <room_label>
575
573
  metheus-governance-mcp-cli runner project up --project-id <project_uuid> --provider telegram --destination-label <room_label> --bot-name <server_bot_name> --roles monitor,review --start false
package/cli.mjs CHANGED
@@ -12306,7 +12306,7 @@ function resolveRunnerProjectUpExecutionPolicy(flags = {}) {
12306
12306
  ? boolFromRaw(startDetachedRaw, true)
12307
12307
  : (explicitDetachedAliasRequested
12308
12308
  ? boolFromRaw(flags.detached, false)
12309
- : !explicitStartRequested);
12309
+ : false);
12310
12310
  const shouldStartRunner = startRequested || startDetachedRequested;
12311
12311
  return {
12312
12312
  applyRequested,
@@ -12323,6 +12323,24 @@ function buildRunnerStartDetachedCommand(flags = {}) {
12323
12323
  })].join(" ");
12324
12324
  }
12325
12325
 
12326
+ function sleepSyncMilliseconds(durationMs) {
12327
+ const numericDurationMs = Math.max(0, intFromRaw(durationMs, 0) || 0);
12328
+ if (numericDurationMs <= 0) return;
12329
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, numericDurationMs);
12330
+ }
12331
+
12332
+ function ensureDetachedRunnerBootstrapped(childPID, logFilePath = "") {
12333
+ sleepSyncMilliseconds(1200);
12334
+ if (isProcessAlive(childPID)) {
12335
+ return;
12336
+ }
12337
+ const normalizedLogFilePath = String(logFilePath || "").trim();
12338
+ if (normalizedLogFilePath && fs.existsSync(normalizedLogFilePath)) {
12339
+ throw new Error(`detached runner exited during bootstrap; inspect ${normalizedLogFilePath}`);
12340
+ }
12341
+ throw new Error("detached runner exited during bootstrap before the polling loop became stable");
12342
+ }
12343
+
12326
12344
  function buildRunnerProjectUpNextSteps({
12327
12345
  applyRequested,
12328
12346
  shouldStartRunner,
@@ -12354,7 +12372,7 @@ async function buildRunnerProjectUpResult(flags = {}) {
12354
12372
  const ui = createPrompter();
12355
12373
  try {
12356
12374
  if (shouldRenderPromptChrome(flags)) {
12357
- ui.setFlow("RUNNER PROJECT UP", "Audit one project destination, create missing runner routes, and start detached polling by default unless --start false is passed");
12375
+ ui.setFlow("RUNNER PROJECT UP", "Audit one project destination, create missing runner routes, and optionally start polling when explicitly requested");
12358
12376
  }
12359
12377
  const provider = String(flags.provider || "").trim()
12360
12378
  ? normalizeBotProvider(flags.provider)
@@ -12452,7 +12470,7 @@ async function buildRunnerProjectUpResult(flags = {}) {
12452
12470
  route_apply_changed: Boolean(applyResult.changed),
12453
12471
  route_config_file: String(applyResult.filePath || auditPayload.routeSuggestionConfigFilePath || "-").trim() || "-",
12454
12472
  enabled_routes_for_selection: matchingRoutes.map((route) => normalizeRunnerRoute(route).name).filter(Boolean),
12455
- start_requested: shouldStartRunner,
12473
+ start_requested: startRequested,
12456
12474
  start_detached_requested: startDetachedRequested,
12457
12475
  next_steps: [],
12458
12476
  applied_routes: ensureArray(applyResult.appliedRoutes).map((item) => safeObject(item)),
@@ -12848,12 +12866,13 @@ async function launchDetachedRunnerProcess(flags, routes, sourceCommand) {
12848
12866
  if (launched.status !== 0) {
12849
12867
  throw new Error(String(launched.stderr || launched.stdout || "failed to launch detached runner").trim());
12850
12868
  }
12851
- const childPID = intFromRawAllowZero(String(launched.stdout || "").trim().split(/\r?\n/).pop(), 0);
12852
- if (childPID <= 0) {
12853
- throw new Error("detached runner launch did not return a child process id");
12854
- }
12855
- return buildRunnerDetachedLaunchRecord(childPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12856
- }
12869
+ const childPID = intFromRawAllowZero(String(launched.stdout || "").trim().split(/\r?\n/).pop(), 0);
12870
+ if (childPID <= 0) {
12871
+ throw new Error("detached runner launch did not return a child process id");
12872
+ }
12873
+ ensureDetachedRunnerBootstrapped(childPID, detachedLogFilePath);
12874
+ return buildRunnerDetachedLaunchRecord(childPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12875
+ }
12857
12876
  const launchTempDir = fs.mkdtempSync(path.join(os.tmpdir(), "metheus-runner-launch-"));
12858
12877
  const scriptPath = path.join(launchTempDir, "start-runner.sh");
12859
12878
  const pidFilePath = path.join(launchTempDir, "runner.pid");
@@ -12877,13 +12896,14 @@ async function launchDetachedRunnerProcess(flags, routes, sourceCommand) {
12877
12896
  });
12878
12897
  if (launched.error) {
12879
12898
  throw launched.error;
12880
- }
12881
- if (launched.status !== 0) {
12882
- throw new Error(String(launched.stderr || launched.stdout || "failed to launch detached runner in Terminal.app").trim());
12883
- }
12884
- const childPID = await waitForRunnerPIDFile(pidFilePath);
12885
- return buildRunnerDetachedLaunchRecord(childPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12886
- }
12899
+ }
12900
+ if (launched.status !== 0) {
12901
+ throw new Error(String(launched.stderr || launched.stdout || "failed to launch detached runner in Terminal.app").trim());
12902
+ }
12903
+ const childPID = await waitForRunnerPIDFile(pidFilePath);
12904
+ ensureDetachedRunnerBootstrapped(childPID, detachedLogFilePath);
12905
+ return buildRunnerDetachedLaunchRecord(childPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12906
+ }
12887
12907
  const terminalLauncher = resolveLinuxDetachedTerminalLauncher(scriptPath);
12888
12908
  if (!terminalLauncher) {
12889
12909
  throw new Error("no supported Linux terminal emulator was found (tried x-terminal-emulator, gnome-terminal, konsole, mate-terminal, tilix, alacritty, xterm). Install one of those terminals so runner.start_detached can open an independent window");
@@ -12894,12 +12914,13 @@ async function launchDetachedRunnerProcess(flags, routes, sourceCommand) {
12894
12914
  stdio: "ignore",
12895
12915
  });
12896
12916
  child.unref();
12897
- if (!child.pid) {
12898
- throw new Error("detached terminal launcher did not return a process id");
12899
- }
12900
- const runnerPID = await waitForRunnerPIDFile(pidFilePath);
12901
- return buildRunnerDetachedLaunchRecord(runnerPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12902
- } finally {
12917
+ if (!child.pid) {
12918
+ throw new Error("detached terminal launcher did not return a process id");
12919
+ }
12920
+ const runnerPID = await waitForRunnerPIDFile(pidFilePath);
12921
+ ensureDetachedRunnerBootstrapped(runnerPID, detachedLogFilePath);
12922
+ return buildRunnerDetachedLaunchRecord(runnerPID, routes, startFlags, sourceCommand, detachedLogFilePath);
12923
+ } finally {
12903
12924
  try {
12904
12925
  fs.rmSync(launchTempDir, { recursive: true, force: true });
12905
12926
  } catch {}
@@ -19334,15 +19355,15 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
19334
19355
  try {
19335
19356
  const projectUpPolicy = resolveRunnerProjectUpExecutionPolicy({});
19336
19357
  push(
19337
- "runner_project_up_default_policy_prefers_detached_start",
19358
+ "runner_project_up_default_policy_keeps_prepare_only_for_direct_cli",
19338
19359
  projectUpPolicy.applyRequested === true
19339
19360
  && projectUpPolicy.startRequested === false
19340
- && projectUpPolicy.startDetachedRequested === true
19341
- && projectUpPolicy.shouldStartRunner === true,
19361
+ && projectUpPolicy.startDetachedRequested === false
19362
+ && projectUpPolicy.shouldStartRunner === false,
19342
19363
  `apply=${projectUpPolicy.applyRequested} start=${projectUpPolicy.startRequested} detached=${projectUpPolicy.startDetachedRequested} shouldStart=${projectUpPolicy.shouldStartRunner}`,
19343
19364
  );
19344
19365
  } catch (err) {
19345
- push("runner_project_up_default_policy_prefers_detached_start", false, String(err?.message || err));
19366
+ push("runner_project_up_default_policy_keeps_prepare_only_for_direct_cli", false, String(err?.message || err));
19346
19367
  }
19347
19368
 
19348
19369
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.289",
3
+ "version": "0.2.290",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [