feat(coding-agent): add experimental first-time setup flow (#5587)

Behind PI_EXPERIMENTAL=1, show a first-time setup dialog on interactive startup when the default agent directory is used and settings.json does not exist. The dialog preselects the detected terminal appearance with an explicit dark/light choice (live preview) and asks for opt-in analytics data sharing. Submitting writes settings.json, which serves as the completion marker; opting in stores a generated trackingId. Escape at any point skips out of setup.
This commit is contained in:
Vegard Stikbakke
2026-06-10 12:11:49 +02:00
committed by GitHub
parent a3cd03e7ff
commit 0ab2aa86af
8 changed files with 342 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
import type { Transport } from "@earendil-works/pi-ai";
import { randomUUID } from "crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
import { dirname, join } from "path";
import lockfile from "proper-lockfile";
@@ -96,6 +97,8 @@ export interface Settings {
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
enableAnalytics?: boolean; // default: false - opt-in analytics data sharing
trackingId?: string; // analytics tracking identifier, generated when analytics is enabled
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
@@ -907,6 +910,25 @@ export class SettingsManager {
this.save();
}
getEnableAnalytics(): boolean {
return this.settings.enableAnalytics ?? false;
}
getTrackingId(): string | undefined {
return this.settings.trackingId;
}
/** Set the analytics opt-in preference; generates a tracking identifier on first opt-in */
setEnableAnalytics(enabled: boolean): void {
this.globalSettings.enableAnalytics = enabled;
this.markModified("enableAnalytics");
if (enabled && !this.globalSettings.trackingId) {
this.globalSettings.trackingId = randomUUID();
this.markModified("trackingId");
}
this.save();
}
getPackages(): PackageSource[] {
return [...(this.settings.packages ?? [])];
}