60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
import { existsSync, readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const HOME = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
const PI_SETTINGS_PATH = join(HOME, ".pi", "agent", "settings.json");
|
|
|
|
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
}
|
|
|
|
function toCamelCase(value: string): string {
|
|
return value.replace(/-([a-z])/g, (_match, letter: string) => letter.toUpperCase());
|
|
}
|
|
|
|
function readPiSettings(): Record<string, unknown> | null {
|
|
if (!existsSync(PI_SETTINGS_PATH)) {
|
|
return null;
|
|
}
|
|
try {
|
|
return JSON.parse(readFileSync(PI_SETTINGS_PATH, "utf8")) as Record<string, unknown>;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function readExtensionSettings(extensionName: string): Record<string, unknown> | null {
|
|
const settings = readPiSettings();
|
|
if (!settings) {
|
|
return null;
|
|
}
|
|
const config = settings[extensionName] ?? settings[toCamelCase(extensionName)];
|
|
return isPlainObject(config) ? config : null;
|
|
}
|
|
|
|
export function readExtensionBooleanSetting(
|
|
extensionName: string,
|
|
key: string,
|
|
defaultValue: boolean,
|
|
): boolean {
|
|
const config = readExtensionSettings(extensionName);
|
|
if (!config || typeof config[key] !== "boolean") {
|
|
return defaultValue;
|
|
}
|
|
return config[key] as boolean;
|
|
}
|
|
|
|
export function readExtensionEnumSetting<T extends string>(
|
|
extensionName: string,
|
|
key: string,
|
|
allowedValues: readonly T[],
|
|
defaultValue: T,
|
|
): T {
|
|
const config = readExtensionSettings(extensionName);
|
|
const value = config?.[key];
|
|
if (typeof value !== "string") {
|
|
return defaultValue;
|
|
}
|
|
return (allowedValues as readonly string[]).includes(value) ? (value as T) : defaultValue;
|
|
}
|