Phase 2: add settings read — merge global and project via SettingsManager.
Parses skillReinject from Pi settings layers with defaults and project-trust aware loading so extension code shares one merged settings view. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,19 @@
|
||||
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
||||
import { SettingsManager, getAgentDir } from "@earendil-works/pi-coding-agent";
|
||||
import type { AutoCompactIntegration } from "./state";
|
||||
|
||||
/** JSON key in global/project settings.json (SPEC §7.3). */
|
||||
export const SKILL_REINJECT_SETTINGS_KEY = "skillReinject";
|
||||
|
||||
export type PartialSkillReinjectSettings = Partial<SkillReinjectSettings>;
|
||||
|
||||
const AUTO_COMPACT_INTEGRATION_VALUES: readonly AutoCompactIntegration[] = [
|
||||
"auto",
|
||||
"defer",
|
||||
"immediate",
|
||||
"off",
|
||||
];
|
||||
|
||||
/** Global/project skillReinject.* settings (SPEC §7.3). */
|
||||
export interface SkillReinjectSettings {
|
||||
enabled: boolean;
|
||||
@@ -23,3 +37,67 @@ export const DEFAULT_SKILL_REINJECT_SETTINGS: Readonly<SkillReinjectSettings> =
|
||||
export function createDefaultSettings(): SkillReinjectSettings {
|
||||
return { ...DEFAULT_SKILL_REINJECT_SETTINGS };
|
||||
}
|
||||
|
||||
function isAutoCompactIntegration(value: unknown): value is AutoCompactIntegration {
|
||||
return (
|
||||
typeof value === "string" &&
|
||||
(AUTO_COMPACT_INTEGRATION_VALUES as readonly string[]).includes(value)
|
||||
);
|
||||
}
|
||||
|
||||
/** Parse unknown JSON; invalid fields are ignored. */
|
||||
export function parseSkillReinjectPartial(raw: unknown): PartialSkillReinjectSettings {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
return {};
|
||||
}
|
||||
const obj = raw as Record<string, unknown>;
|
||||
const result: PartialSkillReinjectSettings = {};
|
||||
if (typeof obj.enabled === "boolean") {
|
||||
result.enabled = obj.enabled;
|
||||
}
|
||||
if (typeof obj.trackReadPaths === "boolean") {
|
||||
result.trackReadPaths = obj.trackReadPaths;
|
||||
}
|
||||
if (typeof obj.triggerTurn === "boolean") {
|
||||
result.triggerTurn = obj.triggerTurn;
|
||||
}
|
||||
if (typeof obj.reinjectOnManualCompaction === "boolean") {
|
||||
result.reinjectOnManualCompaction = obj.reinjectOnManualCompaction;
|
||||
}
|
||||
if (isAutoCompactIntegration(obj.autoCompactIntegration)) {
|
||||
result.autoCompactIntegration = obj.autoCompactIntegration;
|
||||
}
|
||||
if (typeof obj.suffix === "string") {
|
||||
result.suffix = obj.suffix;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Project overrides global; both layers merge onto defaults (SPEC §7.3). */
|
||||
export function mergeSkillReinjectSettings(
|
||||
global: PartialSkillReinjectSettings,
|
||||
project: PartialSkillReinjectSettings,
|
||||
): SkillReinjectSettings {
|
||||
return {
|
||||
...createDefaultSettings(),
|
||||
...global,
|
||||
...project,
|
||||
};
|
||||
}
|
||||
|
||||
function extractSkillReinject(settings: object): PartialSkillReinjectSettings {
|
||||
return parseSkillReinjectPartial(
|
||||
(settings as Record<string, unknown>)[SKILL_REINJECT_SETTINGS_KEY],
|
||||
);
|
||||
}
|
||||
|
||||
/** Merged global + project settings via Pi SettingsManager (SPEC §7.3). */
|
||||
export function readSettings(ctx: ExtensionContext): SkillReinjectSettings {
|
||||
const manager = SettingsManager.create(ctx.cwd, getAgentDir(), {
|
||||
projectTrusted: ctx.isProjectTrusted(),
|
||||
});
|
||||
return mergeSkillReinjectSettings(
|
||||
extractSkillReinject(manager.getGlobalSettings()),
|
||||
extractSkillReinject(manager.getProjectSettings()),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user