// ---------------------------------------------------------------------------// Server-side product-analytics event catalog.//// The server analog of the browser catalog in packages/react/src/api/// analytics.tsx, which is BROWSER-ONLY by design (its own header says server// events need their own seam — this is that seam). Cloud keeps its browser// client; this catalog is for the surfaces that had none: the local daemon// (CLI + desktop) and self-host.//// PROPERTY RULES (same line the browser catalog draws):// - Metadata about product usage only — the question these answer is "how// are product features being used", never "what is this user doing".// - Never secrets, tokens, credentials, code, tool arguments or results.// - Never user free text: no connection names, no tool addresses, no// toolkit slugs (user-entered labels — send booleans/counts instead).// - Plugin keys (`openapi`, `mcp`, `graphql`, ...) ARE allowed: a fixed,// product-defined vocabulary. Integration slugs are NOT — stricter than// the browser catalog: these events leave the user's own infrastructure,// and WHICH integrations someone uses is their business, not ours. The// kind of integration is the product question; the slug is not.// - Identity is the anonymous per-install id only; no emails, no hostnames,// no person or org names.// ---------------------------------------------------------------------------/** * Which door an execution came through. Bound structurally by the host (each * serving plane wraps its engine once), never inferred from a header or flag: * - `mcp` — an agent invoking over the MCP surface. * - `api` — the HTTP executions API (CLI `call`/`resume`, the web console). */export type ExecutionPlane = "mcp" | "api";/** * Which door an artifact operation came through: an agent calling the MCP * artifact tools, or a human in the console UI (whose data layer is the * artifacts HTTP API). Bound at each door's composition point, mirroring * `ExecutionPlane`. */export type ArtifactVia = "agent" | "ui";export interface AnalyticsEvents { /** * A code execution reached a terminal outcome. Recorded once per execution * at completion — a paused execution is recorded when its resume completes, * not when it pauses. `toolkit` marks executions served by a toolkit-scoped * MCP endpoint (the toolkit's slug is a user label and deliberately absent). */ execution_completed: { readonly ok: boolean; readonly plane: ExecutionPlane; readonly toolkit: boolean; }; /** An integration row was created (upsert re-registers are not counted). */ integration_added: { readonly plugin_key: string }; /** An integration was removed by the user. */ integration_removed: { readonly plugin_key: string }; /** A generative-UI artifact was saved as a new row. */ artifact_created: { readonly via: ArtifactVia }; /** * An artifact was opened for its content: the agent's `show-artifact` or * the console detail page. Internal reads (binding resolution inside an * execution) deliberately do not count. */ artifact_viewed: { readonly via: ArtifactVia }; /** An existing artifact was overwritten in place, or renamed. */ artifact_updated: { readonly via: ArtifactVia }; /** An artifact was deleted. Only the UI offers deletion today. */ artifact_deleted: { readonly via: ArtifactVia };}export type AnalyticsEventName = keyof AnalyticsEvents;
// ---------------------------------------------------------------------------
// Server-side product-analytics event catalog.
//
// The server analog of the browser catalog in packages/react/src/api/
// analytics.tsx, which is BROWSER-ONLY by design (its own header says server
// events need their own seam — this is that seam). Cloud keeps its browser
// client; this catalog is for the surfaces that had none: the local daemon
// (CLI + desktop) and self-host.
//
// PROPERTY RULES (same line the browser catalog draws):
// - Metadata about product usage only — the question these answer is "how
// are product features being used", never "what is this user doing".
// - Never secrets, tokens, credentials, code, tool arguments or results.
// - Never user free text: no connection names, no tool addresses, no
// toolkit slugs (user-entered labels — send booleans/counts instead).
// - Plugin keys (`openapi`, `mcp`, `graphql`, ...) ARE allowed: a fixed,
// product-defined vocabulary. Integration slugs are NOT — stricter than
// the browser catalog: these events leave the user's own infrastructure,
// and WHICH integrations someone uses is their business, not ours. The
// kind of integration is the product question; the slug is not.
// - Identity is the anonymous per-install id only; no emails, no hostnames,
// no person or org names.
// ---------------------------------------------------------------------------
/**
* Which door an execution came through. Bound structurally by the host (each
* serving plane wraps its engine once), never inferred from a header or flag:
* - `mcp` — an agent invoking over the MCP surface.
* - `api` — the HTTP executions API (CLI `call`/`resume`, the web console).
*/
export type ExecutionPlane = "mcp" | "api";
/**
* Which door an artifact operation came through: an agent calling the MCP
* artifact tools, or a human in the console UI (whose data layer is the
* artifacts HTTP API). Bound at each door's composition point, mirroring
* `ExecutionPlane`.
*/
export type ArtifactVia = "agent" | "ui";
export interface AnalyticsEvents {
/**
* A code execution reached a terminal outcome. Recorded once per execution
* at completion — a paused execution is recorded when its resume completes,
* not when it pauses. `toolkit` marks executions served by a toolkit-scoped
* MCP endpoint (the toolkit's slug is a user label and deliberately absent).
*/
execution_completed: {
readonly ok: boolean;
readonly plane: ExecutionPlane;
readonly toolkit: boolean;
};
/** An integration row was created (upsert re-registers are not counted). */
integration_added: { readonly plugin_key: string };
/** An integration was removed by the user. */
integration_removed: { readonly plugin_key: string };
/** A generative-UI artifact was saved as a new row. */
artifact_created: { readonly via: ArtifactVia };
/**
* An artifact was opened for its content: the agent's `show-artifact` or
* the console detail page. Internal reads (binding resolution inside an
* execution) deliberately do not count.
*/
artifact_viewed: { readonly via: ArtifactVia };
/** An existing artifact was overwritten in place, or renamed. */
artifact_updated: { readonly via: ArtifactVia };
/** An artifact was deleted. Only the UI offers deletion today. */
artifact_deleted: { readonly via: ArtifactVia };
}
export type AnalyticsEventName = keyof AnalyticsEvents;