feat(config): implement dynamic experiment resolution and unified overrides

This commit is contained in:
mkorwel
2026-02-19 16:37:43 -06:00
committed by Matt Korwel
parent 2e1b556764
commit d61eed2880
5 changed files with 253 additions and 17 deletions
+29 -2
View File
@@ -106,6 +106,7 @@ export interface CliArgs {
rawOutput: boolean | undefined;
acceptRawOutputRisk: boolean | undefined;
isCommand: boolean | undefined;
[key: string]: unknown;
}
/**
@@ -443,13 +444,22 @@ export async function parseArguments(
.option('accept-raw-output-risk', {
type: 'boolean',
description: 'Suppress the security warning when using --raw-output.',
})
.option('experiment', {
type: 'array',
string: true,
nargs: 1,
description:
'Override experiment flags locally (format: flag=value, comma-separated or multiple --experiment)',
coerce: (exps: string[]) =>
// Handle comma-separated values
exps.flatMap((e) => e.split(',').map((s) => s.trim())),
}),
)
.version(await getVersion()) // This will enable the --version flag based on package.json
.alias('v', 'version')
.help()
.alias('h', 'help')
.strict()
.demandCommand(0, 0) // Allow base command to run with no subcommands
.exitProcess(false);
@@ -873,6 +883,22 @@ export async function loadCliConfig(
}
}
const experimentalCliArgs: Record<string, unknown> = {};
if (argv['experiment'] && Array.isArray(argv['experiment'])) {
for (const entry of argv['experiment']) {
const [key, ...valueParts] = entry.split('=');
const value = valueParts.join('=');
if (key && value !== undefined) {
// Simple type inference for CLI args
if (value === 'true') experimentalCliArgs[key] = true;
else if (value === 'false') experimentalCliArgs[key] = false;
else if (!isNaN(Number(value)))
experimentalCliArgs[key] = Number(value);
else experimentalCliArgs[key] = value;
}
}
}
let clientName: string | undefined = undefined;
if (isAcpMode) {
const ide = detectIdeFromEnv();
@@ -893,7 +919,6 @@ export async function loadCliConfig(
...(useContextManagement ? settings?.contextManagement : {}),
enabled: useContextManagement || useGeneralistProfile,
};
return new Config({
acpMode: isAcpMode,
clientName,
@@ -985,6 +1010,8 @@ export async function loadCliConfig(
planSettings: settings.general?.plan?.directory
? settings.general.plan
: (extensionPlanSettings ?? settings.general?.plan),
experimentalSettings: settings.experimental,
experimentalCliArgs,
enableEventDrivenScheduler: true,
skillsSupport: settings.skills?.enabled ?? true,
disabledSkills: settings.skills?.disabled,