/** * One answer to "will this tool actually run right now?". * * Two gates decide that, and neither may live where only `wrap()` in * index.ts can see them: the demo gate (a metric-requiring tool called * while the MCP is attached read-only to the public demo dataset) and the * mode gate (a tool the boot-time mode-detect did not register). Anything * that ROUTES a user to a tool — log10x_start's action_menu, a remediation * `actions[]` — had no way to ask, so it guessed, and the guesses drifted. * * The drift was measurable. On a keyless boot the banner says "attaching to * the public demo dataset", log10x_baseline returns real numbers off that * same dataset, and log10x_start emitted action_menu item `investigate_spike` * with `applicable: true` routing to log10x_top_patterns — which then refused * with `not_configured (metrics_backend)`. The menu offered a door the gate * was holding shut. * * So the gates move here and both callers read the same function. The gate * behaviour is unchanged: this module is where it is asked, not a new policy. */ import { type ModeResolution } from './mode-detect.js'; import type { Environments } from './environments.js'; /** * Tools that query the metrics backend (top_patterns, whats_changing, * etc.). When the MCP is in pure-demo mode (no user configuration, * silently landed on the demo backend), these tools short-circuit * with a structured `not_configured` response instead of returning * demo data the user didn't ask for. We surface the conversation * starter without breaking the demo-mode walkthrough; the silent-demo * path will be removed in a later release. * * Tools NOT in this set bypass the gate: configure_env (the * onboarding tool itself), doctor (status reporting works in any * mode), local-only tools (resolve_batch, extract_templates, * dependency_check pasted input), signin_* (log10x account * management), discover_env (k8s discovery), poc_from_* (pre-config * sample reports). */ export declare const METRIC_REQUIRING_TOOLS: ReadonlySet; /** * When set, the MCP is an intentional read-only demo playground: the metric * tools serve the public demo data instead of the not_configured onboarding * nag. isDemoMode stays true, so the demo banner still renders — we just stop * nagging. Set by the hosted deployment. * * Read per call rather than captured at import: the hosted deployment sets it * before boot, but tests flip it between cases and a module-load snapshot * would freeze the first value they happened to load under. */ export declare function demoPlaygroundEnabled(): boolean; /** * The demo gate. True when this tool will short-circuit with the * `not_configured` envelope instead of querying: a metric-requiring tool, * pure-demo state (nothing configured, silently landed on the demo backend), * and not an intentional playground. * * `demoFallbackReason` being set is a DIFFERENT state — the user tried to * configure and their credentials failed — which gets its own loud banner and * does not take this path. */ export declare function isDemoGated(toolName: string, envs: Environments | undefined): boolean; export declare function recordEnvsProvider(provider: () => Environments | undefined): void; export declare function recordBootMode(mode: ModeResolution | undefined): void; export declare function peekBootMode(): ModeResolution | undefined; /** True when the boot-time mode-detect did not register this tool. */ export declare function isOutOfMode(toolName: string): boolean; /** * Why calling `toolName` right now would not do the job, or null when it * would. The string is user-facing: it goes straight into an action_menu * item's `gated_reason`, so it names a tool that IS callable in this state * rather than the one the gate just refused. * * Argument validation is deliberately out of scope. A tool that needs a * `service` or a `from` timestamp is not refusing the user — the agent * supplies those from the conversation. */ export declare function toolUnavailableReason(toolName: string, envs?: Environments | undefined): string | null;