feat: move telemetry out of core into a usage statistics plugin

This commit is contained in:
LukeGus committed 2026-09-30 23:54:38 -05:00
1 parent f8edb5f299
commit 6217b91ae2
56 files changed
+2064 -564

No files matched your search

+16
View File
@@ -1958,6 +1958,20 @@ export interface PluginSystem {
registerTlsRenewer: () => Promise<() => void>;
}
/** One installed plugin as ctx.plugins.list reports it. */
export interface PluginSummary {
id: string;
version: string;
source: "bundled" | "user";
/** "active" when running; anything else means it is not. */
state: string;
}
/** The installed plugins. Needs plugins:read. */
export interface PluginPlugins {
list: () => Promise<PluginSummary[]>;
}
export interface PluginContext {
readonly pluginId: string;
readonly manifest: PluginManifest;
@@ -1999,6 +2013,8 @@ export interface PluginContext {
readonly process: PluginProcess;
/** The server certificate. Needs system:tls. */
readonly system: PluginSystem;
/** The installed plugins and whether each runs. Needs plugins:read. */
readonly plugins: PluginPlugins;
/**
* Runs `fn` with `userId` as the acting user, for background work that has
+1
View File
@@ -68,6 +68,7 @@ export const CAPABILITY_CATALOG: readonly CapabilityInfo[] = [
entry("files:own", "low"),
entry("secrets:own", "low"),
entry("settings:read-core", "low"),
entry("plugins:read", "low"),
entry("ui:surface", "low"),
] as const;
+26 -1
View File
@@ -78,6 +78,7 @@ import type {
PluginBinarySpec,
PluginTlsCertificateInfo,
PluginTlsStatus,
PluginSummary,
PluginKeyboardInteractiveHandler,
PluginProcessHandle,
PluginProcessOptions,
@@ -152,6 +153,8 @@ export interface FakeContextOptions {
* from registerTlsRenewer calls.
*/
tlsStatus?: Omit<PluginTlsStatus, "renewal">;
/** What ctx.plugins.list answers. Default: only this plugin, active. */
installedPlugins?: PluginSummary[];
/**
* Checks a ctx.system.writeTlsCertificate call. Throw to reject the pair.
* Without it every pair is accepted and described with placeholder info.
@@ -1233,6 +1236,18 @@ export function createFakeContext(
},
},
plugins: {
list: async () =>
options.installedPlugins ?? [
{
id: pluginId,
version: "1.0.0",
source: "bundled",
state: "active",
},
],
},
system: {
tlsStatus: async () => {
tls.calls.push("tlsStatus");
@@ -1416,6 +1431,8 @@ export interface MockContextOptions {
/** See FakeContextOptions. */
tlsStatus?: FakeContextOptions["tlsStatus"];
/** See FakeContextOptions. */
installedPlugins?: FakeContextOptions["installedPlugins"];
/** See FakeContextOptions. */
validateTls?: FakeContextOptions["validateTls"];
/** See FakeContextOptions. */
refuseEnrollment?: string;
@@ -1441,7 +1458,7 @@ export interface MockPluginContext extends FakePluginContext {
* topic outside the plugin's own namespace, settings:read-core on
* ctx.settings.readCore, ssh:connect plus credentials:use on ctx.ssh,
* notify:send on ctx.notify (notify:hub on serve), network:outbound on ctx.fetch, process:spawn on
* ctx.process, system:tls on ctx.system, and auth:provide on ctx.auth. Reading a plugin's own settings is deliberately
* ctx.process, system:tls on ctx.system, plugins:read on ctx.plugins, and auth:provide on ctx.auth. Reading a plugin's own settings is deliberately
* ungated. As the SDK grows a member, add its gate here in the same shape.
*/
export function createMockCtx(
@@ -1472,6 +1489,7 @@ export function createMockCtx(
fetch: options.fetch,
process: options.process,
tlsStatus: options.tlsStatus,
installedPlugins: options.installedPlugins,
validateTls: options.validateTls,
refuseEnrollment: options.refuseEnrollment,
baseUrl: options.baseUrl,
@@ -1838,6 +1856,13 @@ export function createMockCtx(
},
},
plugins: {
list: async () => {
require("plugins:read");
return ctx.plugins.list();
},
},
system: {
tlsStatus: async () => {
require("system:tls");