mirror of
https://github.com/earendil-works/pi.git
synced 2026-06-18 15:54:04 +08:00
0ab2aa86af
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.
96 lines
2.9 KiB
TypeScript
96 lines
2.9 KiB
TypeScript
import { mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
import { tmpdir } from "os";
|
|
import { join } from "path";
|
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
import { shouldRunFirstTimeSetup } from "../src/cli/startup-ui.ts";
|
|
import { ENV_AGENT_DIR } from "../src/config.ts";
|
|
import { SettingsManager } from "../src/core/settings-manager.ts";
|
|
|
|
describe("shouldRunFirstTimeSetup", () => {
|
|
const originalPiExperimental = process.env.PI_EXPERIMENTAL;
|
|
const originalAgentDir = process.env[ENV_AGENT_DIR];
|
|
let tempDir: string;
|
|
let settingsPath: string;
|
|
|
|
beforeEach(() => {
|
|
tempDir = mkdtempSync(join(tmpdir(), "pi-first-time-setup-"));
|
|
settingsPath = join(tempDir, "settings.json");
|
|
process.env.PI_EXPERIMENTAL = "1";
|
|
delete process.env[ENV_AGENT_DIR];
|
|
});
|
|
|
|
afterEach(() => {
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
if (originalPiExperimental === undefined) {
|
|
delete process.env.PI_EXPERIMENTAL;
|
|
} else {
|
|
process.env.PI_EXPERIMENTAL = originalPiExperimental;
|
|
}
|
|
if (originalAgentDir === undefined) {
|
|
delete process.env[ENV_AGENT_DIR];
|
|
} else {
|
|
process.env[ENV_AGENT_DIR] = originalAgentDir;
|
|
}
|
|
});
|
|
|
|
it("returns true when experimental, default agent dir, and no settings.json", () => {
|
|
expect(shouldRunFirstTimeSetup(settingsPath)).toBe(true);
|
|
});
|
|
|
|
it("returns false when experimental features are disabled", () => {
|
|
delete process.env.PI_EXPERIMENTAL;
|
|
|
|
expect(shouldRunFirstTimeSetup(settingsPath)).toBe(false);
|
|
});
|
|
|
|
it("returns false when a custom agent dir is set", () => {
|
|
process.env[ENV_AGENT_DIR] = tempDir;
|
|
|
|
expect(shouldRunFirstTimeSetup(settingsPath)).toBe(false);
|
|
});
|
|
|
|
it("returns false when settings.json already exists", () => {
|
|
writeFileSync(settingsPath, "{}", "utf-8");
|
|
|
|
expect(shouldRunFirstTimeSetup(settingsPath)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("analytics settings", () => {
|
|
it("defaults to disabled with no tracking identifier", () => {
|
|
const manager = SettingsManager.inMemory();
|
|
|
|
expect(manager.getEnableAnalytics()).toBe(false);
|
|
expect(manager.getTrackingId()).toBeUndefined();
|
|
});
|
|
|
|
it("generates a tracking identifier on opt-in", () => {
|
|
const manager = SettingsManager.inMemory();
|
|
|
|
manager.setEnableAnalytics(true);
|
|
|
|
expect(manager.getEnableAnalytics()).toBe(true);
|
|
expect(manager.getTrackingId()).toMatch(/^[0-9a-f-]{36}$/);
|
|
});
|
|
|
|
it("does not generate a tracking identifier on opt-out", () => {
|
|
const manager = SettingsManager.inMemory();
|
|
|
|
manager.setEnableAnalytics(false);
|
|
|
|
expect(manager.getEnableAnalytics()).toBe(false);
|
|
expect(manager.getTrackingId()).toBeUndefined();
|
|
});
|
|
|
|
it("keeps the tracking identifier when toggling analytics", () => {
|
|
const manager = SettingsManager.inMemory();
|
|
|
|
manager.setEnableAnalytics(true);
|
|
const trackingId = manager.getTrackingId();
|
|
manager.setEnableAnalytics(false);
|
|
manager.setEnableAnalytics(true);
|
|
|
|
expect(manager.getTrackingId()).toBe(trackingId);
|
|
});
|
|
});
|