Disable experimental new worktree card style by default (#7977)

This commit is contained in:
Jinjing 2026-07-09 14:52:03 -07:00 committed by GitHub
parent 33f59ad99e
commit ad43dd19ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 54 deletions

View File

@ -92,32 +92,32 @@ describe('agent hooks CLI handler', () => {
rmSync(userDataPath, { recursive: true, force: true })
})
it('keeps the fresh-profile new card style default when creating offline settings', async () => {
it('keeps new card style off when creating offline settings for a fresh profile', async () => {
await runAgentHooksOff(userDataPath)
const persisted = readDataFile(userDataPath)
expect(persisted.settings.experimentalNewWorktreeCardStyle).toBe(true)
expect(persisted.settings.experimentalNewWorktreeCardStyle).toBe(false)
expect(persisted.settings.agentStatusHooksEnabled).toBe(false)
})
it('defaults missing new card style on while offline-updated onboarding is open', async () => {
it('keeps missing new card style off when updating offline settings', async () => {
const existing = getDefaultPersistedState(userDataPath)
delete existing.settings.experimentalNewWorktreeCardStyle
writeDataFile(userDataPath, existing)
await runAgentHooksOff(userDataPath)
expect(readDataFile(userDataPath).settings.experimentalNewWorktreeCardStyle).toBe(true)
expect(readDataFile(userDataPath).settings.experimentalNewWorktreeCardStyle).toBe(false)
})
it('preserves an existing explicit new card style opt-out when updating offline settings', async () => {
it('preserves an existing explicit new card style opt-in when updating offline settings', async () => {
const existing = getDefaultPersistedState(userDataPath)
existing.settings.experimentalNewWorktreeCardStyle = false
existing.settings.experimentalNewWorktreeCardStyle = true
writeDataFile(userDataPath, existing)
await runAgentHooksOff(userDataPath)
expect(readDataFile(userDataPath).settings.experimentalNewWorktreeCardStyle).toBe(false)
expect(readDataFile(userDataPath).settings.experimentalNewWorktreeCardStyle).toBe(true)
})
})

View File

@ -31,16 +31,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
function readPersistedState(dataPath: string): PersistedState {
if (!existsSync(dataPath)) {
const defaults = getDefaultPersistedState(homedir())
return {
...defaults,
settings: {
...defaults.settings,
// Why: offline CLI can create the first profile before desktop load;
// match the Store fresh-install default instead of pinning old cards.
experimentalNewWorktreeCardStyle: true
}
}
return getDefaultPersistedState(homedir())
}
try {
const parsed = JSON.parse(readFileSync(dataPath, 'utf-8'))
@ -83,14 +74,9 @@ function readEnabledFromDisk(): boolean {
function updateEnabledOnDisk(enabled: boolean): string {
const dataPath = getDataPath()
const state = readPersistedState(dataPath)
const experimentalNewWorktreeCardStyle =
state.settings?.experimentalNewWorktreeCardStyle ?? state.onboarding?.closedAt === null
state.settings = {
...getDefaultPersistedState(homedir()).settings,
...state.settings,
// Why: offline CLI can run before Store.load(); mirror its open-onboarding
// default without overriding a saved user opt-out.
experimentalNewWorktreeCardStyle,
agentStatusHooksEnabled: enabled
}
writePersistedState(dataPath, state)

View File

@ -527,7 +527,7 @@ describe('Store', () => {
expect(settings.experimentalActivity).toBe(false)
expect(settings.experimentalActivityDefaultedOffForAllUsers).toBe(true)
expect(settings.experimentalTerminalAttention).toBe(false)
expect(settings.experimentalNewWorktreeCardStyle).toBe(true)
expect(settings.experimentalNewWorktreeCardStyle).toBe(false)
expect(settings.floatingTerminalEnabled).toBe(true)
expect(settings.floatingTerminalDefaultedForAllUsers).toBe(true)
expect(settings.notifications.customSoundPath).toBeNull()
@ -658,7 +658,7 @@ describe('Store', () => {
expect(store.getUI().setupGuideSidebarDismissed).toBe(false)
})
it('defaults new worktree card style on while onboarding is open', async () => {
it('keeps new worktree card style off while onboarding is open', async () => {
writeDataFile({
settings: {},
onboarding: {
@ -673,7 +673,7 @@ describe('Store', () => {
const store = await createStore()
expect(store.getSettings().experimentalNewWorktreeCardStyle).toBe(true)
expect(store.getSettings().experimentalNewWorktreeCardStyle).toBe(false)
})
it('preserves explicit new worktree card style opt-out while onboarding is open', async () => {
@ -696,6 +696,20 @@ describe('Store', () => {
expect(store.getSettings().experimentalNewWorktreeCardStyle).toBe(false)
})
it('preserves explicit new worktree card style opt-in on load', async () => {
writeDataFile({
schemaVersion: 1,
settings: {
experimentalNewWorktreeCardStyle: true
},
ui: {}
})
const store = await createStore()
expect(store.getSettings().experimentalNewWorktreeCardStyle).toBe(true)
})
it('keeps new worktree card style off for existing users backfilled as completed', async () => {
writeDataFile({
schemaVersion: 1,

View File

@ -1350,10 +1350,6 @@ function resolveSetupGuideSidebarDismissedOnLoad(
return onboarding.closedAt !== null || persistedDismissed === true
}
function shouldDefaultNewWorktreeCardStyleOn(onboarding: OnboardingState): boolean {
return onboarding.closedAt === null
}
// Why: read a settings field that was removed from GlobalSettings but can
// still exist on disk. One-shot use for the inline-agents migration.
function readDeprecatedExperimentFlag(parsed: PersistedState | undefined): boolean {
@ -3067,16 +3063,6 @@ export class Store {
if (!parsed.onboarding) {
this.loadNeedsSave = true
}
const defaultNewWorktreeCardStyle =
shouldDefaultNewWorktreeCardStyleOn(normalizedOnboarding)
const migratedExperimentalNewWorktreeCardStyle =
parsed.settings?.experimentalNewWorktreeCardStyle ?? defaultNewWorktreeCardStyle
if (
parsed.settings?.experimentalNewWorktreeCardStyle === undefined &&
defaultNewWorktreeCardStyle
) {
this.loadNeedsSave = true
}
const normalizedProjectGroups = normalizeProjectGroups(parsed.projectGroups)
const loadedCompactWorktreeCards =
parsed.settings?.compactWorktreeCards ??
@ -3130,9 +3116,6 @@ export class Store {
...migratedTerminalTuiScrollSensitivity.settings,
experimentalActivity: migratedExperimentalActivity,
experimentalActivityDefaultedOffForAllUsers: true,
// Why: open first-run onboarding is the local fresh-install signal;
// closed/backfilled onboarding identifies existing profiles.
experimentalNewWorktreeCardStyle: migratedExperimentalNewWorktreeCardStyle,
// Why: compact worktree cards graduated from Experimental; preserve
// the old opt-in for profiles written during the rollout.
compactWorktreeCards: loadedCompactWorktreeCards,
@ -3417,18 +3400,7 @@ export class Store {
}
if (result === null) {
const defaults = getDefaultPersistedState(homedir())
const isFreshDefaultProfile =
!fileExistedOnLoad && shouldDefaultNewWorktreeCardStyleOn(defaults.onboarding)
result = {
...defaults,
settings: {
...defaults.settings,
// Why: a corrupt existing data file also falls back to defaults; only
// the absent-file path is a true fresh install.
experimentalNewWorktreeCardStyle: isFreshDefaultProfile
}
}
result = getDefaultPersistedState(homedir())
}
const workspaceSession = pruneWorkspaceSessionBrowserHistory(