feat(FN-1724): merge fusion/fn-1724

This commit is contained in:
gsxdsm
2026-04-14 10:14:47 -07:00
parent 0dffdec04c
commit 54befbe021
3 changed files with 33 additions and 9 deletions

View File

@@ -1214,18 +1214,15 @@ describe("TaskStore", () => {
expect(settings.experimentalFeatures).toEqual({ "feature-b": true });
});
it("can remove an experimental feature by setting it to undefined (field stays)", async () => {
// Note: We cannot selectively remove a single key from experimentalFeatures
// since it's a simple Record<string, boolean> not a nested object with special handling.
// Users should replace the entire object if they need to remove specific keys.
it("can remove an experimental feature by setting it to null (selective removal)", async () => {
// Features can be selectively removed by setting them to null
await store.updateSettings({
experimentalFeatures: { "feature-a": true, "feature-b": true },
});
// Replace with only feature-b
// Remove feature-a by setting it to null (cast needed for TypeScript type safety)
await store.updateSettings({
experimentalFeatures: { "feature-b": true },
experimentalFeatures: { "feature-a": null } as unknown as Record<string, boolean>,
});
const settings = await store.getSettings();

View File

@@ -793,6 +793,32 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
}
}
// Handle experimentalFeatures merging (similar to promptOverrides)
const incomingExperimentalFeatures = (projectPatch as Record<string, unknown>)["experimentalFeatures"];
if (
incomingExperimentalFeatures !== undefined &&
typeof incomingExperimentalFeatures === "object" &&
incomingExperimentalFeatures !== null &&
!Array.isArray(incomingExperimentalFeatures)
) {
// experimentalFeatures: { key: value } → merge with existing
const incomingMap = incomingExperimentalFeatures as Record<string, unknown>;
const existingMap = ((config.settings as unknown as Record<string, unknown>)["experimentalFeatures"] as Record<string, boolean>) ?? {};
const mergedMap: Record<string, boolean> = { ...existingMap };
for (const [key, value] of Object.entries(incomingMap)) {
// null values remove the feature
if (value === null) {
delete mergedMap[key];
} else if (typeof value === "boolean") {
mergedMap[key] = value;
}
}
(config.settings as unknown as Record<string, unknown>)["experimentalFeatures"] = mergedMap;
(projectPatch as Record<string, unknown>)["experimentalFeatures"] = mergedMap;
}
const globalSettings = await this.globalSettingsStore.getSettings();
const previousMerged: Settings = { ...DEFAULT_SETTINGS, ...globalSettings, ...config.settings } as Settings;
const updatedProjectSettings = { ...config.settings, ...projectPatch };