feat(ui): parts-based rendering, DAG orchestration, and sub-agent fixes#212
Merged
lavaman131 merged 69 commits intomainfrom Feb 17, 2026
Merged
feat(ui): parts-based rendering, DAG orchestration, and sub-agent fixes#212lavaman131 merged 69 commits intomainfrom
lavaman131 merged 69 commits intomainfrom
Conversation
- Add getReadyTasks() exported function for filtering pending tasks - Returns only tasks whose blockedBy dependencies are all completed - Reuses normalizeTaskId() for consistent ID handling - Add comprehensive test suite with 15 new test cases - All tests pass with 100% function coverage and 99.13% line coverage - Type-safe and deterministic implementation Supports DAG orchestration by identifying ready-to-execute tasks. Completes task #1 from workflow.
…stics - Add DeadlockDiagnostic type with cycle, error_dependency, and none variants - Implement detectDeadlock() function that: - Detects circular dependencies using DFS algorithm - Identifies pending tasks blocked by error tasks - Reuses normalizeTaskId() for consistent ID handling - Returns detailed diagnostic information - Add comprehensive test suite with 18 focused test cases covering: - Cycle detection (simple, complex, self-referential) - Error dependency detection - Edge cases (empty lists, invalid IDs, unknown blockers) - Priority handling (cycles before error dependencies) - All 40 tests pass with 99.12% line coverage
- Replace serial worker loop in fresh run flow with runDAGOrchestrator call - Replace serial worker loop in resume flow with runDAGOrchestrator call - Remove unused imports: buildTaskListPreamble, saveWorkflowSession - Update test to mock SubagentGraphBridge for DAG orchestrator - Update test expectations to reflect DAG orchestrator behavior (completes all pending tasks) - Preserve logging/progress UX and persistence semantics from tasks #6-#12 This change enables parallel task execution while maintaining compatibility with existing workflow state management.
Fix 5 failing adversarial formatting tests in content segment builder: - Skip task list insertion when tasksExpanded is false to avoid splitting text for hidden/collapsed task panels - Remove trimStart() on remaining text after tool insertions to preserve leading whitespace boundaries - Restrict paragraph splitting to text truly interleaved between non-text segments and skip fenced code blocks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove automatic runDAGOrchestrator() invocation from both /ralph run and resume command paths. After bootstrapping session and task state, control now returns to the main agent for manual worker dispatch. - Remove runDAGOrchestrator() function and all orchestrator-only imports - Update resume test to verify normalized state without auto-completion - Remove DAG orchestrator integration and E2E test suites (dead code) - Update module description to reflect manual dispatch model Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove dead orchestrator infrastructure from workflow-commands.ts that was left behind after removing auto orchestrator calls in task #1: - Remove graph-related imports (CompiledGraph, BaseState, NodeDefinition, AtomicWorkflowState, setWorkflowResolver, CompiledSubgraph) - Simplify WorkflowMetadata interface: remove generic type parameter and createWorkflow field (graphs are never executed) - Remove entire workflow registry and resolution section (~150 lines): workflowRegistry, initializeRegistry, getWorkflowFromRegistry, resolveWorkflowRef, hasWorkflow, getWorkflowNames, refreshWorkflowRegistry - Remove initializeWorkflowResolver and createWorkflowByName functions - Remove WORKFLOW_DEFINITIONS export alias - Simplify BUILTIN_WORKFLOW_DEFINITIONS: remove dummy graph node creation - Update registerWorkflowCommands to not call initializeWorkflowResolver - Clean up re-exports in commands/index.ts and ui/index.ts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bootstrap Ralph task context after planning/resume so manual worker dispatch starts with task metadata in-session. Improve tool/sub-agent correlation and content insertion ordering so task lists, agent trees, and tool events render in stable chronological order. Refactor skill and parallel-agent status indicator helpers, pin Ralph task updates to the panel while restoring inline task rendering elsewhere, and add focused regression tests plus related specs/research docs. Assistant-model: GitHub Copilot CLI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add parallel-agent-background-lifecycle.test.ts with 19 tests covering: Unit Tests (8): - Agent creation with mode=background/async/sync - tool.complete skips finalization for background agents - tool.complete transitions sync agents to completed - subagent.complete transitions background agents to completed/error - interrupt sets background agent to interrupted Integration Tests (11): - Full background lifecycle: spawn → tool.complete → subagent.complete - Mixed sync+background agents finalize correctly - Stream finalization hasActive checks include background agents - Stream finalization map skips background agents - Field preservation during transformations - Edge cases (empty arrays, ID matching, etc.) All tests pass (19/19). Total test suite: 1084 tests passing. Context: Tests verify the lifecycle state management changes that prevent background-mode Task agents from being prematurely marked as completed.
Extract mode parameter at agent creation time to set status: "background" and background: true flag for background/async Task agents. Guard all five finalization sites to skip agents with the background flag, allowing subagent.complete to be the sole terminal event. - Agent creation: set background status and flag when mode=background|async - tool.complete: skip status/currentTool/durationMs update for bg agents - Cleanup helper: include "background" in active agent check - Stream finalization (3 paths): include "background" in hasActive check - Add 19 unit/integration tests for background lifecycle transitions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move compaction summary from outside scrollbox to inside scrollbox - Remove 'background' from hasActive checks so background agents don't block stream completion - Fix subagent.complete handler to allow background agent updates - Add backgroundAgentMessageIdRef to track post-stream completion updates for background agents in baked messages - Keep background agents in live state after stream finalization so completion events can propagate to the correct message - Improve task segment rendering with border and progress text - Fix setMessagesWindowed purity (defer side-effects to useEffect) - Fix TS errors in background lifecycle tests (Object possibly undefined) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ToolState type with 5 states: pending, running, completed, error, interrupted - Enforce state machine: pending → running → (completed|error|interrupted) - Export ToolState from parts module - Satisfies spec §5.3 Tool State Machine requirements
- Create useThrottledValue hook with generic type parameter - Throttle interval defaults to 100ms - Uses refs for last update time tracking - Cleans up pending timeouts on unmount - Add hook export to hooks index - Add basic validation tests Implements task #20 from parts-based rendering spec §5.3
…nion - Add imports for HitlResponseRecord, PermissionOption, ParallelAgent, TaskItem, MessageSkillLoad, McpSnapshotView, and ContextDisplayInfo - Define concrete Part type interfaces: * TextPart: accumulated text with streaming state * ReasoningPart: reasoning content with duration * ToolPart: tool execution with state machine and HITL support * AgentPart: parallel agent tracking * TaskListPart: task list with expansion state * SkillLoadPart: skill loading status array * McpSnapshotPart: MCP server snapshot view * ContextInfoPart: context display information * CompactionPart: message compaction summary - Define Part discriminated union type for all part types - Export all new types from parts module index Tasks #3 and #4 complete.
- Add Part type import from parts module - Add optional parts?: Part[] field to ChatMessage interface - Field placed after streaming field as per spec - Maintains backward compatibility with optional operator - Documentation comment added for chronological ordering Task #6 complete. Unblocks tasks #7, #9, and #16.
- Created src/ui/components/parts/reasoning-part-display.tsx - Component renders ReasoningPart with thinking emoji and duration - Displays dimmed text using theme colors (colors.muted) - Shows 'Thinking...' during streaming, 'Thought (X.Xs)' when complete - Created src/ui/components/parts/index.ts with exports - Task #22 complete
- Add Part type import from parts module - Add optional parts?: Part[] field to ChatMessage interface - Field placed after streaming field as per spec - Maintains backward compatibility with optional operator - Documentation comment added for chronological ordering Task #6 complete. Unblocks tasks #7, #9, and #16.
- Create comprehensive test suite for shouldFinalizeOnToolComplete() - Test all agent status types (pending, running, completed, error, interrupted, background) - Test background flag behavior (agent.background = true) - Test background status behavior (status = 'background') - All 8 tests pass with 100% code coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Created src/ui/components/parts/tool-part-display.tsx * Renders ToolPart with tool execution status via ToolResult component * Displays active HITL questions inline using UserQuestionInline * Shows completed HITL responses as compact records using CompletedHitlDisplay * Implements toolStateToStatus() converter from ToolState to ToolExecutionStatus * Follows parts-based rendering architecture (spec §5.5) - Updated src/ui/components/parts/index.ts * Added ToolPartDisplay and ToolPartDisplayProps exports Key architectural changes: - HITL questions render inline after tool output (not as fixed overlays) - Uses discriminated union ToolState for tool execution states - Bridges to existing ToolResult component for consistent tool output rendering - Supports both pendingQuestion (active) and hitlResponse (completed) states Implements Task #24 from parts-based rendering specification Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add non-null assertions for array accesses in id.test.ts and store.test.ts - Cast Part[] elements to TextPart when accessing content property - Fixes strict TypeScript checks while maintaining test correctness - All tests still pass with 100% coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Modify the sub-agent update effect in chat.tsx to create/update AgentPart in message.parts[] alongside the existing parallelAgents field. This enables parts-based rendering of sub-agents while maintaining backward compatibility with legacy rendering. Implementation: - Import createPartId, upsertPart, and AgentPart type - Find or create AgentPart in parts[] array during both: * Active streaming message updates * Background agent completion updates - Use upsertPart() for sorted insertion/update - Preserve all existing behavior (dual population pattern) Testing: - All 469 existing UI tests pass - Type checking passes without errors - No behavior changes to legacy rendering path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… splits Implements handleTextDelta() function that handles text streaming with natural tool boundary splitting. The function: - Appends to existing streaming TextPart if isStreaming is true - Creates new TextPart if previous is finalized or doesn't exist - Naturally handles tool-boundary text splitting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add handlers.test.ts with 4 test cases for handleTextDelta - Creates new TextPart on empty parts array - Appends to existing streaming TextPart - Creates new TextPart when last is not streaming - Handles undefined parts initialization - Add helpers.test.ts with 4 test cases for getMessageText - Returns empty string for undefined/empty parts - Concatenates multiple TextPart contents - Ignores non-text parts - All 8 tests pass with 100% function and line coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create src/ui/components/parts/registry.tsx with PART_REGISTRY - Map all Part types to their corresponding renderer components - Export PartRenderer type and PART_REGISTRY from index.ts - Registry enables dynamic dispatch based on Part discriminant Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Finalize streaming TextPart (set isStreaming: false) when tool starts - Create new ToolPart with status: running and startedAt timestamp - ToolPart includes toolCallId, toolName, input from SDK event - Maintains existing tool start behavior (toolCalls array, offsets, etc.) - Uses upsertPart() for chronological insertion into parts[] array Implements Task #14 per spec §5.4 dual-population requirements Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Modify all three text chunk handlers in chat.tsx to create/update TextPart
alongside the existing legacy content field:
1. onChunk callback (line 2452) - workflow initialization streaming
2. handleChunk (line 3355) - main stream message handler
3. handleChunk (line 4818) - queued message handler
Implementation:
- Import handleTextDelta from parts/handlers.ts
- Call handleTextDelta(msg, chunk) before updating message
- Spread parts array into message update: { ...msg, parts: withParts.parts }
- Existing content accumulation unchanged: content: msg.content + chunk
This implements dual population - the existing code continues to work
exactly as before, but we ALSO populate the parts[] array with TextPart
for the new parts-based rendering system.
Backward Compatible:
- parts field is optional on ChatMessage
- No changes to existing content field behavior
- All 477 existing tests pass
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ature stream completion Modify the stream finalization logic in index.ts to use the shouldFinalizeOnToolComplete() guard when checking for active agents. This prevents the stream from being marked as complete prematurely when background agents are still running. The guard returns false for background agents (either via the background flag or status), ensuring that: - Background agents can continue running after tool.complete - Stream remains active until background agents reach terminal state - subagent.complete events are properly processed The dual population of AgentPart was already implemented in task #16 via the parallelAgents effect in chat.tsx, so this task focuses on applying the finalization guard to prevent the critical bug where background agents cause premature stream completion. Implementation: - Import shouldFinalizeOnToolComplete from parts/index.ts - Update hasActiveAgents check in stream finalization (line 1188) - Keep stream active if any agent returns false from guard Testing: - All 19 background agent lifecycle tests pass - All 8 shouldFinalizeOnToolComplete guard tests pass - TypeScript compilation successful Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement MessageBubbleParts component that renders ChatMessage using the parts-based rendering system instead of buildContentSegments(). - Create src/ui/components/parts/message-bubble-parts.tsx - Export component from parts index.ts - Component dispatches each part to its renderer via PART_REGISTRY - Returns null if message has no parts - Passes isLast flag to indicate final part in sequence Implements task #29 per spec §5.5. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
During Phase 3 migration, this defaults to false (legacy rendering). Toggle via ATOMIC_PARTS_RENDERING environment variable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…handler Apply the shouldFinalizeOnToolComplete() guard function to all three finalization paths in the tool.complete handler (index.ts lines 655-732) to prevent premature stream completion when a background agent's tool completes. Also includes Task #18 implementation: Modify handlePermissionRequest to set pendingQuestion on ToolPart for inline HITL rendering. Changes (Task #33): - Replace inline a.background checks with shouldFinalizeOnToolComplete(a) guard in the ID-based correlation path (lines 664-676) - Add shouldFinalizeOnToolComplete(a) check to the fallback path that finds the last running agent without a result (line 692) - Add shouldFinalizeOnToolComplete(a) check to the no-result completion path for eager agents (line 725) Changes (Task #18): - Update handlePermissionRequest to accept optional toolCallId parameter - Find matching ToolPart by toolCallId in message.parts[] array - Set pendingQuestion field on ToolPart with HITL request data - Preserve existing overlay dialog behavior during dual-population The guard returns false for background agents (via background flag or status), ensuring: - Background agents continue running after tool.complete - Stream remains active until background agents reach terminal state - subagent.complete events are properly processed - Only sync/foreground agents transition to completed on tool.complete Testing: - All 19 background agent lifecycle tests pass - All 55 parts unit tests pass with 100% coverage - TypeScript compilation successful (no new errors) Spec reference: §5.4 Fix 3: Stream Deferral and Finalization Guards Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add @deprecated annotations to contentOffsetAtStart, agentsContentOffset, and tasksContentOffset fields. These legacy offset tracking fields will be removed when the parts-based rendering feature flag is removed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The parts-based model replaces the monolithic content string with structured parts[] array. Mark content field as deprecated while maintaining it for the legacy rendering path and dual-population. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mark usePartsRendering as temporary migration flag to be removed once parts-based rendering is fully validated in production. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The docs/ directory contains vendored reference code (opencode, opentui) with unresolved dependencies that fail tsc and bun test. Exclude docs/ from tsconfig and scope test discovery to src/ so pre-commit hooks pass without requiring vendored dependencies to be installed. Assistant-model: Claude Code
Sub-agent tool calls (attributed to running parallel agents) were being dispatched through both the parallel agents tree and the main chat tool-call handlers, causing duplicate display. Track sub-agent tool IDs and gate toolStartHandler/toolCompleteHandler so only non-subagent tools appear in the message parts and ctrl+o transcript. Assistant-model: Claude Code
…stem Replace legacy offset-based buildContentSegments() with parts-driven getRenderableAssistantParts() that synthesizes tool, agent, task-list, MCP snapshot, and context-info parts directly from message data. Key changes: - Remove buildContentSegments(), ContentSegment, and content offset tracking (agentsContentOffset, tasksContentOffset, contentOffsetAtStart) - Remove usePartsRendering feature flag and hook - Add SPACING constants and TASK icon set for consistent layout tokens - Overhaul task list indicator with numbered rows, left rail, progress bar, and status labels - Simplify parallel agents tree (static indicators, remove blink) - Improve HITL tool rendering with dedicated display path - Add circle indicator prefix to assistant text parts - Remove file-content loading from @mention processing (metadata only) - Delete obsolete tests for buildContentSegments and skill-indicator e2e Assistant-model: Claude Code
…Async fallback Switch background agent detection from checking mode="background"|"async" to checking input.run_in_background === true, aligning with the actual Task tool API. Add isAsync fallback in parseTaskToolResult to retroactively mark agents as background when the tool result indicates async execution. Assistant-model: Claude Code
Split TaskListPanel into a reusable TaskListBox (bordered container with progress header, bar, and task rows) and a file-driven TaskListPanel wrapper. TaskListPartDisplay now uses TaskListBox directly. Remove unused sessionId prop from TaskListPanel. Assistant-model: Claude Code
Track skill loads in chat messages with session-level deduplication via loadedSkillsRef. Render SkillLoadPart in assistant message parts for selected builtin skills (prompt-engineer, frontend-design, testing-anti-patterns). Also remove now-unused sessionId prop from TaskListPanel usage. Assistant-model: Claude Code
Replace bordered badge style in CompletedHitlDisplay with a compact single-line format matching ToolResult headers: status icon + label + question + indented response. Simplify HITL display text for declined and chat_about_this response modes. Assistant-model: Claude Code
Assistant-model: Claude Code
… expanded skills Prepend a <skill-loaded> tag when sending expanded builtin skill prompts so the model acts on the already-expanded content rather than re-loading the raw skill via the Skill tool. Also clarify in the capabilities system prompt that listed skills are user-invocable and the model should use the Skill tool directly. Assistant-model: Claude Code
…child margins
Move inter-part spacing responsibility to the parent MessageBubbleParts
container using gap={SPACING.ELEMENT}. Remove marginBottom from child
part components (AgentPartDisplay, CompactionPartDisplay, ToolPartDisplay,
ToolResult) to avoid double-spacing.
Assistant-model: Claude Code
Remove zero-padded index numbers from task items and the RUNNING status label (keep FAILED). Drop the maxWidth prop from TaskListBox and simplify width calculations. Use conditional scrollbox only when items exceed the scroll threshold instead of always wrapping in scrollbox. Assistant-model: Claude Code
Update @anthropic-ai/claude-agent-sdk to ^0.2.44, @github/copilot-sdk to ^0.1.24, @opencode-ai/sdk to ^1.2.6, @clack/prompts to ^1.0.1, oxlint to ^1.48.0, and type packages. Assistant-model: Claude Code
…scovery Write BUILTIN_SKILLS to .claude/skills/<name>/SKILL.md at startup so each SDK's native skill discovery mechanism (Claude Skill tool, Copilot skillDirectories, OpenCode server) can find them. Files are only rewritten when content changes. The generated directory is gitignored. Assistant-model: Claude Code
…lient Add maxThinkingTokens to SessionConfig and ReasoningEffort type with getReasoningEffort() helper. Thinking mode is now adaptive for opus and budget-based (defaulting to 16000 tokens) for other models. Also reformats claude-client.ts to consistent 4-space indentation and line wrapping. Assistant-model: Claude Code
…ring to parts, and fix streaming state Replace the ralph --resume command with an autonomous task loop that continues dispatching workers until all tasks complete. Thread syntaxStyle through the parts rendering pipeline so text parts render as <markdown> and reasoning parts use a dimmed <code filetype="markdown"> variant. Fix streaming state cleanup (hasRunningToolRef, streamingMeta) on interrupts, errors, and stream end to prevent spinner hangs. Improve task list panel with session ID display and blocker sub-lines. Update research-codebase and create-spec skill prompts with better instructions. Assistant-model: Claude Code
…skill refs Enable `memory: project` on all Claude agent configs for persistent context. Remove hardcoded model from OpenCode agents. Update worker.md to reference the `Skill` tool instead of the removed `SlashCommand` tool. Assistant-model: Claude Code
…DK sync Replace legacy `.claude/commands/` and `.opencode/command/` directories with unified `.claude/skills/`, `.opencode/skills/`, and `.github/skills/` SKILL.md files. Add cross-sync materialization so all three SDK directories contain the full skill catalog. Update init.ts to use `skillsSubfolder` and remove the per-agent `getCommandsSubfolder` helper. Remove legacy `SKILL_DEFINITIONS` from skill-commands.ts. Assistant-model: Claude Code
…endering Redesign tool-part-display to show completed HITL responses in a tree hierarchy with question and answer. Enhance user-question-inline with header badges, numbered options, and navigation hints. Trim trailing newlines in text-part-display. Inline blocker info in task-list-indicator instead of using a separate sub-line. Remove unused sessionId prop from TaskListPanel. Enable viewportCulling in transcript-view for performance. Assistant-model: Claude Code
Add ralphTaskIdsRef to track known task IDs from the planning phase. Guard TodoWrite persistence so only updates matching these IDs are written to tasks.json, preventing sub-agent independent todo lists from clobbering ralph's persistent task state. Add mergeBlockedBy utility to preserve task dependency info when agents omit blockedBy in updates. Assistant-model: Claude Code
Replace JSON array storage with NDJSON (newline-delimited JSON) for the conversation history buffer. Uses appendFileSync for O(1) writes instead of read-modify-write. Add in-memory dedup Set to avoid re-reading the file on each append. Support legacy JSON array migration detection on read. Batch eviction flushes in chat.tsx. Add extensive test coverage for windowing lifecycle scenarios (/clear, /compact, Ctrl+O, scale). Assistant-model: Claude Code
Remove unused exports from index.ts (initializeCommands, legacy skill re-exports). Drop 'custom' command category from registry. Remove backward-compatibility re-export of parseMarkdownFrontmatter from agent-commands.ts. Standardize indentation in builtin-commands.ts. Add setRalphTaskIds to test mock context. Assistant-model: Claude Code
…emoval Add codebase research docs and technical design specs for two planned efforts: message truncation with dual-view system, and legacy code removal for skills migration cleanup. Assistant-model: Claude Code
Assistant-model: Claude Code
Replace the manual conversation-collapsed toggle with automatic collapsing based on recency. Only the last 4 messages (EXPANDED_MESSAGE_COUNT) render fully; older messages show as collapsed single-line summaries. Live messages (streaming or with active background agents) are never collapsed regardless of position. Add shouldCollapseMessage utility with comprehensive tests. Assistant-model: Claude Code
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
This branch delivers a comprehensive set of UI and architecture improvements:
parts[]model for chat messages with typed discriminated unions (TextPart,ToolPart,AgentPart,ReasoningPart, etc.), a part registry, and dedicated display components. Includes dual-population of parts during streaming, a feature flag toggle, and guards to prevent premature stream finalization.getReadyTasks,detectDeadlock) for parallel task execution with cycle and error diagnostics..claude/commands/to.claude/skills/directories, materializes builtin skills asSKILL.mdfiles for cross-SDK discovery (Claude, OpenCode, Copilot), and adds a skill load indicator.TaskListBoxcomponent, adds a design system with spacing constants and icon registry.SkillandMultiEdittool support, and a reviewer agent.Test plan
bun test— all new and existing tests passbun typecheck— no type errorsbun lint— no lint violations