feat(settings): add new task defaults for steps, skip-permissions, and propagate#165
Conversation
|
Thank you very much! <3 Review summaryNice clean store-layer plumbing and thorough save/load tests. Two blockers before merge, plus some nits. 🛑 Blocker 1 — Autosave never fires for these togglesThe new setters in The Fix: add three lines to defaultStepsEnabled: store.defaultStepsEnabled,
defaultSkipPermissions: store.defaultSkipPermissions,
defaultPropagateSkipPermissions: store.defaultPropagateSkipPermissions,Worth adding an autosave-level regression test too — this same footgun would catch any future persisted-field PR. 🛑 Blocker 2 — Breaks documented sticky-default behavior for existing users
Pick one:
Either way, add the OpenSpec change. Nits (non-blocking)
Inline-style duplication and missing |
d5063dc to
650817b
Compare
|
Thanks for the thorough review — all issues addressed in the latest push. Here's what was fixed, in the same order as your comments: 🛑 Blocker 1 — Autosave never firesRoot cause confirmed: Fix: Added all three fields to defaultStepsEnabled: store.defaultStepsEnabled,
defaultSkipPermissions: store.defaultSkipPermissions,
defaultPropagateSkipPermissions: store.defaultPropagateSkipPermissions,Regression test: Added 🛑 Blocker 2 — Breaks existing users'
|
Review summary — needs changes 🔴Thanks for this! The store/persistence/UI wiring is clean, consistent, and well-covered at the persistence layer. However, the feature doesn't actually work for 2 of its 3 settings, because the New Task dialog never consumes the values it persists. Details below, ordered by priority. 🔴 Critical —
|
…d propagate Adds three persistent app-level defaults that pre-fill checkboxes in the New Task dialog, plus all fixes from PR johannesjo#165 review: - Settings → General → New Task Defaults section with three toggles - New Task dialog open effect now reads all three defaults from the store (fixes skip-permissions and propagate always opening unchecked, and the race where stepsEnabled captured false before loadState ran) - showSteps migrated to defaultStepsEnabled; existing preferences preserved - persistedSnapshot() exported and tested directly (was tautological inline) - Dead PersistedState.showSteps type removed - OpenSpec change (proposal.md, tasks.md, specs delta) added so `openspec validate --all --strict` passes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
650817b to
503c3e3
Compare
Review summary — addressed ✅Thanks for the thorough second pass — all issues addressed in the latest push. Here's what was fixed, in the same order as your comments: 🔴 Critical —
|
|
Thanks for the detailed PR and tests — the migration story and OpenSpec proposal are great. A few correctness issues to address before merging: High — reset effect tracks store defaults, can clobber in-flight edits ( createEffect(on(() => props.open, (open) => {
if (!open) return;
untrack(() => {
setStepsEnabled(store.defaultStepsEnabled);
setSkipPermissions(store.defaultSkipPermissions);
setPropagateSkipPermissions(store.defaultPropagateSkipPermissions);
});
// … rest of reset
}));Medium — hidden propagateSkipPermissions: coordinatorMode() ? propagateSkipPermissions() : undefined,But the checkbox UI is gated on propagateSkipPermissions:
coordinatorMode() && agentSupportsSkipPermissions() && skipPermissions()
? propagateSkipPermissions()
: undefined,Low — legacy s.defaultStepsEnabled = raw.defaultStepsEnabled === true || raw.showSteps === true;If a saved state has s.defaultStepsEnabled =
typeof raw.defaultStepsEnabled === 'boolean'
? raw.defaultStepsEnabled
: raw.showSteps === true;The existing "new field wins" test only covers the Low — Settings row should mirror the danger wording ( Also
|
|
All issues addressed in the latest push, in order: 🔴 High — open effect re-fires on store mutations Confirmed: reading Fix: wrapped in 🟡 Medium — Confirmed: submission only gated on Fix: gate submission the same way the UI gates visibility: propagateSkipPermissions:
coordinatorMode() && agentSupportsSkipPermissions() && skipPermissions()
? propagateSkipPermissions()
: undefined,🟡 Low — legacy Confirmed: Fix: presence-check the new field first, fall back to s.defaultStepsEnabled =
typeof raw.defaultStepsEnabled === 'boolean'
? raw.defaultStepsEnabled
: raw.showSteps === true;Added the missing reverse test ( 🟡 Low — Settings label didn't match the danger level Updated to "Dangerously skip all confirms by default" with a description noting the blast radius ("The agent will run without asking for confirmation. Only honoured when the selected agent supports it."). Also — dead Removed. It was deliberately dropped in |
|
Thanks for the iterations here. The persistence wiring and dialog gating look mostly solid now, but I found one behavior I think should be fixed before merge. Main issue:
That means checking or unchecking Steps for one task silently mutates the Settings -> New Task Defaults value. This preserves the old "last used Suggested fix: only mutate Smaller follow-ups:
Verification: |
9141e1f to
a9dea0d
Compare
|
All issues addressed in the latest push — in order: Main issue — Confirmed: Fix: removed lines 248–249 (the comment and the Regression test added to Low — Confirmed: Fix: added a presence check so invalid present values resolve to s.defaultStepsEnabled =
typeof raw.defaultStepsEnabled === 'boolean'
? raw.defaultStepsEnabled
: 'defaultStepsEnabled' in (raw as object)
? false
: raw.showSteps === true;New persistence test added:
Updated the checklist line to describe the presence-check logic instead of the old
Removed the |
|
Requested change before merge: the OpenSpec still says creating a task with the opposite Steps checkbox state updates Please update both the canonical steps-tracking spec and the change spec to match the new contract:
I am not blocking on the missing component tests or the broader pre-existing autosave omissions. |
…d propagate Adds three persistent app-level defaults that pre-fill checkboxes in the New Task dialog so users who habitually enable the same options do not have to re-tick them on every task. ## New settings (Settings → General → New Task Defaults) - defaultStepsEnabled — pre-checks Steps tracking in the New Task dialog - defaultSkipPermissions — pre-checks skip-permissions (when agent supports it) - defaultPropagateSkipPermissions — pre-checks propagate (coordinator + skip-perms only) ## Migration loadState migrates legacy showSteps → defaultStepsEnabled on first load. showSteps is no longer written by saveState. Invalid present values for defaultStepsEnabled do not fall back to the legacy field. ## Behavior notes - Task creation never mutates defaultStepsEnabled; only the Settings setter does. - propagateSkipPermissions is gated at submission by all three conditions (coordinatorMode && agentSupportsSkipPermissions && skipPermissions). - The open effect samples defaults inside untrack() on the open transition only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nabled contract Both the canonical spec and the new-task-defaults change spec incorrectly stated that creating a task with the checkbox in the opposite state would update defaultStepsEnabled. The implementation intentionally does not do this — only the Settings toggle mutates the default. Update both specs to reflect the actual contract: - New Task dialog reads defaultStepsEnabled on open - Settings → General → New Task Defaults toggles update defaultStepsEnabled - Task creation does not mutate defaultStepsEnabled Also renames the showSteps reference to defaultStepsEnabled in the canonical spec to match the renamed store field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
a9dea0d to
2514fda
Compare
Spec update addressedThanks for the clear feedback. Both spec files have been updated in the latest push to match the actual contract. Canonical spec (
|
|
Thank you very much! <3 |
Problem
Every time a user creates a new task, three commonly-toggled options reset to
their hardcoded defaults:
Users who habitually enable one or more of these options have to manually
re-check them for every single task, which is repetitive friction.
Solution
Add three persistent settings under a new "New Task Defaults" section in
Settings → General:
The propagate option is conditionally rendered only when
coordinatorModeEnabledis true — matching the same conditional in the New Task Dialog itself.
Implementation
Store layer (
src/store/)types.ts— addeddefaultStepsEnabled,defaultSkipPermissions,defaultPropagateSkipPermissionsto bothAppStoreandPersistedStatecore.ts— default values (allfalse)ui.ts— three setter functions following the existing patternstore.ts— re-exports the new setterspersistence.ts— save/load with the standard falsy-omit pattern(field absent from JSON when
false, explicittruewhen set); alsoadded to
LegacyPersistedStatefor forward-compat parsingUI layer (
src/components/)SettingsDialog.tsx— new "New Task Defaults" section inserted in theGeneral tab, before "Ask about Code"; three checkbox rows matching the
existing label+description card style
NewTaskDialog.tsx—stepsEnabled,skipPermissions, andpropagateSkipPermissionssignals now initialise from the store defaultsinstead of hardcoded
false/store.showStepsTests
44 new test cases added to
src/store/persistence.test.ts, one describeblock per setting (
new task defaults persistence). Each setting gets fivecoverage points:
falsewhen the field is absent from saved statetruefrom saved statefalsefrom the serialised JSON (falsy-omit pattern)truethroughsaveStatefalseAll 1113 tests pass on this branch (full suite:
npm test).🤖 Generated with Claude Code