metheus-governance-mcp-cli 0.2.165 → 0.2.166
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 +4 -0
- package/cli.mjs +247 -54
- package/lib/local-project-dispatch.mjs +50 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -514,6 +514,8 @@ Workspace/source-of-truth model:
|
|
|
514
514
|
- `project-workspaces.json` answers only one question: `project_id -> local workspace_dir on this machine`
|
|
515
515
|
- use local tool `project.workspace` to read that binding
|
|
516
516
|
- use local tool `project.workspace.bind` to explicitly update that binding
|
|
517
|
+
- use local tool `runner.project_up` to audit a project destination and create/select the executable runner routes
|
|
518
|
+
- use local tool `runner.show` to inspect one resolved route before launch
|
|
517
519
|
- use local tool `runner.start_detached` to launch an existing runner route in a separate local terminal
|
|
518
520
|
- use local tool `runner.status` to inspect detached runner processes launched by this CLI
|
|
519
521
|
- use local tool `runner.stop` to stop detached runner processes launched by this CLI
|
|
@@ -587,6 +589,8 @@ Mapping behavior:
|
|
|
587
589
|
- use `project.workspace` to read the current local binding from `project-workspaces.json`
|
|
588
590
|
- use `project.workspace.bind` to intentionally write the binding into `project-workspaces.json`
|
|
589
591
|
- `project.workspace.bind` updates the workspace registry directly; it does not need `bot-runner.json` side effects to succeed
|
|
592
|
+
- use `runner.project_up` after workspace binding to prepare executable routes for one project destination
|
|
593
|
+
- use `runner.show` to inspect the selected route before launching it
|
|
590
594
|
|
|
591
595
|
Runner command contract:
|
|
592
596
|
- stdin: JSON payload containing project, destination, trigger message, and recent context comments
|
package/cli.mjs
CHANGED
|
@@ -4719,6 +4719,63 @@ function resolveRunnerProjectUpRoutes({
|
|
|
4719
4719
|
}
|
|
4720
4720
|
|
|
4721
4721
|
async function runRunnerProjectUp(flags) {
|
|
4722
|
+
const result = await buildRunnerProjectUpResult(flags);
|
|
4723
|
+
const { summaryPayload, applyRequested, applyResult, shouldStartRunner, matchingRoutes, startDetachedRequested, startFlags } = result;
|
|
4724
|
+
if (boolFromRaw(flags.json, false)) {
|
|
4725
|
+
process.stdout.write(`${JSON.stringify(summaryPayload, null, 2)}\n`);
|
|
4726
|
+
} else {
|
|
4727
|
+
process.stdout.write(
|
|
4728
|
+
[
|
|
4729
|
+
`Runner project up: ${summaryPayload.ok ? "OK" : "WARN"}`,
|
|
4730
|
+
`project_id: ${summaryPayload.project_id || "-"}`,
|
|
4731
|
+
`destination_label: ${summaryPayload.destination_label || "-"}`,
|
|
4732
|
+
`destination_id: ${summaryPayload.destination_id || "-"}`,
|
|
4733
|
+
`room_probe_ok: ${summaryPayload.room_probe_ok ? "true" : "false"}`,
|
|
4734
|
+
`room_visible_bot_admins: ${summaryPayload.room_visible_bot_admins}`,
|
|
4735
|
+
`my_server_bots: ${summaryPayload.my_server_bots}`,
|
|
4736
|
+
`my_local_bots: ${summaryPayload.my_local_bots}`,
|
|
4737
|
+
`bot_name_filter: ${summaryPayload.bot_name_filter}`,
|
|
4738
|
+
`bot_id_filter: ${summaryPayload.bot_id_filter}`,
|
|
4739
|
+
`role_filter: ${summaryPayload.role_filter}`,
|
|
4740
|
+
`route_suggestions_create_total: ${summaryPayload.route_suggestions_create_total}`,
|
|
4741
|
+
`route_suggestions_existing_total: ${summaryPayload.route_suggestions_existing_total}`,
|
|
4742
|
+
`route_suggestions_blocked_total: ${summaryPayload.route_suggestions_blocked_total}`,
|
|
4743
|
+
`route_apply_requested: ${summaryPayload.route_apply_requested ? "true" : "false"}`,
|
|
4744
|
+
`route_apply_changed: ${summaryPayload.route_apply_changed ? "true" : "false"}`,
|
|
4745
|
+
`route_config_file: ${summaryPayload.route_config_file}`,
|
|
4746
|
+
`enabled_routes_for_selection: ${summaryPayload.enabled_routes_for_selection.join(", ") || "-"}`,
|
|
4747
|
+
`start_requested: ${summaryPayload.start_requested ? "true" : "false"}`,
|
|
4748
|
+
`start_detached_requested: ${summaryPayload.start_detached_requested ? "true" : "false"}`,
|
|
4749
|
+
`next_steps: ${summaryPayload.next_steps.join(" | ") || "-"}`,
|
|
4750
|
+
].join("\n") + "\n",
|
|
4751
|
+
);
|
|
4752
|
+
}
|
|
4753
|
+
if (applyRequested && applyResult.ok === false) {
|
|
4754
|
+
process.exitCode = 1;
|
|
4755
|
+
if (shouldStartRunner) {
|
|
4756
|
+
throw new Error(String(applyResult.error || "runner project up could not apply runner routes").trim());
|
|
4757
|
+
}
|
|
4758
|
+
return;
|
|
4759
|
+
}
|
|
4760
|
+
if (!shouldStartRunner) {
|
|
4761
|
+
return;
|
|
4762
|
+
}
|
|
4763
|
+
if (!matchingRoutes.length) {
|
|
4764
|
+
throw new Error("runner project up did not find any enabled routes for the selected project destination");
|
|
4765
|
+
}
|
|
4766
|
+
if (!boolFromRaw(flags.json, false)) {
|
|
4767
|
+
process.stdout.write(
|
|
4768
|
+
`${startDetachedRequested ? "Starting detached runner" : "Starting runner"} for project ${summaryPayload.project_id} destination ${summaryPayload.destination_label || summaryPayload.destination_id} using ${matchingRoutes.length} enabled route(s).\n`,
|
|
4769
|
+
);
|
|
4770
|
+
}
|
|
4771
|
+
if (startDetachedRequested) {
|
|
4772
|
+
await runRunnerStartDetachedResolvedRoutes(matchingRoutes, startFlags, "runner project up");
|
|
4773
|
+
return;
|
|
4774
|
+
}
|
|
4775
|
+
await runRunnerStartResolvedRoutes(matchingRoutes, startFlags);
|
|
4776
|
+
}
|
|
4777
|
+
|
|
4778
|
+
async function buildRunnerProjectUpResult(flags = {}) {
|
|
4722
4779
|
const ui = createPrompter();
|
|
4723
4780
|
try {
|
|
4724
4781
|
if (shouldRenderPromptChrome(flags)) {
|
|
@@ -4776,6 +4833,7 @@ async function runRunnerProjectUp(flags) {
|
|
|
4776
4833
|
changed: false,
|
|
4777
4834
|
filePath: String(auditPayload.routeSuggestionConfigFilePath || "").trim(),
|
|
4778
4835
|
appliedRoutes: [],
|
|
4836
|
+
disabledRoutes: [],
|
|
4779
4837
|
error: "route apply skipped because the Telegram room visibility probe failed",
|
|
4780
4838
|
})
|
|
4781
4839
|
: null;
|
|
@@ -4820,6 +4878,8 @@ async function runRunnerProjectUp(flags) {
|
|
|
4820
4878
|
start_requested: shouldStartRunner,
|
|
4821
4879
|
start_detached_requested: startDetachedRequested,
|
|
4822
4880
|
next_steps: [],
|
|
4881
|
+
applied_routes: ensureArray(applyResult.appliedRoutes).map((item) => safeObject(item)),
|
|
4882
|
+
disabled_routes: ensureArray(applyResult.disabledRoutes).map((item) => safeObject(item)),
|
|
4823
4883
|
};
|
|
4824
4884
|
if (!applyRequested) {
|
|
4825
4885
|
summaryPayload.next_steps.push(`${CLI_NAME} runner project up --project-id ${summaryPayload.project_id} --provider ${provider} --destination-id ${summaryPayload.destination_id} --apply true --start false`);
|
|
@@ -4828,58 +4888,18 @@ async function runRunnerProjectUp(flags) {
|
|
|
4828
4888
|
} else {
|
|
4829
4889
|
summaryPayload.next_steps.push(`${CLI_NAME} runner show --route-name ${summaryPayload.enabled_routes_for_selection[0] || "<route_name>"}`);
|
|
4830
4890
|
}
|
|
4831
|
-
if (
|
|
4832
|
-
|
|
4833
|
-
} else {
|
|
4834
|
-
process.stdout.write(
|
|
4835
|
-
[
|
|
4836
|
-
`Runner project up: ${summaryPayload.ok ? "OK" : "WARN"}`,
|
|
4837
|
-
`project_id: ${summaryPayload.project_id || "-"}`,
|
|
4838
|
-
`destination_label: ${summaryPayload.destination_label || "-"}`,
|
|
4839
|
-
`destination_id: ${summaryPayload.destination_id || "-"}`,
|
|
4840
|
-
`room_probe_ok: ${summaryPayload.room_probe_ok ? "true" : "false"}`,
|
|
4841
|
-
`room_visible_bot_admins: ${summaryPayload.room_visible_bot_admins}`,
|
|
4842
|
-
`my_server_bots: ${summaryPayload.my_server_bots}`,
|
|
4843
|
-
`my_local_bots: ${summaryPayload.my_local_bots}`,
|
|
4844
|
-
`bot_name_filter: ${summaryPayload.bot_name_filter}`,
|
|
4845
|
-
`bot_id_filter: ${summaryPayload.bot_id_filter}`,
|
|
4846
|
-
`role_filter: ${summaryPayload.role_filter}`,
|
|
4847
|
-
`route_suggestions_create_total: ${summaryPayload.route_suggestions_create_total}`,
|
|
4848
|
-
`route_suggestions_existing_total: ${summaryPayload.route_suggestions_existing_total}`,
|
|
4849
|
-
`route_suggestions_blocked_total: ${summaryPayload.route_suggestions_blocked_total}`,
|
|
4850
|
-
`route_apply_requested: ${summaryPayload.route_apply_requested ? "true" : "false"}`,
|
|
4851
|
-
`route_apply_changed: ${summaryPayload.route_apply_changed ? "true" : "false"}`,
|
|
4852
|
-
`route_config_file: ${summaryPayload.route_config_file}`,
|
|
4853
|
-
`enabled_routes_for_selection: ${summaryPayload.enabled_routes_for_selection.join(", ") || "-"}`,
|
|
4854
|
-
`start_requested: ${summaryPayload.start_requested ? "true" : "false"}`,
|
|
4855
|
-
`start_detached_requested: ${summaryPayload.start_detached_requested ? "true" : "false"}`,
|
|
4856
|
-
`next_steps: ${summaryPayload.next_steps.join(" | ") || "-"}`,
|
|
4857
|
-
].join("\n") + "\n",
|
|
4858
|
-
);
|
|
4859
|
-
}
|
|
4860
|
-
if (applyRequested && applyResult.ok === false) {
|
|
4861
|
-
process.exitCode = 1;
|
|
4862
|
-
if (shouldStartRunner) {
|
|
4863
|
-
throw new Error(String(applyResult.error || "runner project up could not apply runner routes").trim());
|
|
4864
|
-
}
|
|
4865
|
-
return;
|
|
4866
|
-
}
|
|
4867
|
-
if (!shouldStartRunner) {
|
|
4868
|
-
return;
|
|
4869
|
-
}
|
|
4870
|
-
if (!matchingRoutes.length) {
|
|
4871
|
-
throw new Error("runner project up did not find any enabled routes for the selected project destination");
|
|
4872
|
-
}
|
|
4873
|
-
if (!boolFromRaw(flags.json, false)) {
|
|
4874
|
-
process.stdout.write(
|
|
4875
|
-
`${startDetachedRequested ? "Starting detached runner" : "Starting runner"} for project ${summaryPayload.project_id} destination ${summaryPayload.destination_label || summaryPayload.destination_id} using ${matchingRoutes.length} enabled route(s).\n`,
|
|
4876
|
-
);
|
|
4877
|
-
}
|
|
4878
|
-
if (startDetachedRequested) {
|
|
4879
|
-
await runRunnerStartDetachedResolvedRoutes(matchingRoutes, startFlags, "runner project up");
|
|
4880
|
-
return;
|
|
4891
|
+
if (applyRequested && applyResult.ok === false && applyResult.error) {
|
|
4892
|
+
summaryPayload.error = String(applyResult.error || "").trim();
|
|
4881
4893
|
}
|
|
4882
|
-
|
|
4894
|
+
return {
|
|
4895
|
+
summaryPayload,
|
|
4896
|
+
applyRequested,
|
|
4897
|
+
applyResult,
|
|
4898
|
+
shouldStartRunner,
|
|
4899
|
+
startDetachedRequested,
|
|
4900
|
+
matchingRoutes,
|
|
4901
|
+
startFlags,
|
|
4902
|
+
};
|
|
4883
4903
|
} finally {
|
|
4884
4904
|
ui.close();
|
|
4885
4905
|
}
|
|
@@ -7314,6 +7334,9 @@ function buildLocalProjectDispatchDeps() {
|
|
|
7314
7334
|
normalizeMergeAction,
|
|
7315
7335
|
executeCtxpackMergeActionForTool: (params) => executeCtxpackMergeActionForTool(params, buildProjectToolDeps()),
|
|
7316
7336
|
buildCtxpackMergeExecuteText,
|
|
7337
|
+
buildRunnerProjectUpResult: (flags) => buildRunnerProjectUpResult(flags),
|
|
7338
|
+
resolveRunnerShowSelection: (flags) => resolveRunnerShowSelection(flags),
|
|
7339
|
+
buildRunnerShowPayload: (route, flags) => buildRunnerShowPayload(route, flags),
|
|
7317
7340
|
startDetachedRunnerWithFlags: (flags, sourceCommand) => startDetachedRunnerWithFlags(flags, sourceCommand),
|
|
7318
7341
|
buildRunnerDetachedStatusPayload: (flags) => buildRunnerDetachedStatusPayload(flags),
|
|
7319
7342
|
stopDetachedRunnerWithFlags: (flags) => stopDetachedRunnerWithFlags(flags),
|
|
@@ -7853,6 +7876,8 @@ const LOCAL_PROJECT_TOOL_NAMES = [
|
|
|
7853
7876
|
"project.workspace.bind",
|
|
7854
7877
|
];
|
|
7855
7878
|
const LOCAL_RUNNER_TOOL_NAMES = [
|
|
7879
|
+
"runner.project_up",
|
|
7880
|
+
"runner.show",
|
|
7856
7881
|
"runner.start_detached",
|
|
7857
7882
|
"runner.status",
|
|
7858
7883
|
"runner.stop",
|
|
@@ -7997,6 +8022,46 @@ function buildRunnerStartDetachedInputSchema() {
|
|
|
7997
8022
|
};
|
|
7998
8023
|
}
|
|
7999
8024
|
|
|
8025
|
+
function buildRunnerProjectUpInputSchema() {
|
|
8026
|
+
return {
|
|
8027
|
+
type: "object",
|
|
8028
|
+
properties: {
|
|
8029
|
+
project_id: { type: "string", description: "Project UUID to audit and bind to a destination." },
|
|
8030
|
+
provider: { type: "string", enum: ["telegram"], description: "Provider. runner.project_up currently supports telegram only." },
|
|
8031
|
+
destination_id: { type: "string", description: "Destination UUID filter." },
|
|
8032
|
+
destination_label: { type: "string", description: "Destination label filter." },
|
|
8033
|
+
bot_name: { type: "string", description: "Server bot name filter." },
|
|
8034
|
+
bot_id: { type: "string", description: "Server bot UUID filter." },
|
|
8035
|
+
role: { type: "string", enum: ["monitor", "review", "worker", "approval"], description: "Single role filter." },
|
|
8036
|
+
roles: { type: "string", description: "Comma-separated role filter list." },
|
|
8037
|
+
apply: { type: "boolean", description: "If true, create/disable routes as suggested. Defaults to true." },
|
|
8038
|
+
start: { type: "boolean", description: "If true, start the resolved routes after apply." },
|
|
8039
|
+
start_detached: { type: "boolean", description: "If true, start in a separate local terminal after apply." },
|
|
8040
|
+
dry_run_delivery: { type: "boolean", description: "If true, do not actually send provider replies." },
|
|
8041
|
+
concurrency: { type: "integer", minimum: 1, description: "Max concurrent scheduling groups." },
|
|
8042
|
+
},
|
|
8043
|
+
required: ["project_id"],
|
|
8044
|
+
additionalProperties: false,
|
|
8045
|
+
};
|
|
8046
|
+
}
|
|
8047
|
+
|
|
8048
|
+
function buildRunnerShowInputSchema() {
|
|
8049
|
+
return {
|
|
8050
|
+
type: "object",
|
|
8051
|
+
properties: {
|
|
8052
|
+
route_name: { type: "string", description: "Exact runner route name." },
|
|
8053
|
+
bot_name: { type: "string", description: "Server bot name when one enabled route matches." },
|
|
8054
|
+
bot_id: { type: "string", description: "Server bot UUID when one enabled route matches." },
|
|
8055
|
+
project_id: { type: "string", description: "Project UUID filter." },
|
|
8056
|
+
provider: { type: "string", enum: ["telegram", "slack", "kakaotalk"], description: "Provider filter." },
|
|
8057
|
+
role: { type: "string", enum: ["monitor", "review", "worker", "approval"], description: "Role filter." },
|
|
8058
|
+
destination_id: { type: "string", description: "Destination UUID filter." },
|
|
8059
|
+
destination_label: { type: "string", description: "Destination label filter." },
|
|
8060
|
+
},
|
|
8061
|
+
additionalProperties: false,
|
|
8062
|
+
};
|
|
8063
|
+
}
|
|
8064
|
+
|
|
8000
8065
|
function buildRunnerStatusInputSchema() {
|
|
8001
8066
|
return {
|
|
8002
8067
|
type: "object",
|
|
@@ -8056,6 +8121,18 @@ function buildLocalToolSpecs() {
|
|
|
8056
8121
|
"Bind a project_id to a local workspace_dir in project-workspaces.json so local runner and AI execution use the correct project folder.",
|
|
8057
8122
|
inputSchema: buildProjectWorkspaceBindInputSchema(),
|
|
8058
8123
|
},
|
|
8124
|
+
{
|
|
8125
|
+
name: "runner.project_up",
|
|
8126
|
+
description:
|
|
8127
|
+
"Audit one project destination, create missing runner routes, and optionally start polling. Use this before runner.start_detached when the route is not ready yet.",
|
|
8128
|
+
inputSchema: buildRunnerProjectUpInputSchema(),
|
|
8129
|
+
},
|
|
8130
|
+
{
|
|
8131
|
+
name: "runner.show",
|
|
8132
|
+
description:
|
|
8133
|
+
"Inspect one resolved runner route and report workspace mapping, execution profile, and last run details.",
|
|
8134
|
+
inputSchema: buildRunnerShowInputSchema(),
|
|
8135
|
+
},
|
|
8059
8136
|
{
|
|
8060
8137
|
name: "runner.start_detached",
|
|
8061
8138
|
description:
|
|
@@ -8508,6 +8585,8 @@ function appendProjectHintToInitialize(responseObj, args, options = {}) {
|
|
|
8508
8585
|
const projectWorkspaceTool = displayToolNameForClient("project.workspace", useSafeToolAliases);
|
|
8509
8586
|
const projectWorkspaceBindTool = displayToolNameForClient("project.workspace.bind", useSafeToolAliases);
|
|
8510
8587
|
const projectSummaryTool = displayToolNameForClient("project.summary", useSafeToolAliases);
|
|
8588
|
+
const runnerProjectUpTool = displayToolNameForClient("runner.project_up", useSafeToolAliases);
|
|
8589
|
+
const runnerShowTool = displayToolNameForClient("runner.show", useSafeToolAliases);
|
|
8511
8590
|
const runnerStartDetachedTool = displayToolNameForClient("runner.start_detached", useSafeToolAliases);
|
|
8512
8591
|
const runnerStatusTool = displayToolNameForClient("runner.status", useSafeToolAliases);
|
|
8513
8592
|
const runnerStopTool = displayToolNameForClient("runner.stop", useSafeToolAliases);
|
|
@@ -8528,6 +8607,7 @@ function appendProjectHintToInitialize(responseObj, args, options = {}) {
|
|
|
8528
8607
|
: []),
|
|
8529
8608
|
`- MUST call \`${projectWorkspaceTool}\` first when the user provides only a Project ID and you need the local project folder/workspace binding.`,
|
|
8530
8609
|
`- Use \`${projectWorkspaceBindTool}\` only when you need to explicitly write/update the local project-workspaces.json registry binding.`,
|
|
8610
|
+
`- Use \`${runnerProjectUpTool}\` to audit a project destination and create/select runner routes before starting polling. Then use \`${runnerShowTool}\` to inspect the resolved route if needed.`,
|
|
8531
8611
|
`- To run automated polling independently of the current AI session, call \`${runnerStartDetachedTool}\` after the workspace binding and route are ready. Use \`${runnerStatusTool}\` to inspect detached runner processes and \`${runnerStopTool}\` to stop them later.`,
|
|
8532
8612
|
`- After resolving the local workspace, call \`${projectSummaryTool}\` for project overview/agenda/server metadata.`,
|
|
8533
8613
|
`- If user enters a Project ID in text (e.g., "Project ID <uuid>"), pass that exact UUID as \`project_id\` argument when calling \`${projectSummaryTool}\`.`,
|
|
@@ -9732,12 +9812,125 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
9732
9812
|
push("detached_runner_linux_launcher_selects_supported_terminal", false, String(err?.message || err));
|
|
9733
9813
|
}
|
|
9734
9814
|
|
|
9815
|
+
try {
|
|
9816
|
+
const projectUpResponse = await handleLocalProjectToolDispatchImpl(
|
|
9817
|
+
{
|
|
9818
|
+
requestObj: {
|
|
9819
|
+
jsonrpc: "2.0",
|
|
9820
|
+
id: 8,
|
|
9821
|
+
method: "tools/call",
|
|
9822
|
+
params: {
|
|
9823
|
+
name: "runner.project_up",
|
|
9824
|
+
arguments: {
|
|
9825
|
+
project_id: selftestProjectID,
|
|
9826
|
+
destination_label: "Selftest Room",
|
|
9827
|
+
},
|
|
9828
|
+
},
|
|
9829
|
+
},
|
|
9830
|
+
toolName: "runner.project_up",
|
|
9831
|
+
toolArgs: {
|
|
9832
|
+
project_id: selftestProjectID,
|
|
9833
|
+
destination_label: "Selftest Room",
|
|
9834
|
+
},
|
|
9835
|
+
args: {
|
|
9836
|
+
baseURL: DEFAULT_SITE_URL,
|
|
9837
|
+
timeoutSeconds: 30,
|
|
9838
|
+
},
|
|
9839
|
+
token: "selftest-token",
|
|
9840
|
+
workspaceDir: "",
|
|
9841
|
+
workspaceSignalTrusted: true,
|
|
9842
|
+
},
|
|
9843
|
+
{
|
|
9844
|
+
...buildLocalProjectDispatchDeps(),
|
|
9845
|
+
buildRunnerProjectUpResult: async () => ({
|
|
9846
|
+
summaryPayload: {
|
|
9847
|
+
ok: true,
|
|
9848
|
+
project_id: selftestProjectID,
|
|
9849
|
+
destination_label: "Selftest Room",
|
|
9850
|
+
destination_id: "dest-1",
|
|
9851
|
+
route_apply_requested: true,
|
|
9852
|
+
route_apply_changed: true,
|
|
9853
|
+
enabled_routes_for_selection: ["telegram-monitor-selftest"],
|
|
9854
|
+
next_steps: [`${CLI_NAME} runner show --route-name telegram-monitor-selftest`],
|
|
9855
|
+
},
|
|
9856
|
+
matchingRoutes: [{ name: "telegram-monitor-selftest" }],
|
|
9857
|
+
applyRequested: true,
|
|
9858
|
+
applyResult: { ok: true, changed: true },
|
|
9859
|
+
shouldStartRunner: false,
|
|
9860
|
+
startDetachedRequested: false,
|
|
9861
|
+
startFlags: {},
|
|
9862
|
+
}),
|
|
9863
|
+
},
|
|
9864
|
+
);
|
|
9865
|
+
const projectUpStructured = safeObject(safeObject(projectUpResponse).result)?.structuredContent || {};
|
|
9866
|
+
push(
|
|
9867
|
+
"local_runner_project_up_tool_dispatches",
|
|
9868
|
+
projectUpStructured.ok === true
|
|
9869
|
+
&& ensureArray(projectUpStructured.enabled_routes_for_selection).includes("telegram-monitor-selftest"),
|
|
9870
|
+
`routes=${ensureArray(projectUpStructured.enabled_routes_for_selection).join(",")} next=${ensureArray(projectUpStructured.next_steps).join(" | ")}`,
|
|
9871
|
+
);
|
|
9872
|
+
} catch (err) {
|
|
9873
|
+
push("local_runner_project_up_tool_dispatches", false, String(err?.message || err));
|
|
9874
|
+
}
|
|
9875
|
+
|
|
9876
|
+
try {
|
|
9877
|
+
const showResponse = await handleLocalProjectToolDispatchImpl(
|
|
9878
|
+
{
|
|
9879
|
+
requestObj: {
|
|
9880
|
+
jsonrpc: "2.0",
|
|
9881
|
+
id: 9,
|
|
9882
|
+
method: "tools/call",
|
|
9883
|
+
params: {
|
|
9884
|
+
name: "runner.show",
|
|
9885
|
+
arguments: {
|
|
9886
|
+
route_name: "telegram-monitor-selftest",
|
|
9887
|
+
},
|
|
9888
|
+
},
|
|
9889
|
+
},
|
|
9890
|
+
toolName: "runner.show",
|
|
9891
|
+
toolArgs: {
|
|
9892
|
+
route_name: "telegram-monitor-selftest",
|
|
9893
|
+
},
|
|
9894
|
+
args: {
|
|
9895
|
+
baseURL: DEFAULT_SITE_URL,
|
|
9896
|
+
timeoutSeconds: 30,
|
|
9897
|
+
},
|
|
9898
|
+
token: "selftest-token",
|
|
9899
|
+
workspaceDir: "",
|
|
9900
|
+
workspaceSignalTrusted: true,
|
|
9901
|
+
},
|
|
9902
|
+
{
|
|
9903
|
+
...buildLocalProjectDispatchDeps(),
|
|
9904
|
+
resolveRunnerShowSelection: () => ({ name: "telegram-monitor-selftest" }),
|
|
9905
|
+
buildRunnerShowPayload: () => ({
|
|
9906
|
+
ok: true,
|
|
9907
|
+
route_name: "telegram-monitor-selftest",
|
|
9908
|
+
route_config: { project_id: selftestProjectID },
|
|
9909
|
+
resolved_destination: { destination_label: "Selftest Room" },
|
|
9910
|
+
workspace_mapping: { workspace_dir: "C:\\selftest-workspace", workspace_source: "project-workspaces.json:manual_override" },
|
|
9911
|
+
execution_profile: { permission_mode: "read_only" },
|
|
9912
|
+
warnings: [],
|
|
9913
|
+
errors: [],
|
|
9914
|
+
}),
|
|
9915
|
+
},
|
|
9916
|
+
);
|
|
9917
|
+
const showStructured = safeObject(safeObject(showResponse).result)?.structuredContent || {};
|
|
9918
|
+
push(
|
|
9919
|
+
"local_runner_show_tool_dispatches",
|
|
9920
|
+
showStructured.ok === true
|
|
9921
|
+
&& String(showStructured.route_name || "").trim() === "telegram-monitor-selftest",
|
|
9922
|
+
`route=${String(showStructured.route_name || "").trim() || "(none)"} workspace=${String(safeObject(showStructured.workspace_mapping).workspace_dir || "").trim() || "-"}`,
|
|
9923
|
+
);
|
|
9924
|
+
} catch (err) {
|
|
9925
|
+
push("local_runner_show_tool_dispatches", false, String(err?.message || err));
|
|
9926
|
+
}
|
|
9927
|
+
|
|
9735
9928
|
try {
|
|
9736
9929
|
const startResponse = await handleLocalProjectToolDispatchImpl(
|
|
9737
9930
|
{
|
|
9738
9931
|
requestObj: {
|
|
9739
9932
|
jsonrpc: "2.0",
|
|
9740
|
-
id:
|
|
9933
|
+
id: 10,
|
|
9741
9934
|
method: "tools/call",
|
|
9742
9935
|
params: {
|
|
9743
9936
|
name: "runner.start_detached",
|
|
@@ -9791,7 +9984,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
9791
9984
|
{
|
|
9792
9985
|
requestObj: {
|
|
9793
9986
|
jsonrpc: "2.0",
|
|
9794
|
-
id:
|
|
9987
|
+
id: 11,
|
|
9795
9988
|
method: "tools/call",
|
|
9796
9989
|
params: {
|
|
9797
9990
|
name: "runner.status",
|
|
@@ -9843,7 +10036,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
9843
10036
|
{
|
|
9844
10037
|
requestObj: {
|
|
9845
10038
|
jsonrpc: "2.0",
|
|
9846
|
-
id:
|
|
10039
|
+
id: 12,
|
|
9847
10040
|
method: "tools/call",
|
|
9848
10041
|
params: {
|
|
9849
10042
|
name: "runner.stop",
|
|
@@ -57,6 +57,9 @@ export async function handleLocalProjectToolDispatch(
|
|
|
57
57
|
const normalizeMergeAction = requireDependency(deps, "normalizeMergeAction");
|
|
58
58
|
const executeCtxpackMergeActionForTool = requireDependency(deps, "executeCtxpackMergeActionForTool");
|
|
59
59
|
const buildCtxpackMergeExecuteText = requireDependency(deps, "buildCtxpackMergeExecuteText");
|
|
60
|
+
const buildRunnerProjectUpResult = requireDependency(deps, "buildRunnerProjectUpResult");
|
|
61
|
+
const resolveRunnerShowSelection = requireDependency(deps, "resolveRunnerShowSelection");
|
|
62
|
+
const buildRunnerShowPayload = requireDependency(deps, "buildRunnerShowPayload");
|
|
60
63
|
const startDetachedRunnerWithFlags = requireDependency(deps, "startDetachedRunnerWithFlags");
|
|
61
64
|
const buildRunnerDetachedStatusPayload = requireDependency(deps, "buildRunnerDetachedStatusPayload");
|
|
62
65
|
const stopDetachedRunnerWithFlags = requireDependency(deps, "stopDetachedRunnerWithFlags");
|
|
@@ -241,6 +244,53 @@ export async function handleLocalProjectToolDispatch(
|
|
|
241
244
|
|
|
242
245
|
if (localRunnerToolNames.includes(toolName)) {
|
|
243
246
|
try {
|
|
247
|
+
if (toolName === "runner.project_up") {
|
|
248
|
+
const normalizedFlags = {
|
|
249
|
+
...toolArgs,
|
|
250
|
+
...(Object.prototype.hasOwnProperty.call(toolArgs, "project_id") ? {} : { project_id: resolveProjectID(toolArgs, args, workspaceDir, deps) }),
|
|
251
|
+
...(Object.prototype.hasOwnProperty.call(toolArgs, "start") ? {} : { start: false }),
|
|
252
|
+
...(Object.prototype.hasOwnProperty.call(toolArgs, "start_detached") ? {} : { start_detached: false }),
|
|
253
|
+
...(Object.prototype.hasOwnProperty.call(toolArgs, "json") ? {} : { json: true }),
|
|
254
|
+
};
|
|
255
|
+
const result = await buildRunnerProjectUpResult(normalizedFlags);
|
|
256
|
+
const payload = {
|
|
257
|
+
...safeObject(result.summaryPayload),
|
|
258
|
+
matching_routes: ensureArray(result.matchingRoutes).map((route) => String(safeObject(route).name || "").trim()).filter(Boolean),
|
|
259
|
+
};
|
|
260
|
+
const text = [
|
|
261
|
+
`ok: ${payload.ok ? "true" : "false"}`,
|
|
262
|
+
`project_id: ${String(payload.project_id || "").trim() || "-"}`,
|
|
263
|
+
`destination_label: ${String(payload.destination_label || "").trim() || "-"}`,
|
|
264
|
+
`destination_id: ${String(payload.destination_id || "").trim() || "-"}`,
|
|
265
|
+
`route_apply_requested: ${payload.route_apply_requested ? "true" : "false"}`,
|
|
266
|
+
`route_apply_changed: ${payload.route_apply_changed ? "true" : "false"}`,
|
|
267
|
+
`enabled_routes_for_selection: ${ensureArray(payload.enabled_routes_for_selection).join(", ") || "-"}`,
|
|
268
|
+
`next_steps: ${ensureArray(payload.next_steps).join(" | ") || "-"}`,
|
|
269
|
+
].join("\n");
|
|
270
|
+
return jsonRpcResult(requestObj, {
|
|
271
|
+
content: [{ type: "text", text }],
|
|
272
|
+
structuredContent: payload,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (toolName === "runner.show") {
|
|
276
|
+
const route = resolveRunnerShowSelection(toolArgs);
|
|
277
|
+
const payload = buildRunnerShowPayload(route, toolArgs);
|
|
278
|
+
const text = [
|
|
279
|
+
`ok: ${payload.ok ? "true" : "false"}`,
|
|
280
|
+
`route_name: ${String(payload.route_name || "").trim() || "-"}`,
|
|
281
|
+
`project_id: ${String(safeObject(payload.route_config).project_id || "").trim() || "-"}`,
|
|
282
|
+
`destination_label: ${String(safeObject(payload.resolved_destination).destination_label || "").trim() || "-"}`,
|
|
283
|
+
`workspace_dir: ${String(safeObject(payload.workspace_mapping).workspace_dir || "").trim() || "-"}`,
|
|
284
|
+
`workspace_source: ${String(safeObject(payload.workspace_mapping).workspace_source || "").trim() || "-"}`,
|
|
285
|
+
`permission_mode: ${String(safeObject(payload.execution_profile).permission_mode || "").trim() || "-"}`,
|
|
286
|
+
`warnings: ${ensureArray(payload.warnings).join(" | ") || "-"}`,
|
|
287
|
+
`errors: ${ensureArray(payload.errors).join(" | ") || "-"}`,
|
|
288
|
+
].join("\n");
|
|
289
|
+
return jsonRpcResult(requestObj, {
|
|
290
|
+
content: [{ type: "text", text }],
|
|
291
|
+
structuredContent: payload,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
244
294
|
if (toolName === "runner.start_detached") {
|
|
245
295
|
const payload = await startDetachedRunnerWithFlags(toolArgs, "runner.start_detached");
|
|
246
296
|
const launch = safeObject(payload.launch);
|