generated from nhcarrigan/template
feat: productivity suite — task loop, workflow, theming, docs & more (#197)
## Summary A large productivity-focused feature branch delivering a suite of improvements across automation, project management, theming, performance, and documentation. ### Features - **Guided Project Workflow** (#189) — Four-phase workflow panel (Discuss → Plan → Execute → Verify) to keep projects structured from idea to completion - **Automated Task Loop** (#179) — Per-task conversation orchestration with wave-based parallel execution, blocked-task detection, and concurrency control - **Wave-Based Parallel Execution** (#191) — Tasks run in dependency-aware waves with configurable concurrency; independent tasks execute in parallel - **Auto-Commit After Task Completion** (#192) — Task Loop optionally commits after each completed task so progress is never lost - **PRD Creator** (#180) — AI-assisted PRD and task list panel that outputs `hikari-tasks.json` for the Task Loop to consume - **Project Context Panel** (#188) — Persistent `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, and `STATE.md` files injected into Claude's context automatically - **Codebase Mapper** (#190) — Generates a `CODEBASE.md` architectural summary so Claude always understands the project structure - **Community Preset Themes** (#181) — Six built-in community themes: Dracula, Catppuccin Mocha, Nord, Solarized Dark, Gruvbox Dark, and Rosé Pine - **In-App Changelog Panel** (#193) — Fetches release notes from GitHub at runtime and displays them inside the app - **Full Embedded Documentation** (#196) — Replaced the single-page help modal with a 12-page paginated docs browser featuring a sidebar TOC, prev/next navigation, keyboard navigation (arrow keys, `?` shortcut), and comprehensive coverage of every feature ### Performance & Fixes - **Lazy Loading & Virtualisation** (#194) — Virtual windowing for conversation history, markdown memoisation, and debounced search for smooth rendering of large sessions - **Ctrl+C Copy Fix** (#195) — `Ctrl+C` now copies selected text as expected; interrupt-Claude behaviour only fires when no text is selected ### UX - Back-to-workflow button in PRD Creator and Task Loop panels for easy navigation - Navigation icon cluster replaced with a single clean dropdown menu ## Closes Closes #179 Closes #180 Closes #181 Closes #188 Closes #189 Closes #190 Closes #191 Closes #192 Closes #193 Closes #194 Closes #195 Closes #196 --- ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #197 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #197.
This commit is contained in:
@@ -66,6 +66,9 @@
|
||||
custom_font_family: null,
|
||||
custom_ui_font_path: null,
|
||||
custom_ui_font_family: null,
|
||||
task_loop_auto_commit: false,
|
||||
task_loop_commit_prefix: "feat",
|
||||
task_loop_include_summary: false,
|
||||
});
|
||||
|
||||
let showCustomThemeEditor = $state(false);
|
||||
@@ -730,7 +733,7 @@
|
||||
<div class="flex flex-wrap gap-2" role="group" aria-label="Theme selection">
|
||||
<button
|
||||
onclick={() => handleThemeChange("dark")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 rounded-lg border transition-colors {config.theme ===
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'dark'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
@@ -739,7 +742,7 @@
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("light")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 rounded-lg border transition-colors {config.theme ===
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'light'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
@@ -748,7 +751,7 @@
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("high-contrast")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 rounded-lg border transition-colors {config.theme ===
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'high-contrast'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
@@ -758,7 +761,7 @@
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("custom")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 rounded-lg border transition-colors {config.theme ===
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'custom'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
@@ -767,6 +770,96 @@
|
||||
Custom
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Preset Themes — Dark -->
|
||||
<span class="block text-xs text-[var(--text-tertiary)] mt-3 mb-2">Dark Presets</span>
|
||||
<div class="flex flex-wrap gap-2" role="group" aria-label="Dark preset theme selection">
|
||||
<button
|
||||
onclick={() => handleThemeChange("dracula")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'dracula'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Dracula theme"
|
||||
>
|
||||
Dracula
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("catppuccin")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'catppuccin'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Catppuccin Mocha theme"
|
||||
>
|
||||
Catppuccin
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("nord")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'nord'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Nord theme"
|
||||
>
|
||||
Nord
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("solarized")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'solarized'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Solarized Dark theme"
|
||||
>
|
||||
Solarized
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Preset Themes — Light -->
|
||||
<span class="block text-xs text-[var(--text-tertiary)] mt-3 mb-2">Light Presets</span>
|
||||
<div class="flex flex-wrap gap-2" role="group" aria-label="Light preset theme selection">
|
||||
<button
|
||||
onclick={() => handleThemeChange("solarized-light")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'solarized-light'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Solarized Light theme"
|
||||
>
|
||||
Solarized
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("catppuccin-latte")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'catppuccin-latte'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Catppuccin Latte theme"
|
||||
>
|
||||
Latte
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("gruvbox-light")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'gruvbox-light'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Gruvbox Light theme"
|
||||
>
|
||||
Gruvbox
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleThemeChange("rose-pine-dawn")}
|
||||
class="flex-1 min-w-[70px] px-3 py-2 text-sm rounded-lg border transition-colors {config.theme ===
|
||||
'rose-pine-dawn'
|
||||
? 'bg-[var(--accent-primary)] border-[var(--accent-primary)] text-white'
|
||||
: 'bg-[var(--bg-primary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--accent-primary)]'}"
|
||||
title="Rosé Pine Dawn theme"
|
||||
>
|
||||
Rosé Pine
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Custom Theme Editor -->
|
||||
|
||||
Reference in New Issue
Block a user