/** * 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; /** * The one CloudWatch log group the hosted public demo reads. Its task role is * granted logs:FilterLogEvents on this group, plus DescribeLogGroups, and * nothing else. */ export declare const PUBLIC_DEMO_LOG_GROUP = "/log10x/otel-demo"; /** * Lead-in for every answer a code path gives instead of an AWS call in the * hosted public demo. Same wording as the demo gate above. */ export declare const PUBLIC_DEMO_AWS_UNAVAILABLE = "not available in the demo: attached read-only to the public 10x demo dataset"; /** * True when this process is the hosted public demo: demo mode (isDemoMode, or * the public demo key still in use) on the intentional playground * (LOG10X_MCP_DEMO_PLAYGROUND). In that state the process runs on an AWS role * anyone on the internet can drive, and that role is refused everything but * FilterLogEvents on PUBLIC_DEMO_LOG_GROUP (and DescribeLogGroups), so the * account-wide reads (SSM env-config, log-group fan-out, dependency inventory, * bucket discovery) must not be attempted. A refused call trips l1x-unauthorized-api-call. * * Deliberately narrower than isDemoMode alone. A keyless local boot is also in * demo mode, but its AWS credentials are the user's own and the POC lane runs * against the user's own CloudWatch; restricting it to the demo group would * break that lane, and it never touches the demo role. * * isDemoGated() is no help here: the playground flag turns it OFF. * * The process-key check covers a fresh loadEnvironments() (doctor reloads): * the demo key is in process.env by then, so the fresh object reads * isDemoMode: false while the process is still on the demo dataset. */ export declare function isPublicDemoPlayground(envs?: Environments): 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;