mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-14 21:20:42 +00:00
fix(cli): guide lookup misses
This commit is contained in:
@@ -5,12 +5,14 @@ import {
|
||||
setConfiguredMcpServer,
|
||||
unsetConfiguredMcpServer,
|
||||
} from "../config/mcp-config.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { serveOpenClawChannelMcp } from "../mcp/channel-server.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeStringifiedOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { formatCliCommand } from "./command-format.js";
|
||||
import { resolveGatewayAuthOptions } from "./gateway-secret-options.js";
|
||||
import { applyParentDefaultHelpAction } from "./program/parent-default-help.js";
|
||||
|
||||
@@ -52,7 +54,7 @@ export function registerMcpCli(program: Command) {
|
||||
claudeChannelMode !== "on" &&
|
||||
claudeChannelMode !== "off"
|
||||
) {
|
||||
throw new Error("Invalid --claude-channel-mode value. Use auto, on, or off.");
|
||||
throw new Error('Invalid --claude-channel-mode value. Use "auto", "on", or "off".');
|
||||
}
|
||||
await serveOpenClawChannelMcp({
|
||||
gatewayUrl: opts.url as string | undefined,
|
||||
@@ -62,7 +64,9 @@ export function registerMcpCli(program: Command) {
|
||||
verbose: Boolean(opts.verbose),
|
||||
});
|
||||
} catch (err) {
|
||||
defaultRuntime.error(String(err));
|
||||
defaultRuntime.error(
|
||||
`MCP server failed to start: ${formatErrorMessage(err)}. Run ${formatCliCommand("openclaw mcp list")} to inspect configured servers.`,
|
||||
);
|
||||
defaultRuntime.exit(1);
|
||||
}
|
||||
});
|
||||
@@ -82,7 +86,9 @@ export function registerMcpCli(program: Command) {
|
||||
}
|
||||
const names = Object.keys(loaded.mcpServers).toSorted();
|
||||
if (names.length === 0) {
|
||||
defaultRuntime.log(`No MCP servers configured in ${loaded.path}.`);
|
||||
defaultRuntime.log(
|
||||
`No MCP servers configured in ${loaded.path}. Add one with ${formatCliCommand('openclaw mcp set <name> \'{"command":"uvx","args":["context7-mcp"]}\'')}.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
defaultRuntime.log(`MCP servers (${loaded.path}):`);
|
||||
@@ -103,7 +109,9 @@ export function registerMcpCli(program: Command) {
|
||||
}
|
||||
const value = name ? loaded.mcpServers[name] : loaded.mcpServers;
|
||||
if (name && !value) {
|
||||
fail(`No MCP server named "${name}" in ${loaded.path}.`);
|
||||
fail(
|
||||
`No MCP server named "${name}" in ${loaded.path}. Run ${formatCliCommand("openclaw mcp list")} to see configured servers.`,
|
||||
);
|
||||
}
|
||||
if (opts.json) {
|
||||
printJson(value ?? {});
|
||||
@@ -144,7 +152,9 @@ export function registerMcpCli(program: Command) {
|
||||
fail(result.error);
|
||||
}
|
||||
if (!result.removed) {
|
||||
fail(`No MCP server named "${name}" in ${result.path}.`);
|
||||
fail(
|
||||
`No MCP server named "${name}" in ${result.path}. Run ${formatCliCommand("openclaw mcp list")} to see configured servers.`,
|
||||
);
|
||||
}
|
||||
defaultRuntime.log(`Removed MCP server "${name}" from ${result.path}.`);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { listAgentEntries, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import { isRouteBinding, listRouteBindings } from "../config/bindings.js";
|
||||
import { replaceConfigFile } from "../config/config.js";
|
||||
import { logConfigUpdated } from "../config/logging.js";
|
||||
@@ -80,12 +81,16 @@ function resolveTargetAgentIdOrExit(params: {
|
||||
fallbackToDefault: true,
|
||||
});
|
||||
if (!agentId) {
|
||||
params.runtime.error("Unable to resolve agent id.");
|
||||
params.runtime.error(
|
||||
`Unable to resolve agent id. Run ${formatCliCommand("openclaw agents list")} to choose one.`,
|
||||
);
|
||||
params.runtime.exit(1);
|
||||
return null;
|
||||
}
|
||||
if (!hasAgent(params.cfg, agentId)) {
|
||||
params.runtime.error(`Agent "${agentId}" not found.`);
|
||||
params.runtime.error(
|
||||
`Agent "${agentId}" not found. Run ${formatCliCommand("openclaw agents list")} to see configured agents.`,
|
||||
);
|
||||
params.runtime.exit(1);
|
||||
return null;
|
||||
}
|
||||
@@ -178,12 +183,16 @@ export async function agentsBindingsCommand(
|
||||
|
||||
const filterAgentId = resolveAgentId(cfg, opts.agent?.trim());
|
||||
if (opts.agent && !filterAgentId) {
|
||||
runtime.error("Agent id is required.");
|
||||
runtime.error(
|
||||
`Agent id is required. Run ${formatCliCommand("openclaw agents list")} to choose one.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
if (filterAgentId && !hasAgent(cfg, filterAgentId)) {
|
||||
runtime.error(`Agent "${filterAgentId}" not found.`);
|
||||
runtime.error(
|
||||
`Agent "${filterAgentId}" not found. Run ${formatCliCommand("openclaw agents list")} to see configured agents.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { findOverlappingWorkspaceAgentIds } from "../agents/agent-delete-safety.js";
|
||||
import { resolveAgentDir, resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import { replaceConfigFile } from "../config/config.js";
|
||||
import { logConfigUpdated } from "../config/logging.js";
|
||||
import {
|
||||
@@ -64,7 +65,9 @@ export async function agentsDeleteCommand(
|
||||
|
||||
const input = opts.id?.trim();
|
||||
if (!input) {
|
||||
runtime.error("Agent id is required.");
|
||||
runtime.error(
|
||||
`Agent id is required. Run ${formatCliCommand("openclaw agents list")} to choose one.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -80,7 +83,9 @@ export async function agentsDeleteCommand(
|
||||
}
|
||||
|
||||
if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) {
|
||||
runtime.error(`Agent "${agentId}" not found.`);
|
||||
runtime.error(
|
||||
`Agent "${agentId}" not found. Run ${formatCliCommand("openclaw agents list")} to see configured agents.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import path from "node:path";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import {
|
||||
resolveDefaultSessionStorePath,
|
||||
resolveSessionFilePath,
|
||||
@@ -86,7 +87,9 @@ export async function exportTrajectoryCommand(
|
||||
}
|
||||
const sessionKey = resolvedOpts.sessionKey?.trim();
|
||||
if (!sessionKey) {
|
||||
runtime.error("--session-key is required");
|
||||
runtime.error(
|
||||
`--session-key is required. Run ${formatCliCommand("openclaw sessions list")} to choose a session.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -97,7 +100,9 @@ export async function exportTrajectoryCommand(
|
||||
const store = loadSessionStore(storePath, { skipCache: true });
|
||||
const entry = store[sessionKey] as SessionEntry | undefined;
|
||||
if (!entry?.sessionId) {
|
||||
runtime.error(`Session not found: ${sessionKey}`);
|
||||
runtime.error(
|
||||
`Session not found: ${sessionKey}. Run ${formatCliCommand("openclaw sessions list")} to see available sessions.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -115,7 +120,9 @@ export async function exportTrajectoryCommand(
|
||||
return;
|
||||
}
|
||||
if (!(await pathExists(sessionFile))) {
|
||||
runtime.error("Session file not found.");
|
||||
runtime.error(
|
||||
`Session file not found for ${sessionKey}. Run ${formatCliCommand("openclaw doctor")} to inspect session storage.`,
|
||||
);
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { info } from "../globals.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
@@ -19,6 +20,10 @@ const MODE_PAD = 14;
|
||||
const REV_PAD = 6;
|
||||
const CTRL_PAD = 20;
|
||||
|
||||
function formatFlowLookupMiss(lookup: string): string {
|
||||
return `TaskFlow not found: ${lookup}. Run ${formatCliCommand("openclaw tasks flow list")} to see recent flow ids.`;
|
||||
}
|
||||
|
||||
function truncate(value: string, maxChars: number) {
|
||||
if (value.length <= maxChars) {
|
||||
return value;
|
||||
@@ -173,7 +178,9 @@ export async function flowsListCommand(
|
||||
runtime.log(info(`Status filter: ${statusFilter}`));
|
||||
}
|
||||
if (flows.length === 0) {
|
||||
runtime.log("No TaskFlows found.");
|
||||
runtime.log(
|
||||
`No TaskFlows found. Run ${formatCliCommand("openclaw tasks list")} to inspect standalone background tasks.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const rich = isRich();
|
||||
@@ -188,7 +195,7 @@ export async function flowsShowCommand(
|
||||
) {
|
||||
const flow = resolveTaskFlowForLookupToken(opts.lookup);
|
||||
if (!flow) {
|
||||
runtime.error(`TaskFlow not found: ${opts.lookup}`);
|
||||
runtime.error(formatFlowLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -245,7 +252,7 @@ export async function flowsShowCommand(
|
||||
export async function flowsCancelCommand(opts: { lookup: string }, runtime: RuntimeEnv) {
|
||||
const flow = resolveTaskFlowForLookupToken(opts.lookup);
|
||||
if (!flow) {
|
||||
runtime.error(`Flow not found: ${opts.lookup}`);
|
||||
runtime.error(formatFlowLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -254,7 +261,7 @@ export async function flowsCancelCommand(opts: { lookup: string }, runtime: Runt
|
||||
flowId: flow.flowId,
|
||||
});
|
||||
if (!result.found) {
|
||||
runtime.error(result.reason ?? `Flow not found: ${opts.lookup}`);
|
||||
runtime.error(result.reason ?? formatFlowLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveCronStorePath } from "../cron/store.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
@@ -46,6 +47,10 @@ const RUN_PAD = 10;
|
||||
|
||||
const info = theme.info;
|
||||
|
||||
function formatTaskLookupMiss(lookup: string): string {
|
||||
return `Task not found: ${lookup}. Run ${formatCliCommand("openclaw tasks list")} to see recent task ids.`;
|
||||
}
|
||||
|
||||
async function loadTaskCancelConfig() {
|
||||
return getRuntimeConfig();
|
||||
}
|
||||
@@ -313,7 +318,9 @@ export async function tasksListCommand(
|
||||
runtime.log(info(`Status filter: ${statusFilter}`));
|
||||
}
|
||||
if (tasks.length === 0) {
|
||||
runtime.log("No background tasks found.");
|
||||
runtime.log(
|
||||
`No background tasks found. Run ${formatCliCommand("openclaw tasks audit")} to check for stale task state.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const rich = isRich();
|
||||
@@ -328,7 +335,7 @@ export async function tasksShowCommand(
|
||||
) {
|
||||
const task = reconcileTaskLookupToken(opts.lookup);
|
||||
if (!task) {
|
||||
runtime.error(`Task not found: ${opts.lookup}`);
|
||||
runtime.error(formatTaskLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -374,7 +381,7 @@ export async function tasksNotifyCommand(
|
||||
) {
|
||||
const task = reconcileTaskLookupToken(opts.lookup);
|
||||
if (!task) {
|
||||
runtime.error(`Task not found: ${opts.lookup}`);
|
||||
runtime.error(formatTaskLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -383,7 +390,7 @@ export async function tasksNotifyCommand(
|
||||
notifyPolicy: opts.notify,
|
||||
});
|
||||
if (!updated) {
|
||||
runtime.error(`Task not found: ${opts.lookup}`);
|
||||
runtime.error(formatTaskLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -393,7 +400,7 @@ export async function tasksNotifyCommand(
|
||||
export async function tasksCancelCommand(opts: { lookup: string }, runtime: RuntimeEnv) {
|
||||
const task = reconcileTaskLookupToken(opts.lookup);
|
||||
if (!task) {
|
||||
runtime.error(`Task not found: ${opts.lookup}`);
|
||||
runtime.error(formatTaskLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -402,7 +409,7 @@ export async function tasksCancelCommand(opts: { lookup: string }, runtime: Runt
|
||||
taskId: task.taskId,
|
||||
});
|
||||
if (!result.found) {
|
||||
runtime.error(result.reason ?? `Task not found: ${opts.lookup}`);
|
||||
runtime.error(result.reason ?? formatTaskLookupMiss(opts.lookup));
|
||||
runtime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user