refactor: normalize cli command hints

This commit is contained in:
Peter Steinberger
2026-01-20 07:42:21 +00:00
parent 11b9b6dba5
commit 6d5195c890
106 changed files with 521 additions and 220 deletions

View File

@@ -1,3 +1,4 @@
import { formatCliCommand } from "../../cli/command-format.js";
import type { ClawdbotConfig } from "../../config/config.js";
import { normalizeProviderId } from "../model-selection.js";
import { listProfilesForProvider } from "./profiles.js";
@@ -37,6 +38,6 @@ export function formatAuthDoctorHint(params: {
}`,
`- auth store oauth profiles: ${storeOauthProfiles || "(none)"}`,
`- suggested profile: ${suggested}`,
'Fix: run "clawdbot doctor --yes"',
`Fix: run "${formatCliCommand("clawdbot doctor --yes")}"`,
].join("\n");
}

View File

@@ -4,6 +4,7 @@ import { type Api, getEnvApiKey, type Model } from "@mariozechner/pi-ai";
import type { ClawdbotConfig } from "../config/config.js";
import type { ModelProviderConfig } from "../config/types.js";
import { getShellEnvAppliedKeys } from "../infra/shell-env.js";
import { formatCliCommand } from "../cli/command-format.js";
import {
type AuthProfileStore,
ensureAuthProfileStore,
@@ -103,7 +104,7 @@ export async function resolveApiKeyForProvider(params: {
[
`No API key found for provider "${provider}".`,
`Auth store: ${authStorePath} (agentDir: ${resolvedAgentDir}).`,
"Configure auth for this agent (clawdbot agents add <id>) or copy auth-profiles.json from the main agentDir.",
`Configure auth for this agent (${formatCliCommand("clawdbot agents add <id>")}) or copy auth-profiles.json from the main agentDir.`,
].join(" "),
);
}

View File

@@ -1,6 +1,7 @@
import { spawn } from "node:child_process";
import { defaultRuntime } from "../../runtime.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { DEFAULT_SANDBOX_IMAGE, SANDBOX_AGENT_WORKSPACE_MOUNT } from "./constants.js";
import { readRegistry, updateRegistry } from "./registry.js";
import { computeSandboxConfigHash } from "./config-hash.js";
@@ -214,13 +215,13 @@ async function readContainerConfigHash(containerName: string): Promise<string |
function formatSandboxRecreateHint(params: { scope: SandboxConfig["scope"]; sessionKey: string }) {
if (params.scope === "session") {
return `clawdbot sandbox recreate --session ${params.sessionKey}`;
return formatCliCommand(`clawdbot sandbox recreate --session ${params.sessionKey}`);
}
if (params.scope === "agent") {
const agentId = resolveSandboxAgentId(params.sessionKey) ?? "main";
return `clawdbot sandbox recreate --agent ${agentId}`;
return formatCliCommand(`clawdbot sandbox recreate --agent ${agentId}`);
}
return "clawdbot sandbox recreate --all";
return formatCliCommand("clawdbot sandbox recreate --all");
}
export async function ensureSandboxContainer(params: {

View File

@@ -2,6 +2,7 @@ import type { ClawdbotConfig } from "../../config/config.js";
import { canonicalizeMainSessionAlias, resolveAgentMainSessionKey } from "../../config/sessions.js";
import { resolveSessionAgentId } from "../agent-scope.js";
import { expandToolGroups } from "../tool-policy.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { resolveSandboxConfigForAgent } from "./config.js";
import { resolveSandboxToolPolicyForAgent } from "./tool-policy.js";
import type { SandboxConfig, SandboxToolPolicyResolved } from "./types.js";
@@ -115,7 +116,9 @@ export function formatSandboxToolPolicyBlockedMessage(params: {
if (runtime.mode === "non-main") {
lines.push(`- Use main session key (direct): ${runtime.mainSessionKey}`);
}
lines.push(`- See: clawdbot sandbox explain --session ${runtime.sessionKey}`);
lines.push(
`- See: ${formatCliCommand(`clawdbot sandbox explain --session ${runtime.sessionKey}`)}`,
);
return lines.join("\n");
}

View File

@@ -1,5 +1,6 @@
import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js";
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
import { formatCliCommand } from "../cli/command-format.js";
import { listDeliverableMessageChannels } from "../utils/message-channel.js";
import type { ResolvedTimeFormat } from "./date-time.js";
import type { EmbeddedContextFile } from "./pi-embedded-helpers.js";
@@ -124,7 +125,7 @@ function buildDocsSection(params: { docsPath?: string; isMinimal: boolean; readT
"Community: https://discord.com/invite/clawd",
"Find new skills: https://clawdhub.com",
"For Clawdbot behavior, commands, config, or architecture: consult local docs first.",
"When diagnosing issues, run `clawdbot status` yourself when possible; only ask the user if you lack access (e.g., sandboxed).",
`When diagnosing issues, run \`${formatCliCommand("clawdbot status")}\` yourself when possible; only ask the user if you lack access (e.g., sandboxed).`,
"",
];
}
@@ -364,11 +365,11 @@ export function buildAgentSystemPrompt(params: {
"## Clawdbot CLI Quick Reference",
"Clawdbot is controlled via subcommands. Do not invent commands.",
"To manage the Gateway daemon service (start/stop/restart):",
"- clawdbot daemon status",
"- clawdbot daemon start",
"- clawdbot daemon stop",
"- clawdbot daemon restart",
"If unsure, ask the user to run `clawdbot help` (or `clawdbot daemon --help`) and paste the output.",
`- ${formatCliCommand("clawdbot daemon status")}`,
`- ${formatCliCommand("clawdbot daemon start")}`,
`- ${formatCliCommand("clawdbot daemon stop")}`,
`- ${formatCliCommand("clawdbot daemon restart")}`,
`If unsure, ask the user to run \`${formatCliCommand("clawdbot help")}\` (or \`${formatCliCommand("clawdbot daemon --help")}\`) and paste the output.`,
"",
...skillsSection,
...memorySection,

View File

@@ -5,7 +5,7 @@ import { Type } from "@sinclair/typebox";
import type { ClawdbotConfig } from "../../config/config.js";
import { scheduleGatewaySigusr1Restart } from "../../infra/restart.js";
import {
DOCTOR_NONINTERACTIVE_HINT,
formatDoctorNonInteractiveHint,
type RestartSentinelPayload,
writeRestartSentinel,
} from "../../infra/restart-sentinel.js";
@@ -83,7 +83,7 @@ export function createGatewayTool(opts?: {
ts: Date.now(),
sessionKey,
message: note ?? reason ?? null,
doctorHint: DOCTOR_NONINTERACTIVE_HINT,
doctorHint: formatDoctorNonInteractiveHint(),
stats: {
mode: "gateway.restart",
reason,

View File

@@ -1,6 +1,7 @@
import { Type } from "@sinclair/typebox";
import type { ClawdbotConfig } from "../../config/config.js";
import { formatCliCommand } from "../../cli/command-format.js";
import type { AnyAgentTool } from "./common.js";
import { jsonResult, readNumberParam, readStringParam } from "./common.js";
import {
@@ -124,8 +125,7 @@ function missingSearchKeyPayload(provider: (typeof SEARCH_PROVIDERS)[number]) {
}
return {
error: "missing_brave_api_key",
message:
"web_search needs a Brave Search API key. Run `clawdbot configure --section web` to store it, or set BRAVE_API_KEY in the Gateway environment.",
message: `web_search needs a Brave Search API key. Run \`${formatCliCommand("clawdbot configure --section web")}\` to store it, or set BRAVE_API_KEY in the Gateway environment.`,
docs: "https://docs.clawd.bot/tools/web",
};
}

View File

@@ -4,6 +4,7 @@ import path from "node:path";
import { fileURLToPath } from "node:url";
import { isSubagentSessionKey } from "../routing/session-key.js";
import { formatCliCommand } from "../cli/command-format.js";
import { resolveUserPath } from "../utils.js";
export function resolveDefaultAgentWorkspaceDir(
@@ -135,7 +136,7 @@ After the user chooses, update:
- Notes
3) ~/.clawdbot/clawdbot.json
Run: clawdbot agents set-identity --workspace "<this workspace>" --from-identity
Run: ${formatCliCommand('clawdbot agents set-identity --workspace "<this workspace>" --from-identity')}
If multiple agents share a host, add --agent <id>.
## Cleanup