export interface InstallEventPayload { skillId: string; source: 'mcp' | 'cli' | 'vscode'; success: boolean; durationMs?: number; trustTier?: string; errorCode?: string; } /** * SMI-5193: Search-event payload emitted from the MCP `search` tool to the * Skillsmith telemetry endpoint (`/functions/v1/events`). * * **All keys MUST be snake_case** — the `events` edge function's * `sanitizeMetadata` allowlists `results_count`, `duration_ms`, `has_query`, * `trust_tier`, `category`. camelCase variants are silently dropped server-side * (event accepted, metadata lost). The event name is `'search'` (in the edge * function's `ALLOWED_EVENTS`); `'skill_search'` would 400 silently. */ export interface SearchEventPayload { query: string; results_count: number; duration_ms: number; has_query: boolean; trust_tier?: string; category?: string; } /** * Emit a skill-install event to Skillsmith's remote telemetry endpoint. * * Best-effort: never throws, never blocks the caller. Silently skips in these cases: * - No API key available (CLI offline / unauthenticated) * - SKILLSMITH_TELEMETRY=0 (opt-out) * - Network / endpoint failure * * The API key is mapped to a namespaced, non-reversible telemetry actor ID * (HMAC-SHA-256 keyed by `skillsmith-telemetry-actor:v1`) before transmission. * The server stores that digest as `actor` — never the raw key, never an * email, never a user ID. * * Event shape when emitted: * event_type: "telemetry:skill_install" * actor: hmac_sha256("skillsmith-telemetry-actor:v1", apiKey) hex * metadata: { skill_id, source, success, duration_ms?, trust_tier?, error_code? } */ export declare function emitInstallEvent(payload: InstallEventPayload): Promise; /** * SMI-5193: Emit a search event to Skillsmith's remote telemetry endpoint. * * Fire-and-forget (synchronous, returns `void`) — wraps `postTelemetryEvent` * with `void` so the caller never awaits. The MCP search tool calls this * after a search completes so the usage report's search count reflects MCP * searches (landing in `search_metrics` via the `events` edge function). * * Silently skips in these cases: * - No API key available (CLI offline / unauthenticated) * - SKILLSMITH_TELEMETRY=0 (opt-out) * - Network / endpoint failure * * CRITICAL — silent-failure modes that motivated this signature: * - `event` MUST be `'search'` (in `events/index.ts` ALLOWED_EVENTS). * `'skill_search'` would 400 silently. * - `anonymous_id` is REQUIRED (validated as 16-128 char hex server-side). * Missing → 400 silently. * - Metadata keys MUST be snake_case — `sanitizeMetadata` allowlists * `results_count`, `duration_ms`, `has_query`, `trust_tier`, `category`. * camelCase variants are silently dropped. */ export declare function emitSearchEvent(payload: SearchEventPayload): void; /** * The synchronously-available, background-refreshed identity `wrap.ts` * needs to attribute a `tool_call` event. Never resolved inline on the * emit path — see `setTelemetryIdentityProvider`. * * `sdkVersion` is deliberately optional and resolved by the mcp-server * caller (`context.async.ts`), not here: `@skillsmith/core` has no * dependency on `@modelcontextprotocol/sdk` or any mcp-server package * metadata, so this module must stay agnostic to how the caller derives it. * * `tier` is intentionally NOT part of this shape yet. Wave 3 (SMI-6362) * ships without it: the only synchronous, already-cached tier resolver in * the codebase (`createLicenseMiddleware`'s per-instance cache, * `middleware/license.ts`) is constructed in `index.ts`'s `main()`, after * `context.async.ts` (where this provider is installed) has already run — * `context.async.ts` cannot reach it without a new cross-module wiring path, * which is out of this wave's stated file footprint. Named limitation, * tracked as a Wave 6 follow-up in the plan doc — not silently dropped. */ export interface TelemetryIdentity { accessToken: string; apiKey?: string; sdkVersion?: string; } export type TelemetryIdentityProvider = () => TelemetryIdentity | null; /** * Install (or clear, with `null`) the module-level identity provider * `emitToolCallEvent` reads synchronously on every call. The provider itself * must never block — see the design note in the SMI-6362 plan §1 * ("Credential plumbing"): the cache is refreshed in the background by the * caller (on install, on 401, and on a timer), never inline here. */ export declare function setTelemetryIdentityProvider(provider: TelemetryIdentityProvider | null): void; export declare function setTelemetryIdentityInvalidationHandler(handler: (() => void) | null): void; /** Payload `wrap.ts`'s second sink builds per MCP tool call. */ export interface ToolCallEventPayload { toolName: string; framework: string; durationMs: number; success: boolean; /** SMI-6362 §1: from the agent-marker file's own session id, when present. */ sessionId?: string; /** * SMI-6362 §1: always `false` this wave. No MCP harness today distinguishes * a subagent-issued tool call from a top-level one at the protocol level — * the marker channel's `_meta`/file schema (SMI-5456) has no such field, * and subagents share the SAME MCP server process as the top-level agent, * so there is no process-level signal either. Sending a guessed value * would be actively misleading in a paid analytics surface; `false` is the * only honest default until a real signal exists. Named limitation, * tracked as a Wave 6 follow-up in the plan doc (parallel to D-9). */ isSubagent: boolean; errorName?: string; errorMessage?: string; } interface TelemetryEmitStats { accepted: number; rejected: number; failed: number; skippedNoIdentity: number; /** * SMI-6362 Wave 4 (D-8, completing what Wave 3 left unexported): the * `X-Skillsmith-Telemetry-Reason` from the most recent rejection, so the * read path (`analytics.ts` AC-10) can render an actionable line — e.g. * `ambiguous_team` -> "set SKILLSMITH_LICENSE_KEY to choose which team" — * instead of just a count. `null` until the first rejection this process. */ lastRejectionReason: string | null; } /** SMI-6362 (D-8): a snapshot of this process's `tool_call` emission outcomes. */ export declare function getTelemetryEmitStats(): TelemetryEmitStats; /** Reset for tests only. */ export declare function _resetTelemetryEmitStatsForTests(): void; /** * SMI-6362 §1: emit a `tool_call` event for an MCP tool invocation. * * Fire-and-forget (synchronous, returns `void`), mirroring `emitSearchEvent`. * Reads the identity provider synchronously; if none is installed or it * returns `null` (no cached credential yet), the event is skipped entirely * — never sent unauthenticated, per the plan's "no fallback to an * unauthenticated POST" rule (§1, "Credential plumbing"). */ export declare function emitToolCallEvent(payload: ToolCallEventPayload): void; export {}; //# sourceMappingURL=remote-audit.d.ts.map