* feat(task): add Ctrl+Enter and escape shortcuts
* fix(task): prevent accidental deletion on Escape, extract SubmitTrigger, and add tests
* fix(task): guard Escape deletion with !wasChanged && !newVal and make Mod+Enter no-op for top-level tasks
* fix(task): make Mod+Enter add a subtask regardless of task level
Top-level tasks previously made Mod+Enter a no-op; the keyboard chain
now creates a child subtask on top-level and a sibling on subtasks,
matching the existing `a` shortcut. Adds spec coverage for both paths.
* test(task): cover Mod+Enter ordering and rename spec to task-shortcuts
The new test asserts that typing a title and pressing Mod+Enter both
persists the title (via update) and spawns the new subtask (via
addSubTaskTo). Renames the spec file to reflect that it covers both
Escape and Mod+Enter handling on TaskComponent.
* fix(task): keep focus on fresh empty subtask and expand collapsed parent
- task-title: Mod+Enter is a no-op when both the current and previously
persisted titles are empty, preventing duplicate empty subtasks on
rapid Ctrl+Enter and keeping the textarea focused for typing.
- task.component: when Mod+Enter targets self (top-level task), expand
the parent's hidden subtask list first so the newly spawned subtask
is visible and can be focused for editing.
* revert(task): drop Mod+Enter dedupe — over-fires in browser
The dedupe path (skip when current and previous title are both empty)
intermittently blocked Mod+Enter even on tasks with content, leaving
the user with no visible response. Reverting to the simple unconditional
spawn while keeping the parent auto-expand fix from this commit chain.
* feat(task): on Mod+Enter, focus an existing empty subtask if one exists
Mod+Enter now spawns a new subtask only if there is no empty subtask
already under the same parent. If one is found, focus moves to it
instead of creating a duplicate. Works the same way for both subtasks
(empty siblings) and top-level tasks (empty children). When the parent
has HideAll set, expand the subtask list first via showSubTasks so the
focused/created child is visible.
* feat(task): trigger Mod+Enter from focused-task path too
Previously Mod+Enter only fired from the title editor. Now a focused
(but not editing) task also responds — invoking the same smart spawn /
focus-empty-sibling logic via the global task shortcut handler.
addSubTaskOrFocusEmpty() is now public so the shortcut service can
delegate to it.
* fix(task): focused-task Ctrl+Enter mirrors `a` (plain create), not smart logic
When a task is focused but not editing, Ctrl+Enter now calls addSubTask
directly — same as the `a` shortcut. The smart focus-empty-sibling
logic stays inside the title editor, where the user has already chosen
to commit the current value. Also moved the new shortcut handler above
the plain-Enter "edit title" branch so the modifier key isn't swallowed.
* refactor(task): collapse Mod+Enter and keydown branches
- _addSubTaskOrFocusEmpty: parent and subtask paths now share a single
store query and find/focus/create flow. The only parent-specific bit
left is the HideAll auto-expand check at the top.
- handleKeyDown: replaced three near-identical Escape/Enter/ModEnter
branches with a single trigger lookup followed by a shared blur path.
* test(task): cover handleKeyDown trigger routing + cleanup
- task-title.component.spec: 4 specs covering Escape/Enter/Mod+Enter
routing and the mention-list swallow path. Locks in the recent
consolidation of the keydown handler.
- task-shortcuts.spec: replace magic _hideSubTasksMode literals with
named HideSubTasksMode enum values for grep-friendliness.
- task-shortcut.service: add a precedence comment near the Ctrl+Enter
branch documenting that a user-remapped togglePlay (handled earlier)
takes precedence over this hardcoded combo.
* refactor(task): consolidate task-focus helper into TaskService
Promote _focusNewlyCreatedTask to a public TaskService.focusTaskById,
and route TaskComponent's focus-empty-sibling flow through the same
helper. Eliminates ~15 lines of double-RAF + edit-if-empty duplication
that lived in task.component.ts._focusExistingTask.
---------
Co-authored-by: Johannes Millan <johannes.millan@gmail.com>
Strip _deadline suffix from reminder IDs before passing to the dialog so
task lookups succeed. Add isDeadlineReminder flag so the dialog can use
deadlineRemindAt for display, clear it on dismiss, and snooze by updating
the deadline reminder time instead of the schedule reminder.
Implement a flexible two-way sync system for GitHub issues:
- Add field mapping framework (isDone↔state, title↔title, notes↔body)
with configurable sync directions (off/pullOnly/pushOnly/both)
- Push field changes to GitHub on task update via NgRx effect
- Auto-create GitHub issues for new top-level tasks (opt-in toggle)
- Add adapter interface for future provider extensibility
- Add conflict detection using last-synced baseline values
The reminderId field was deprecated in favor of remindAt. After migration
4.6, tasks store reminder timestamps directly in remindAt instead of
referencing a separate Reminder entity.
Changes:
- Remove reminderId from TaskCopy interface and plugin-api Task type
- Update all code checking reminderId to use remindAt instead
- Update data repair to clear legacy reminderId values
- Remove obsolete reminderId validation (reminders array is now empty)
- Update migration files to handle legacy types
- Update tests to reflect new behavior
- Add unit tests for isPersistentAction type guard.
- Fix compilation errors in task scheduling components caused by removed reminderId/removeReminderFromTask.
- Fix type error in create-sorted-blocker-blocks.spec.ts.
- Fix lint errors in various files.
- Add @super-productivity/plugin-api package with TypeScript definitions
- Define core plugin interfaces, types, and manifest structure
- Add plugin hooks system for event-driven architecture
- Create plugin API type definitions and constants
- Add documentation and development guidelines
Implement collapsible "Later Today" section on work-view page that shows:
- Main tasks scheduled for later today
- Subtasks scheduled for later today (even if parent isn't)
- Tasks hidden from normal undone task list
- Chronological ordering by earliest scheduled time
- Disabled drag-and-drop functionality
Includes comprehensive test coverage with 14 test cases covering edge cases,
parent-subtask relationships, and sorting behavior.