Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
00eee3c
refactor: SettingsDialog reactive store + delete obsolete utils
psinha40898 Feb 12, 2026
456d7d0
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 12, 2026
90bd195
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 12, 2026
12808a0
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 15, 2026
6572ac7
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 16, 2026
bbbfe68
fix(cli): use checkExhaustive for default case in switch statement as…
psinha40898 Feb 16, 2026
83f511e
fix,refactor(cli): improve type safety ergonomics for non primitive s…
psinha40898 Feb 16, 2026
0895547
revert unecessary agentconfigdialog changes
psinha40898 Feb 16, 2026
7c11cf5
test(cli): the previous tests had tangled concerned with respect to u…
psinha40898 Feb 16, 2026
9f6a2bc
fix(cli): display default setting for unscoped
psinha40898 Feb 16, 2026
7de73e7
better diffs
psinha40898 Feb 17, 2026
ec9491f
test(cli): scope as the determiner of star.
psinha40898 Feb 18, 2026
1b3a5fa
test(cli): organize display tests for scope based behavior
psinha40898 Feb 18, 2026
ddac20d
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 18, 2026
5e879f0
refactor(cli): Remove es lint ignores in favor of type predicate whic…
psinha40898 Feb 20, 2026
a425e43
refactor(cli): move utils for parsing settings, improve documentation…
psinha40898 Feb 21, 2026
a85ab8b
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 21, 2026
cbf5ac0
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 21, 2026
58e0c76
test(cli): fix a test for the non primitive settings
psinha40898 Feb 21, 2026
a0248c5
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 21, 2026
ca2999a
refactor(cli): revert unecessary diffs.
psinha40898 Feb 21, 2026
8022acd
refactor(cli): rename isInScope to isInSettingsScope
psinha40898 Feb 23, 2026
d83dc8b
fix(cli): parser should not reject on falsy outputs like 0
psinha40898 Feb 23, 2026
885ad17
fix(cli): better message explaining why the prompt is showing
psinha40898 Feb 23, 2026
c68f9d3
fix(cli): import proper helper
psinha40898 Feb 23, 2026
080e5b2
fix(cli): incorrect import
psinha40898 Feb 23, 2026
f67243b
test(cli): Update tests to represent new restart prompt text
psinha40898 Feb 25, 2026
bbbdc87
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Feb 25, 2026
9cbc3c0
fix(cli): remove special case for vim mode setting in settings dialog…
psinha40898 Mar 1, 2026
aed7b76
fix(cli): VimModeContext should use new store pattern
psinha40898 Mar 1, 2026
13cab41
Merge branch 'main' into pyush/refactor/react-settings-dialog
psinha40898 Mar 1, 2026
142a568
Merge branch 'main' into pyush/refactor/react-settings-dialog
jacob314 Mar 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 21 additions & 44 deletions packages/cli/src/ui/components/AgentConfigDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
BaseSettingsDialog,
type SettingsDialogItem,
} from './shared/BaseSettingsDialog.js';
import { getNestedValue, isRecord } from '../../utils/settingsUtils.js';

/**
* Configuration field definition for agent settings
Expand Down Expand Up @@ -111,45 +112,30 @@ interface AgentConfigDialogProps {
onSave?: () => void;
}

/**
* Get a nested value from an object using a path array
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here can be reverted to reduce the scope of the PR.

*/
function getNestedValue(
obj: Record<string, unknown> | undefined,
path: string[],
): unknown {
if (!obj) return undefined;
let current: unknown = obj;
for (const key of path) {
if (current === null || current === undefined) return undefined;
if (typeof current !== 'object') return undefined;
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
current = (current as Record<string, unknown>)[key];
}
return current;
}

/**
* Set a nested value in an object using a path array, creating intermediate objects as needed
*/
function setNestedValue(
obj: Record<string, unknown>,
path: string[],
value: unknown,
): Record<string, unknown> {
function setNestedValue(obj: unknown, path: string[], value: unknown): unknown {
if (!isRecord(obj)) return obj;

const result = { ...obj };
let current = result;

for (let i = 0; i < path.length - 1; i++) {
const key = path[i];
if (current[key] === undefined || current[key] === null) {
current[key] = {};
} else if (isRecord(current[key])) {
current[key] = { ...current[key] };
}

const next = current[key];
if (isRecord(next)) {
current = next;
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
current[key] = { ...(current[key] as Record<string, unknown>) };
// Cannot traverse further through non-objects
return result;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
current = current[key] as Record<string, unknown>;
}

const finalKey = path[path.length - 1];
Expand Down Expand Up @@ -267,11 +253,7 @@ export function AgentConfigDialog({
const items: SettingsDialogItem[] = useMemo(
() =>
AGENT_CONFIG_FIELDS.map((field) => {
const currentValue = getNestedValue(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
pendingOverride as Record<string, unknown>,
field.path,
);
const currentValue = getNestedValue(pendingOverride, field.path);
const defaultValue = getFieldDefaultFromDefinition(field, definition);
const effectiveValue =
currentValue !== undefined ? currentValue : defaultValue;
Expand Down Expand Up @@ -324,23 +306,18 @@ export function AgentConfigDialog({
const field = AGENT_CONFIG_FIELDS.find((f) => f.key === key);
if (!field || field.type !== 'boolean') return;

const currentValue = getNestedValue(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
pendingOverride as Record<string, unknown>,
field.path,
);
const currentValue = getNestedValue(pendingOverride, field.path);
const defaultValue = getFieldDefaultFromDefinition(field, definition);
const effectiveValue =
currentValue !== undefined ? currentValue : defaultValue;
const newValue = !effectiveValue;

// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const newOverride = setNestedValue(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
pendingOverride as Record<string, unknown>,
pendingOverride,
field.path,
newValue,
) as AgentOverride;

setPendingOverride(newOverride);
setModifiedFields((prev) => new Set(prev).add(key));

Expand Down Expand Up @@ -375,9 +352,9 @@ export function AgentConfigDialog({
}

// Update pending override locally
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const newOverride = setNestedValue(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
pendingOverride as Record<string, unknown>,
pendingOverride,
field.path,
parsed,
) as AgentOverride;
Expand All @@ -398,9 +375,9 @@ export function AgentConfigDialog({
if (!field) return;

// Remove the override (set to undefined)
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const newOverride = setNestedValue(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
pendingOverride as Record<string, unknown>,
pendingOverride,
field.path,
undefined,
) as AgentOverride;
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/ui/components/DialogManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ export const DialogManager = ({
return (
<Box flexDirection="column">
<SettingsDialog
settings={settings}
onSelect={() => uiActions.closeSettingsDialog()}
onRestartRequest={async () => {
await runExitCleanup();
Expand Down
Loading
Loading