feat: subtask UX, PR badge refresh, batch delete, notification & terminal size fixes#81
Open
kovtcharov-amd wants to merge 47 commits into
Open
feat: subtask UX, PR badge refresh, batch delete, notification & terminal size fixes#81kovtcharov-amd wants to merge 47 commits into
kovtcharov-amd wants to merge 47 commits into
Conversation
showBrowseButton was hardcoded to false, preventing users from using the native folder picker. Set to true so the Browse button appears and opens the OS folder dialog via the existing WebSocket handler. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add drag-and-drop support on the workspace panel: drop a folder from the OS file explorer to add it as a workspace. In Electron, the full path is extracted directly. In the browser, opens the path input modal. - Fix Browse button: use REST endpoint instead of blocking WebSocket execFileSync which froze the server. Only show Browse in Electron mode where the native dialog works reliably. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: syncWorkspaceMcpConfigs wrote .mcp.json to the claudia project root on every startup, triggering tsx watch to restart the server in an infinite loop. Now skips syncing to Claudia's own workspace directory. Also: - Fix Browse button: add -STA flag for Windows PowerShell folder dialog, remember last browsed path across sessions, kdialog fallback on Linux - Re-enable Browse button in Add Workspace dialog - Fix drag-and-drop: only activate for external OS drops (Files type), internal workspace reordering drags pass through unaffected Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 512KB caps were too aggressive — users lost scrollback history after rotation. Disk files now cap at 10MB (rotate keeping 5MB tail), and clients receive up to 2MB of history for scrollback. Memory loading on reconnect remains capped at 512KB to prevent OOM. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a scrollbar appears/disappears during active output, the container width changes by ~15px, flipping cols by 1-2. This caused Claude Code's TUI to re-render at alternating widths, producing overlapping garbled text. Fix: - Skip resize events where cols changed by <= 2 (scrollbar noise) - Track last sent cols/rows to deduplicate - Increase ResizeObserver debounce from 50ms to 150ms - Use fitTerminal() (fit + refresh) to clear artifacts after resize Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
References #59 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d-turn The previous policy only reconnected tasks with shouldContinue=true (busy/starting at time of shutdown). This meant every tsx watch restart disconnected all idle tasks (34 tasks showing 'disconnected'), requiring manual clicks to reconnect each one. Now reconnects ALL tasks that were active within the last 2 hours and have a sessionId. Mid-turn tasks still get priority in reconnect order. Batching (2 at a time with delays) prevents resource exhaustion.
1. TaskInputBar: queue messages when WebSocket is not open instead of silently dropping them. Retries every 500ms until WebSocket reconnects. Previously typing 'continue' while disconnected did nothing — the message stayed in the input but was never sent. 2. Start scripts: switch from 'dev' (tsx watch) to 'dev:no-watch' to prevent spurious server restarts from file changes (Claude Code tasks editing source files, antivirus, Windows indexer). The UI restart button still works for manual restarts. 3. CLAUDE.md: updated with current architecture, no-push-to-main rule, no attribution comments rule.
…disconnect # Conflicts: # CLAUDE.md # frontend/src/components/TerminalView.tsx
Re-pasting on retry caused duplicate content because Claude Code wraps long prompts across multiple lines — Ctrl+U only clears the current line, leaving the rest. Now the prompt is written once; only Enter is retried.
…e, MCP guidance - Worktree child workspaces are hidden from the sidebar and rendered inline within their parent workspace as collapsible groups - Each group shows the branch name (or task name after Claude auto-titles) with a green dot for active tasks and a remove button - Added isolate toggle button in the task input row (GitBranch icon) that creates a worktree for the next task when enabled - Backend now reads `isolate` flag from task:create messages and creates a worktree when set (previously only workspace-level autoWorktree worked) - When a task in a worktree is renamed, the worktree workspace displayName updates to match so the group header shows a human-readable label - Added worktree isolation guidance to the MCP orchestration system prompt instructing Claude to use isolate:true for file-modifying parallel tasks - Silent worktree creation failures now send a WS error to the client
Spawned tasks inherited ANTHROPIC_MODEL from the shell that launched the server (e.g. a corporate proxy profile), which in interactive PTY mode beat the --model flag -- so tasks silently ran the inherited model regardless of the Claudia setting. getTaskEnvironment now overrides ANTHROPIC_MODEL with the configured defaultModel so the Claudia setting is authoritative. Also: validate effortLevel/defaultModel config switches, and add a -Watch switch to start.ps1 to opt into tsx auto-reload (default stays no-watch for stability).
…croll - resolveClaudeSpawn now detects the native bin/claude.exe shipped by newer @anthropic-ai/claude-code and spawns it directly. The old code looked only for cli.js, didn't find it, and fell back to `cmd.exe /c claude.cmd`, which re-parsed the command line and corrupted the multiline --system-prompt and the --model flag after it -- so spawned tasks ignored the configured model. Reverts the earlier ANTHROPIC_MODEL env override, which was the wrong fix. - decodeHtmlEntities normalizes task display names (e.g. "notes & CI" -> "notes & CI") at rename and on serialization, fixing legacy/agent-encoded names rendered as plain text in the UI. - TerminalView guards scrollToLine against a non-integer viewportY (xterm throws "This API only accepts integers" on NaN), stopping an error loop.
Updates the injected orchestration guidance and the claudia_create_task tool description to instruct agents to prefer spawning Claudia tasks over launching their own internal subagents for delegatable work — Claudia tasks are user-visible, monitorable, resumable, and worktree-isolated. Internal subagents remain the fallback for quick inline lookups or when a task would clearly produce a worse outcome.
PR badges: - Resolve a workspace branch's GitHub PR via `gh` (getPrForBranch), cached in-memory on the workspace store (never persisted) and pushed to the UI. - Refresh only active/unseen workspaces every 90s with reentrancy and per-workspace in-flight guards, to avoid `gh` process storms on slow-auth machines; also refresh on task create and workspace reset. - New PrBadge component renders #number tinted by PR state (draft/open/ merged/closed) with a subtle CI status mark, in the worktree group header and the main workspace header. Tooltip shows PR number, title, state, CI. Backend restart: - start.ps1/start.sh run the backend in a relaunch loop; exit code 75 (from POST /api/server/restart) restarts it, any other code stops. Fixes the restart button, which previously killed the backend with no recovery. - start.ps1 caches the process Handle before WaitForExit so ExitCode is readable; full process-tree kill on exit frees ports and fixes stuck Ctrl+C. - `dev` script sets CLAUDIA_WATCH_MODE so the endpoint touches index.ts under tsx watch but exits 75 in no-watch. gracefulShutdown takes an exit code and guards against double-shutdown.
When a task runs raw `git worktree add` (instead of Claudia's auto-worktree path), the new worktree wasn't registered as a workspace and never showed in the sidebar. discoverWorktrees() scans repos that have Claudia tasks, finds git worktrees not yet known, and registers them via addWorktreeWorkspace + broadcast. Triggered when a task goes idle and on a 60s periodic sweep, with a concurrency guard. Scoped to repos with active tasks to avoid surfacing unrelated pre-existing worktrees.
A worktree with a single task now renders inline as a normal task row with a small worktree icon badge (branch in tooltip) plus a PR badge for its branch, instead of a collapsible group section. Worktrees with 2+ tasks keep the group (where the PR badge lives on the group header, so the per-task badge would be redundant).
Rework worktree discovery: instead of mass-registering every worktree in a repo (which floods repos with dozens of worktrees), detect when a task's Claude session creates a NEW worktree by diffing the repo's worktree list against a per-repo baseline taken at first scan. A branch that appears while a task runs in that repo is attributed to the most-recently-active task and the task row is annotated with sessionWorktreeBranch + PR info, showing the worktree badge in place. The task's PTY cwd stays at the parent repo, so the session's branch isn't otherwise visible.
Long task prompts sometimes arrived truncated at the start ("began
mid-sentence") because Claude Code's TUI input box repaints while the prompt
is being written, dropping leading characters. Wrap the initial-prompt write
in bracketed paste (ESC[200~ ... ESC[201~) so the terminal delivers it as one
atomic paste. Claude Code enables bracketed-paste mode (ESC[?2004h), so the
markers are consumed. Strip any stray end-marker in the prompt defensively.
A worktree workspace stored the branch it was created with, but Claude often switches to or creates a different branch inside the worktree and opens the PR there (e.g. claudia/task-xxxx -> fix/my-feature). PR lookup queried the stale stored branch and found no PR, so the badge stayed empty. Now resolve the worktree's CURRENT branch via getCurrentBranch(worktreePath), falling back to the stored worktreeBranch.
The PR refresh only polled active-task workspaces on the 90s interval, so when a task switched branches and went idle the badge stayed stale. Now trigger refreshPrInfoFor on idle, same as worktree discovery, so the badge updates promptly after Claude finishes a step that changed the branch.
Previously the PR badge only refreshed on the 90s interval, so branch switches mid-task showed stale badges. Now refreshPrInfoFor does a fast local getCurrentBranch check on every idle/busy state change and only calls the expensive gh API when the branch actually changed. The periodic interval uses force=true to also catch CI status updates on unchanged branches.
The dropdown menu used position:absolute inside an overflow-y:auto container, so it got clipped when near the bottom. Switched to position:fixed and calculate coordinates from the trigger button's viewport rect. The menu closes on scroll since its fixed position would detach from the trigger.
… prompt The initial-prompt path used bracketed paste to prevent front-truncation, but the writeToTask follow-up path (line 3404) still wrote raw text. Large pasted messages (e.g. release notes with markdown/emoji) got truncated the same way. Now both paths wrap in ESC[200~...ESC[201~.
Archived tasks were rendered in insertion order (oldest first) and showed the raw prompt text instead of the displayName set by the agent. Now sorted by lastActivity descending and uses displayName when available.
Messages sent while a task is busy were written as raw text without bracketed paste, causing the same truncation/loss as the initial-prompt bug. Now all multi-char message writes use bracketed paste regardless of task state. Reverts the queuing approach (the TUI does accept input while busy when delivered correctly).
Adds four MCP tools so Claude Code sessions can self-schedule: - claudia_cron_create: schedule a recurring or one-shot prompt on any task - claudia_cron_list: list all scheduled tasks (optionally filtered by taskId) - claudia_cron_delete: cancel a scheduled task by cronId - claudia_cron_pause: pause/resume a scheduled task The orchestration system prompt is updated so each session knows its own task ID and how to use cron expressions for periodic checks, delayed follow-ups, or recurring monitoring.
gh pr list --head main returns unrelated PRs (e.g. from forks) that aren't the workspace's own PR, so a workspace on main incorrectly showed a badge. Now skip the PR lookup entirely when the branch matches the repo's default branch and clear any stale prInfo.
The claudia MCP server needs per-task env vars (CLAUDIA_WORKSPACE_ID, CLAUDIA_TASK_ID) to function. It was being included in the workspace .mcp.json sync WITHOUT those vars, and Claude Code loaded that env-less copy instead of the per-task --mcp-config copy -- causing "Claudia MCP tools aren't available." Only inject the claudia server entry when a task context (workspaceId) is present, so it only appears in --mcp-config.
added 15 commits
June 8, 2026 11:07
The PR badge <a> tag is natively draggable, which intercepted dragenter
events when dragging workspaces over a header containing a PR badge,
preventing the drop-target highlight. Set draggable={false} on the link.
PR info broadcasts were sending the entire workspaces array via workspace:updated, which triggered setWorkspaces() on the frontend and re-rendered the full workspace list. This killed in-progress workspace drag-and-drop because the browser's native drag tracking lost its DOM references. Now broadcast only the affected workspace (singular payload), which uses updateWorkspace() — a targeted merge that doesn't re-render unrelated workspace sections.
Inline worktree task items were draggable={true} with no-op drag handlers,
which let them initiate spurious drags and intercept dragenter events from
neighboring real task drags. Set draggable={false} when worktreeInfo is
present so they don't interfere with task reordering.
The system prompt now explicitly tells Claude to keep the title current whenever the focus of work shifts (not just "if work evolves significantly"). The mid-session title instruction is injected every 5th follow-up message instead of only once, reinforcing that stale titles should be updated.
Resumed sessions (--resume) don't load MCP servers from --mcp-config, only from the workspace .mcp.json. The previous fix excluded claudia from .mcp.json entirely, breaking MCP tools on resumed tasks. Now build a per-workspace .mcp.json with CLAUDIA_WORKSPACE_ID set so the claudia MCP server works on both new and resumed sessions. Also debounce the worktree discovery trigger and cache non-git repos to reduce log spam.
The four claudia_cron_* tools were registered twice, causing the MCP server to crash on startup with "Tool claudia_cron_create is already registered". This silently broke ALL claudia MCP tools for every task session — the root cause of the persistent "Claudia MCP tools aren't available" reports.
Critical: parseWorktreeListOutput had isFirst inside the loop, so every worktree got isMain=true. discoverWorktrees filtered !isMain which always returned empty -- session worktree attribution never worked. Fixed by setting isMain=false for all, then marking only results[0] as true. Also: task:rename workspace broadcast uses singular update (not full array) to avoid killing drag; removed double-decode in toPublicTask; clean up prInfoCache on workspace delete.
- Auto-accept Claude Code permission prompts at PTY level when skip- permissions is enabled (bypasses known CLI bugs with --dangerously-skip-permissions) - Pass --allowedTools * instead of mcp__* when skip-permissions is on - Write allow: ['*'] to settings.local.json for all workspaces (including self) when skip-permissions is enabled - Trigger workspace sync when skipPermissions config changes - Merge regular tasks and worktree groups into a unified sorted list so new worktree tasks appear at their natural position - Filter worktree child workspaces from references submenu - Fix context menu z-index so it renders above sibling workspace cards
claudia_list_tasks and claudia_stop_all_tasks were filtering by exact workspace ID match, which excluded tasks running in worktree child workspaces. Now fetches the workspace list to find children with matching worktreeParentId and includes their tasks in results.
- claudia_list_tasks now shows all tasks including disconnected and interrupted ones, with a canResume field indicating resumability - claudia_continue_task explicitly documents support for disconnected/ interrupted states (auto-reconnect was already handled by backend) - claudia_get_task_status includes canResume field - Updated tool descriptions to clarify cross-state visibility
Agents can now request task deletion via claudia_delete_task, but it requires explicit user approval — a ConfirmModal appears in the UI and the user must click "Delete" before the task is archived. If the user clicks "Keep" or ignores the popup (60s timeout), the deletion is rejected and the agent is notified. The system prompt guidance explicitly states agents must never delete tasks automatically — only when the user explicitly asks.
…-as-read - New Inbox tab in the right-hand FileExplorer panel showing GitHub notifications via gh api notifications - Unread count badge on the tab button (caps at 9+) - Mark individual notifications as read with optimistic UI update - Notification items show type icon, reason badge, clickable title, repo name, and relative timestamp - Auto-refresh every 60 seconds when tab is active - Backend endpoints: GET /api/github/notifications, PATCH .../threadId - Extracted shared formatRelativeDate helper, fixed duplicate Issues tab - Fixed apiUrlToHtmlUrl to not generate broken release URLs - Fixed stale closure in markAsRead badge count via useEffect derivation
Add complete planning documentation for Claudia Manager MVP - an enhanced task tracking and health monitoring system for Claudia Code. Planning Summary: - 13 iterations of comprehensive review - 107 issues identified and resolved (24 CRITICAL, 22 HIGH, 42 MEDIUM, 19 LOW) - 99% confidence level achieved - $0/month operational cost for MVP Core Documents: - claudia-manager.md: Main specification (~4,000 lines) - ABSOLUTELY-FINAL.md: Final certification and summary - REVIEW-COMPLETE.md: Complete iteration history - SCOPE-UPDATE-GITHUB-WEBHOOKS.md: Event-driven GitHub integration Iteration Reviews: - critique-v2.md: Initial architecture review - red-team-review.md: Hostile security review - implementation-reality.md: Code-level integration validation - production-ops.md: Production operations review - catastrophic-failures.md: Worst-case scenario analysis - scale-load.md: Performance at scale (1000 tasks, 200 repos) - security-audit.md: Defense-in-depth security review - ux-edge-cases.md: User experience and accessibility - api-compatibility.md: Backward compatibility and versioning - deployment-ops.md: Deployment and rollback procedures - testing-docs.md: Test strategy and documentation - monitoring-final.md: Monitoring and alerting MVP Features (3-week timeline): 1. Task Labels - Organize tasks with custom tags 2. Health Monitor - Detect stalled/errored tasks automatically 3. GitHub Integration - Event-driven webhooks for PR/issue tracking Validation Criteria (Week 3): - Label adoption ≥50% - Filter usage ≥30% - Health monitor clicks ≥5/day - GitHub tasks ≥5/day - User satisfaction ≥4/5 Next Steps: - Week 0: Preparation (dependencies, security modules) - Week 1-2: Implementation - Week 3: Validation and go/no-go decision See ABSOLUTELY-FINAL.md for executive summary and REVIEW-COMPLETE.md for complete iteration history.
Tasks created via claudia_create_task now appear as collapsible subtasks under the orchestrator task that spawned them. This makes it easy to see which tasks belong to a multi-agent run without hunting through collapsed worktree groups. - Add parentTaskId field to Task type and PersistedTask (survives restart) - MCP claudia_create_task sends SELF_TASK_ID as parentTaskId automatically - Frontend groups same-workspace subtasks under their parent task row - Nested worktrees (worktrees-within-worktrees) are flattened recursively and shown as indented subtasks under the orchestrator task row - Collapsible subtask toggle shows count, active pulse, and chevron - Remove the old WorktreeGroupSection header row — tasks render flat
…inal size fixes Subtask improvements: - Collapse/expand toggle rendered inline in the parent task row (pill badge with count) - Sub-worktree tasks carry workspace-level worktreeBranch and prInfo through SubtaskEntry - SubtaskList and TaskWithSubtasks wired to onRefreshTaskPr for hover-triggered refresh PR badge refresh: - task:select and new task:refreshPr (hover) trigger immediate backend PR lookup - refreshPrInfoFor uses repo root (worktreeParentId || ws.id) — fixes wrong path for worktrees - sessionWorktreePrInfo now re-fetched on the 30s interval (was set-once-and-frozen) - Idle/interrupted tasks included in interval refresh so merged PRs show up post-completion - user-triggered refreshes bypass prInfoInFlight guard so hover always fires Bypass permissions fix: - permissionMode=bypassPermissions now treated same as skipPermissions toggle - Affects --dangerously-skip-permissions flag, --allowedTools *, and settings.local.json Batch delete confirmation: - Multiple claudia_delete_task MCP calls now queue into one modal with checkboxes - Each task pre-checked; user can uncheck to keep; confirm button shows count Notification fix: - Replace undefined --background-secondary with solid var(--bg-tertiary) + color-mix tints Terminal size fix: - Replace pixel-math guess (clientWidth/9) with lastKnownTerminalSize from FitAddon - New tasks spawn PTY at the real measured terminal size, eliminating narrow-width bug
thisislance98
approved these changes
Jul 13, 2026
added 2 commits
July 13, 2026 14:38
…ence Resolved merge conflicts integrating: - WebGL2 + Unicode 11 terminal rendering (#73) - Per-task checkpoints with git snapshot/restore (#74) - Persistent UI state across reconnect/reload (#79) - Reconnect input delivery fix (#78) All our branch features preserved: - Subtask nesting and inline collapse toggle - PR badge refresh on hover/click - Batch delete confirmation modal - Bypass permissions propagation fix - Terminal size seeding from FitAddon - Notification transparency fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
▶ 5) — no separate row, no wasted spacegh pr list— now correctly uses the parent repo pathclaudia_delete_taskMCP calls accumulate into a single modal with checkboxes instead of sequential popupspermissionMode=bypassPermissionsnow correctly flows to--dangerously-skip-permissions,--allowedTools *, andsettings.local.jsonfor subtasks--background-secondaryCSS var with solidvar(--bg-tertiary)+color-mixtints — notifications were transparentclientWidth/9), eliminating the narrow-width-on-creation bugTest plan
claudia_delete_taskon multiple tasks simultaneously — verify single modal with checkbox list appears