| author | |
| committer | |
| log | bf8ffe81a63c82d3de5fbaa9991fd5f30034a452 |
| tree | 480e957d641187acede881dfd390f2eddf3fd276 |
| parent | 464fad9a433c246b4a5b73c8640787c174c2c195 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: maria-rcks <maria@kuuro.net>7 files changed, 80 insertions(+), 2 deletions(-)
apps/server/src/environment/ServerEnvironment.ts+1| ... | @@ -232,6 +232,7 @@ export const make = Effect.gen(function* () { | ... | @@ -232,6 +232,7 @@ export const make = Effect.gen(function* () { |
| 232 | otlpEndpointCheck: true, | 232 | otlpEndpointCheck: true, |
| 233 | projectWorktreeCleanup: true, | 233 | projectWorktreeCleanup: true, |
| 234 | worktreesDirectory: true, | 234 | worktreesDirectory: true, |
| 235 | threadAutoSettlementScope: true, | ||
| 235 | threadRestartContinuation: true, | 236 | threadRestartContinuation: true, |
| 236 | projectSettingsOverrides: true, | 237 | projectSettingsOverrides: true, |
| 237 | projectProviderInstanceOverrides: true, | 238 | projectProviderInstanceOverrides: true, |
apps/server/src/orchestration-v2/ThreadSettlementService.test.ts+32| ... | @@ -251,6 +251,38 @@ describe("threadHasQueuedTurnStart", () => { | ... | @@ -251,6 +251,38 @@ describe("threadHasQueuedTurnStart", () => { |
| 251 | }); | 251 | }); |
| 252 | 252 | ||
| 253 | describe("resolveAutoSettlementAt", () => { | 253 | describe("resolveAutoSettlementAt", () => { |
| 254 | it("keeps threads with a PR from inactivity settlement only when asked", () => { | ||
| 255 | const input = { | ||
| 256 | thread: shell({ | ||
| 257 | latestUserMessageAt: at(-4 * DAY_MS), | ||
| 258 | linkedPullRequest: { | ||
| 259 | projectId: ProjectId.make("project-1"), | ||
| 260 | repository: "owner/repo", | ||
| 261 | number: 1, | ||
| 262 | url: "https://example.test/owner/repo/pull/1", | ||
| 263 | }, | ||
| 264 | }), | ||
| 265 | pullRequest: null, | ||
| 266 | nowMs: NOW_MS, | ||
| 267 | autoSettleAfterDays: 3, | ||
| 268 | autoSettleOnMerge: true, | ||
| 269 | autoSettleKeepPullRequests: true, | ||
| 270 | }; | ||
| 271 | expect(ThreadSettlementService.resolveAutoSettlementAt(input)).toBeNull(); | ||
| 272 | expect( | ||
| 273 | ThreadSettlementService.resolveAutoSettlementAt({ | ||
| 274 | ...input, | ||
| 275 | autoSettleKeepPullRequests: false, | ||
| 276 | }), | ||
| 277 | ).toEqual(at(-4 * DAY_MS)); | ||
| 278 | expect( | ||
| 279 | ThreadSettlementService.resolveAutoSettlementAt({ | ||
| 280 | ...input, | ||
| 281 | pullRequest: { state: "merged", mergedAt: DateTime.formatIso(at(-1)) }, | ||
| 282 | }), | ||
| 283 | ).toEqual(at(-4 * DAY_MS)); | ||
| 284 | }); | ||
| 285 | |||
| 254 | it("uses the latest activity time when the inactivity window elapses", () => { | 286 | it("uses the latest activity time when the inactivity window elapses", () => { |
| 255 | const idle = shell({ | 287 | const idle = shell({ |
| 256 | latestUserMessageAt: at(-4 * DAY_MS), | 288 | latestUserMessageAt: at(-4 * DAY_MS), |
apps/server/src/orchestration-v2/ThreadSettlementService.ts+10-1| ... | @@ -202,6 +202,7 @@ export function resolveAutoSettlementAt(input: { | ... | @@ -202,6 +202,7 @@ export function resolveAutoSettlementAt(input: { |
| 202 | readonly nowMs: number; | 202 | readonly nowMs: number; |
| 203 | readonly autoSettleAfterDays: number | null; | 203 | readonly autoSettleAfterDays: number | null; |
| 204 | readonly autoSettleOnMerge: boolean; | 204 | readonly autoSettleOnMerge: boolean; |
| 205 | readonly autoSettleKeepPullRequests?: boolean; | ||
| 205 | }): DateTime.Utc | null { | 206 | }): DateTime.Utc | null { |
| 206 | const { thread } = input; | 207 | const { thread } = input; |
| 207 | let pullRequest = input.pullRequest; | 208 | let pullRequest = input.pullRequest; |
| ... | @@ -236,6 +237,9 @@ export function resolveAutoSettlementAt(input: { | ... | @@ -236,6 +237,9 @@ export function resolveAutoSettlementAt(input: { |
| 236 | if (pullRequest !== null && pullRequestSettles(thread, pullRequest, input.autoSettleOnMerge)) { | 237 | if (pullRequest !== null && pullRequestSettles(thread, pullRequest, input.autoSettleOnMerge)) { |
| 237 | return activityAtMs === null ? thread.createdAt : DateTime.makeUnsafe(activityAtMs); | 238 | return activityAtMs === null ? thread.createdAt : DateTime.makeUnsafe(activityAtMs); |
| 238 | } | 239 | } |
| 240 | const hasPullRequest = | ||
| 241 | pullRequest !== null || thread.linkedPullRequest != null || thread.branchPullRequest != null; | ||
| 242 | if (input.autoSettleKeepPullRequests === true && hasPullRequest) return null; | ||
| 239 | if (input.autoSettleAfterDays === null || activityAtMs === null) return null; | 243 | if (input.autoSettleAfterDays === null || activityAtMs === null) return null; |
| 240 | // A passed wake timer restarts inactivity. An earlier wake can only delay settlement. | 244 | // A passed wake timer restarts inactivity. An earlier wake can only delay settlement. |
| 241 | const snoozedUntilMs = toMillis(thread.snoozedUntil); | 245 | const snoozedUntilMs = toMillis(thread.snoozedUntil); |
| ... | @@ -275,6 +279,7 @@ export function autoSettlementSettingsKey( | ... | @@ -275,6 +279,7 @@ export function autoSettlementSettingsKey( |
| 275 | return JSON.stringify([ | 279 | return JSON.stringify([ |
| 276 | settings.sidebarAutoSettleOnMerge, | 280 | settings.sidebarAutoSettleOnMerge, |
| 277 | settings.sidebarAutoSettleAfterDays, | 281 | settings.sidebarAutoSettleAfterDays, |
| 282 | settings.sidebarAutoSettleKeepPullRequests, | ||
| 278 | // Only entries that touch settlement, in a stable order, so a project | 283 | // Only entries that touch settlement, in a stable order, so a project |
| 279 | // override on an unrelated key does not queue a sweep. JSON drops | 284 | // override on an unrelated key does not queue a sweep. JSON drops |
| 280 | // undefined, so inherit (absent) and never (null) need distinct marks. | 285 | // undefined, so inherit (absent) and never (null) need distinct marks. |
| ... | @@ -282,7 +287,8 @@ export function autoSettlementSettingsKey( | ... | @@ -282,7 +287,8 @@ export function autoSettlementSettingsKey( |
| 282 | .filter( | 287 | .filter( |
| 283 | ([, entry]) => | 288 | ([, entry]) => |
| 284 | entry.sidebarAutoSettleOnMerge !== undefined || | 289 | entry.sidebarAutoSettleOnMerge !== undefined || |
| 285 | entry.sidebarAutoSettleAfterDays !== undefined, | 290 | entry.sidebarAutoSettleAfterDays !== undefined || |
| 291 | entry.sidebarAutoSettleKeepPullRequests !== undefined, | ||
| 286 | ) | 292 | ) |
| 287 | .sort(([left], [right]) => left.localeCompare(right)) | 293 | .sort(([left], [right]) => left.localeCompare(right)) |
| 288 | .map(([projectId, entry]) => [ | 294 | .map(([projectId, entry]) => [ |
| ... | @@ -291,6 +297,7 @@ export function autoSettlementSettingsKey( | ... | @@ -291,6 +297,7 @@ export function autoSettlementSettingsKey( |
| 291 | entry.sidebarAutoSettleAfterDays === undefined | 297 | entry.sidebarAutoSettleAfterDays === undefined |
| 292 | ? "inherit" | 298 | ? "inherit" |
| 293 | : entry.sidebarAutoSettleAfterDays, | 299 | : entry.sidebarAutoSettleAfterDays, |
| 300 | entry.sidebarAutoSettleKeepPullRequests ?? "inherit", | ||
| 294 | ]), | 301 | ]), |
| 295 | ]); | 302 | ]); |
| 296 | } | 303 | } |
| ... | @@ -343,6 +350,7 @@ export const make = Effect.gen(function* () { | ... | @@ -343,6 +350,7 @@ export const make = Effect.gen(function* () { |
| 343 | nowMs: DateTime.toEpochMillis(decisionNow), | 350 | nowMs: DateTime.toEpochMillis(decisionNow), |
| 344 | autoSettleAfterDays: currentSettings.sidebarAutoSettleAfterDays, | 351 | autoSettleAfterDays: currentSettings.sidebarAutoSettleAfterDays, |
| 345 | autoSettleOnMerge: currentSettings.sidebarAutoSettleOnMerge, | 352 | autoSettleOnMerge: currentSettings.sidebarAutoSettleOnMerge, |
| 353 | autoSettleKeepPullRequests: currentSettings.sidebarAutoSettleKeepPullRequests, | ||
| 346 | }); | 354 | }); |
| 347 | if (settledAt === null) return thread; | 355 | if (settledAt === null) return thread; |
| 348 | const uuid = yield* crypto.randomUUIDv4(); | 356 | const uuid = yield* crypto.randomUUIDv4(); |
| ... | @@ -445,6 +453,7 @@ export const make = Effect.gen(function* () { | ... | @@ -445,6 +453,7 @@ export const make = Effect.gen(function* () { |
| 445 | nowMs: DateTime.toEpochMillis(decisionNow), | 453 | nowMs: DateTime.toEpochMillis(decisionNow), |
| 446 | autoSettleAfterDays: settings.sidebarAutoSettleAfterDays, | 454 | autoSettleAfterDays: settings.sidebarAutoSettleAfterDays, |
| 447 | autoSettleOnMerge: settings.sidebarAutoSettleOnMerge, | 455 | autoSettleOnMerge: settings.sidebarAutoSettleOnMerge, |
| 456 | autoSettleKeepPullRequests: settings.sidebarAutoSettleKeepPullRequests, | ||
| 448 | }) !== null | 457 | }) !== null |
| 449 | ); | 458 | ); |
| 450 | }); | 459 | }); |
apps/web/src/components/settings/SettingsPanels.tsx+27| ... | @@ -582,6 +582,10 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -582,6 +582,10 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 582 | DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays | 582 | DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays |
| 583 | ? ["Auto-settle inactive threads"] | 583 | ? ["Auto-settle inactive threads"] |
| 584 | : []), | 584 | : []), |
| 585 | ...(settings.sidebarAutoSettleKeepPullRequests !== | ||
| 586 | DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleKeepPullRequests | ||
| 587 | ? ["Keep threads with a PR"] | ||
| 588 | : []), | ||
| 585 | ...(settings.sidebarAutoSettleOnMerge !== DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleOnMerge | 589 | ...(settings.sidebarAutoSettleOnMerge !== DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleOnMerge |
| 586 | ? ["Auto-settle merged threads"] | 590 | ? ["Auto-settle merged threads"] |
| 587 | : []), | 591 | : []), |
| ... | @@ -708,6 +712,7 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -708,6 +712,7 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 708 | settings.enableProviderUpdateChecks, | 712 | settings.enableProviderUpdateChecks, |
| 709 | settings.continueThreadsAfterServerUpdate, | 713 | settings.continueThreadsAfterServerUpdate, |
| 710 | settings.sidebarAutoSettleAfterDays, | 714 | settings.sidebarAutoSettleAfterDays, |
| 715 | settings.sidebarAutoSettleKeepPullRequests, | ||
| 711 | settings.sidebarAutoSettleOnMerge, | 716 | settings.sidebarAutoSettleOnMerge, |
| 712 | settings.autoResumeLimitedThreads, | 717 | settings.autoResumeLimitedThreads, |
| 713 | settings.snoozeLimitedThreads, | 718 | settings.snoozeLimitedThreads, |
| ... | @@ -815,6 +820,7 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -815,6 +820,7 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 815 | sidebarProjectSortOrder: DEFAULT_UNIFIED_SETTINGS.sidebarProjectSortOrder, | 820 | sidebarProjectSortOrder: DEFAULT_UNIFIED_SETTINGS.sidebarProjectSortOrder, |
| 816 | sidebarWorkingShelfEnabled: DEFAULT_UNIFIED_SETTINGS.sidebarWorkingShelfEnabled, | 821 | sidebarWorkingShelfEnabled: DEFAULT_UNIFIED_SETTINGS.sidebarWorkingShelfEnabled, |
| 817 | sidebarAutoSettleAfterDays: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays, | 822 | sidebarAutoSettleAfterDays: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays, |
| 823 | sidebarAutoSettleKeepPullRequests: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleKeepPullRequests, | ||
| 818 | sidebarAutoSettleOnMerge: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleOnMerge, | 824 | sidebarAutoSettleOnMerge: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleOnMerge, |
| 819 | autoResumeLimitedThreads: DEFAULT_UNIFIED_SETTINGS.autoResumeLimitedThreads, | 825 | autoResumeLimitedThreads: DEFAULT_UNIFIED_SETTINGS.autoResumeLimitedThreads, |
| 820 | snoozeLimitedThreads: DEFAULT_UNIFIED_SETTINGS.snoozeLimitedThreads, | 826 | snoozeLimitedThreads: DEFAULT_UNIFIED_SETTINGS.snoozeLimitedThreads, |
| ... | @@ -2203,6 +2209,9 @@ export function GeneralSettingsPanel() { | ... | @@ -2203,6 +2209,9 @@ export function GeneralSettingsPanel() { |
| 2203 | connectedEnvironments.every( | 2209 | connectedEnvironments.every( |
| 2204 | (target) => target.serverConfig?.environment.capabilities.threadAutoSettlement === true, | 2210 | (target) => target.serverConfig?.environment.capabilities.threadAutoSettlement === true, |
| 2205 | ); | 2211 | ); |
| 2212 | const supportsAutoSettlementScope = connectedEnvironments.every( | ||
| 2213 | (target) => target.serverConfig?.environment.capabilities.threadAutoSettlementScope === true, | ||
| 2214 | ); | ||
| 2206 | const supportsRestartContinuation = | 2215 | const supportsRestartContinuation = |
| 2207 | connectedEnvironments.length > 0 && | 2216 | connectedEnvironments.length > 0 && |
| 2208 | connectedEnvironments.every( | 2217 | connectedEnvironments.every( |
| ... | @@ -2483,6 +2492,24 @@ export function GeneralSettingsPanel() { | ... | @@ -2483,6 +2492,24 @@ export function GeneralSettingsPanel() { |
| 2483 | } | 2492 | } |
| 2484 | /> | 2493 | /> |
| 2485 | ) : null} | 2494 | ) : null} |
| 2495 | {settings.sidebarAutoSettleAfterDays !== null && supportsAutoSettlementScope ? ( | ||
| 2496 | <SettingsRow | ||
| 2497 | serverScoped | ||
| 2498 | settingKeys={["sidebarAutoSettleKeepPullRequests"]} | ||
| 2499 | title="Keep threads with a PR" | ||
| 2500 | description="Inactivity does not settle threads with a pull request. Merge and close still do." | ||
| 2501 | control={ | ||
| 2502 | <ScopedSwitch | ||
| 2503 | settingKeys={["sidebarAutoSettleKeepPullRequests"]} | ||
| 2504 | checked={settings.sidebarAutoSettleKeepPullRequests} | ||
| 2505 | onCheckedChange={(checked) => | ||
| 2506 | updateSettings({ sidebarAutoSettleKeepPullRequests: checked }) | ||
| 2507 | } | ||
| 2508 | aria-label="Keep threads with a PR" | ||
| 2509 | /> | ||
| 2510 | } | ||
| 2511 | /> | ||
| 2512 | ) : null} | ||
| 2486 | </> | 2513 | </> |
| 2487 | ) : null} | 2514 | ) : null} |
| 2488 | </SettingsSection> | 2515 | </SettingsSection> |
docs/user/thread-sidebar.md+2-1| ... | @@ -150,7 +150,8 @@ By default, environments settle inactive threads after three days and settle | ... | @@ -150,7 +150,8 @@ By default, environments settle inactive threads after three days and settle |
| 150 | threads whose pull request merged. A closed pull request can also settle an idle | 150 | threads whose pull request merged. A closed pull request can also settle an idle |
| 151 | thread. Work in progress, pending questions or approvals, and live background work | 151 | thread. Work in progress, pending questions or approvals, and live background work |
| 152 | prevent automatic settlement. An open pull request does not prevent inactivity | 152 | prevent automatic settlement. An open pull request does not prevent inactivity |
| 153 | settlement, but an old closed or merged pull request does not settle work you | 153 | settlement unless you turn on **Keep threads with a PR** in **Settings → General**, |
| 154 | but an old closed or merged pull request does not settle work you | ||
| 154 | resumed after it closed. Only your own messages count as resuming. A turn that | 155 | resumed after it closed. Only your own messages count as resuming. A turn that |
| 155 | finished background work or a pull request watch starts on its own does not. | 156 | finished background work or a pull request watch starts on its own does not. |
| 156 | 157 |
packages/contracts/src/environment.ts+2| ... | @@ -131,6 +131,8 @@ export const ExecutionEnvironmentCapabilities = Schema.Struct({ | ... | @@ -131,6 +131,8 @@ export const ExecutionEnvironmentCapabilities = Schema.Struct({ |
| 131 | projectWorktreeCleanup: Schema.optionalKey(Schema.Boolean), | 131 | projectWorktreeCleanup: Schema.optionalKey(Schema.Boolean), |
| 132 | /** Server honors the `worktreesDirectory` setting. */ | 132 | /** Server honors the `worktreesDirectory` setting. */ |
| 133 | worktreesDirectory: Schema.optionalKey(Schema.Boolean), | 133 | worktreesDirectory: Schema.optionalKey(Schema.Boolean), |
| 134 | /** Server can exclude PR-linked threads from inactivity settlement. */ | ||
| 135 | threadAutoSettlementScope: Schema.optionalKey(Schema.Boolean), | ||
| 134 | /** Server persists the opt-in for continuing interrupted threads after restarts. */ | 136 | /** Server persists the opt-in for continuing interrupted threads after restarts. */ |
| 135 | threadRestartContinuation: Schema.optionalKey(Schema.Boolean), | 137 | threadRestartContinuation: Schema.optionalKey(Schema.Boolean), |
| 136 | /** Server resolves `projectSettingsOverrides`; older servers ignore the key. */ | 138 | /** Server resolves `projectSettingsOverrides`; older servers ignore the key. */ |
packages/contracts/src/settings.ts+6| ... | @@ -984,6 +984,7 @@ export const PROJECT_SCOPED_SERVER_SETTING_KEYS = [ | ... | @@ -984,6 +984,7 @@ export const PROJECT_SCOPED_SERVER_SETTING_KEYS = [ |
| 984 | "pullRequestMergeMethod", | 984 | "pullRequestMergeMethod", |
| 985 | "sidebarAutoSettleOnMerge", | 985 | "sidebarAutoSettleOnMerge", |
| 986 | "sidebarAutoSettleAfterDays", | 986 | "sidebarAutoSettleAfterDays", |
| 987 | "sidebarAutoSettleKeepPullRequests", | ||
| 987 | "continueThreadsAfterServerUpdate", | 988 | "continueThreadsAfterServerUpdate", |
| 988 | "responseStreamingMode", | 989 | "responseStreamingMode", |
| 989 | ] as const; | 990 | ] as const; |
| ... | @@ -1031,6 +1032,7 @@ export const ProjectSettingsOverrides = Schema.Struct({ | ... | @@ -1031,6 +1032,7 @@ export const ProjectSettingsOverrides = Schema.Struct({ |
| 1031 | pullRequestMergeMethod: Schema.optionalKey(Schema.NullOr(PullRequestMergeMethod)), | 1032 | pullRequestMergeMethod: Schema.optionalKey(Schema.NullOr(PullRequestMergeMethod)), |
| 1032 | sidebarAutoSettleOnMerge: Schema.optionalKey(Schema.Boolean), | 1033 | sidebarAutoSettleOnMerge: Schema.optionalKey(Schema.Boolean), |
| 1033 | sidebarAutoSettleAfterDays: Schema.optionalKey(Schema.NullOr(SidebarAutoSettleAfterDays)), | 1034 | sidebarAutoSettleAfterDays: Schema.optionalKey(Schema.NullOr(SidebarAutoSettleAfterDays)), |
| 1035 | sidebarAutoSettleKeepPullRequests: Schema.optionalKey(Schema.Boolean), | ||
| 1034 | continueThreadsAfterServerUpdate: Schema.optionalKey(Schema.Boolean), | 1036 | continueThreadsAfterServerUpdate: Schema.optionalKey(Schema.Boolean), |
| 1035 | responseStreamingMode: Schema.optionalKey(ResponseStreamingMode), | 1037 | responseStreamingMode: Schema.optionalKey(ResponseStreamingMode), |
| 1036 | providerInstances: Schema.optionalKey( | 1038 | providerInstances: Schema.optionalKey( |
| ... | @@ -1198,6 +1200,9 @@ export const ServerSettings = Schema.Struct({ | ... | @@ -1198,6 +1200,9 @@ export const ServerSettings = Schema.Struct({ |
| 1198 | ), | 1200 | ), |
| 1199 | snoozeLimitedThreads: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), | 1201 | snoozeLimitedThreads: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 1200 | autoResumeLimitedThreads: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), | 1202 | autoResumeLimitedThreads: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), |
| 1203 | sidebarAutoSettleKeepPullRequests: Schema.Boolean.pipe( | ||
| 1204 | Schema.withDecodingDefault(Effect.succeed(false)), | ||
| 1205 | ), | ||
| 1201 | sidebarAutoSettleOnMerge: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), | 1206 | sidebarAutoSettleOnMerge: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), |
| 1202 | backgroundActivity: BackgroundActivitySettings, | 1207 | backgroundActivity: BackgroundActivitySettings, |
| 1203 | // Legacy flat fields retained for old settings files and old clients. New | 1208 | // Legacy flat fields retained for old settings files and old clients. New |
| ... | @@ -1572,6 +1577,7 @@ export const ServerSettingsPatch = Schema.Struct({ | ... | @@ -1572,6 +1577,7 @@ export const ServerSettingsPatch = Schema.Struct({ |
| 1572 | deviceOnboardingCompleted: Schema.optionalKey(Schema.Boolean), | 1577 | deviceOnboardingCompleted: Schema.optionalKey(Schema.Boolean), |
| 1573 | deviceHosts: Schema.optionalKey(SshDeviceHostConfigs), | 1578 | deviceHosts: Schema.optionalKey(SshDeviceHostConfigs), |
| 1574 | sidebarAutoSettleAfterDays: Schema.optionalKey(Schema.NullOr(SidebarAutoSettleAfterDays)), | 1579 | sidebarAutoSettleAfterDays: Schema.optionalKey(Schema.NullOr(SidebarAutoSettleAfterDays)), |
| 1580 | sidebarAutoSettleKeepPullRequests: Schema.optionalKey(Schema.Boolean), | ||
| 1575 | sidebarAutoSettleOnMerge: Schema.optionalKey(Schema.Boolean), | 1581 | sidebarAutoSettleOnMerge: Schema.optionalKey(Schema.Boolean), |
| 1576 | autoResumeLimitedThreads: Schema.optionalKey(Schema.Boolean), | 1582 | autoResumeLimitedThreads: Schema.optionalKey(Schema.Boolean), |
| 1577 | snoozeLimitedThreads: Schema.optionalKey(Schema.Boolean), | 1583 | snoozeLimitedThreads: Schema.optionalKey(Schema.Boolean), |