feat(coding-agent): add install telemetry ping controls
This commit is contained in:
@@ -323,6 +323,7 @@ ${chalk.bold("Environment Variables:")}
|
||||
${ENV_AGENT_DIR.padEnd(32)} - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
|
||||
PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)
|
||||
PI_OFFLINE - Disable startup network operations when set to 1/true/yes
|
||||
PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no
|
||||
PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/)
|
||||
PI_AI_ANTIGRAVITY_VERSION - Override Antigravity User-Agent version (e.g., 1.23.0)
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ export interface Settings {
|
||||
shellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., "shopt -s expand_aliases" for alias support)
|
||||
npmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., ["mise", "exec", "node@20", "--", "npm"])
|
||||
collapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)
|
||||
enableInstallTelemetry?: boolean; // default: true - anonymous version/update ping after changelog-detected updates
|
||||
packages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)
|
||||
extensions?: string[]; // Array of local extension file paths or directories
|
||||
skills?: string[]; // Array of local skill file paths or directories
|
||||
@@ -736,6 +737,16 @@ export class SettingsManager {
|
||||
this.save();
|
||||
}
|
||||
|
||||
getEnableInstallTelemetry(): boolean {
|
||||
return this.settings.enableInstallTelemetry ?? true;
|
||||
}
|
||||
|
||||
setEnableInstallTelemetry(enabled: boolean): void {
|
||||
this.globalSettings.enableInstallTelemetry = enabled;
|
||||
this.markModified("enableInstallTelemetry");
|
||||
this.save();
|
||||
}
|
||||
|
||||
getPackages(): PackageSource[] {
|
||||
return [...(this.settings.packages ?? [])];
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ export interface SettingsConfig {
|
||||
availableThemes: string[];
|
||||
hideThinkingBlock: boolean;
|
||||
collapseChangelog: boolean;
|
||||
enableInstallTelemetry: boolean;
|
||||
doubleEscapeAction: "fork" | "tree" | "none";
|
||||
treeFilterMode: "default" | "no-tools" | "user-only" | "labeled-only" | "all";
|
||||
showHardwareCursor: boolean;
|
||||
@@ -66,6 +67,7 @@ export interface SettingsCallbacks {
|
||||
onThemePreview?: (theme: string) => void;
|
||||
onHideThinkingBlockChange: (hidden: boolean) => void;
|
||||
onCollapseChangelogChange: (collapsed: boolean) => void;
|
||||
onEnableInstallTelemetryChange: (enabled: boolean) => void;
|
||||
onDoubleEscapeActionChange: (action: "fork" | "tree" | "none") => void;
|
||||
onTreeFilterModeChange: (mode: "default" | "no-tools" | "user-only" | "labeled-only" | "all") => void;
|
||||
onShowHardwareCursorChange: (enabled: boolean) => void;
|
||||
@@ -206,6 +208,13 @@ export class SettingsSelectorComponent extends Container {
|
||||
currentValue: config.quietStartup ? "true" : "false",
|
||||
values: ["true", "false"],
|
||||
},
|
||||
{
|
||||
id: "install-telemetry",
|
||||
label: "Install telemetry",
|
||||
description: "Send an anonymous version/update ping after changelog-detected updates",
|
||||
currentValue: config.enableInstallTelemetry ? "true" : "false",
|
||||
values: ["true", "false"],
|
||||
},
|
||||
{
|
||||
id: "double-escape-action",
|
||||
label: "Double-escape action",
|
||||
@@ -396,6 +405,9 @@ export class SettingsSelectorComponent extends Container {
|
||||
case "quiet-startup":
|
||||
callbacks.onQuietStartupChange(newValue === "true");
|
||||
break;
|
||||
case "install-telemetry":
|
||||
callbacks.onEnableInstallTelemetryChange(newValue === "true");
|
||||
break;
|
||||
case "double-escape-action":
|
||||
callbacks.onDoubleEscapeActionChange(newValue as "fork" | "tree");
|
||||
break;
|
||||
|
||||
@@ -136,6 +136,11 @@ function isAnthropicSubscriptionAuthKey(apiKey: string | undefined): boolean {
|
||||
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
||||
}
|
||||
|
||||
function isTruthyEnvFlag(value: string | undefined): boolean {
|
||||
if (!value) return false;
|
||||
return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for InteractiveMode initialization.
|
||||
*/
|
||||
@@ -767,20 +772,41 @@ export class InteractiveMode {
|
||||
const entries = parseChangelog(changelogPath);
|
||||
|
||||
if (!lastVersion) {
|
||||
// Fresh install - just record the version, don't show changelog
|
||||
// Fresh install - record the version, send telemetry, don't show changelog
|
||||
this.settingsManager.setLastChangelogVersion(VERSION);
|
||||
this.reportInstallTelemetry(VERSION);
|
||||
return undefined;
|
||||
} else {
|
||||
const newEntries = getNewEntries(entries, lastVersion);
|
||||
if (newEntries.length > 0) {
|
||||
this.settingsManager.setLastChangelogVersion(VERSION);
|
||||
return newEntries.map((e) => e.content).join("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
const newEntries = getNewEntries(entries, lastVersion);
|
||||
if (newEntries.length > 0) {
|
||||
this.settingsManager.setLastChangelogVersion(VERSION);
|
||||
this.reportInstallTelemetry(VERSION);
|
||||
return newEntries.map((e) => e.content).join("\n\n");
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private reportInstallTelemetry(version: string): void {
|
||||
if (process.env.PI_OFFLINE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const telemetryEnv = process.env.PI_TELEMETRY;
|
||||
const telemetryEnabled =
|
||||
telemetryEnv !== undefined ? isTruthyEnvFlag(telemetryEnv) : this.settingsManager.getEnableInstallTelemetry();
|
||||
if (!telemetryEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
void fetch(`https://pi.dev/install?version=${encodeURIComponent(version)}`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
})
|
||||
.then(() => undefined)
|
||||
.catch(() => undefined);
|
||||
}
|
||||
|
||||
private getMarkdownThemeWithSettings(): MarkdownTheme {
|
||||
return {
|
||||
...getMarkdownTheme(),
|
||||
@@ -3352,6 +3378,7 @@ export class InteractiveMode {
|
||||
availableThemes: getAvailableThemes(),
|
||||
hideThinkingBlock: this.hideThinkingBlock,
|
||||
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
||||
enableInstallTelemetry: this.settingsManager.getEnableInstallTelemetry(),
|
||||
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
||||
treeFilterMode: this.settingsManager.getTreeFilterMode(),
|
||||
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
||||
@@ -3427,6 +3454,9 @@ export class InteractiveMode {
|
||||
onCollapseChangelogChange: (collapsed) => {
|
||||
this.settingsManager.setCollapseChangelog(collapsed);
|
||||
},
|
||||
onEnableInstallTelemetryChange: (enabled) => {
|
||||
this.settingsManager.setEnableInstallTelemetry(enabled);
|
||||
},
|
||||
onQuietStartupChange: (enabled) => {
|
||||
this.settingsManager.setQuietStartup(enabled);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user