feat: task runner and problems pane#60
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds workspace-open and file-save task triggers with IPC plumbing, propagates editor context to task runs, wires task-owned PTYs to renderer terminals, introduces a Problems pane for task diagnostics, and extends shared types, preload, main, and renderer integration for trigger results and diagnostics. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Renderer as Renderer
participant Main as Main Process
participant TaskRunner as TaskRunner
participant Terminal as Terminal Pane
participant PTY as PTY/Shell
Note over Renderer,Main: File Save flow
User->>Renderer: Save file (Cmd-S)
Renderer->>Renderer: writeFile()
Renderer->>Main: notifyFileSaved(filePath)
Main->>TaskRunner: getFileSaveTasks(relativePath)
TaskRunner-->>Main: matching tasks
Main->>TaskRunner: runSingle(taskId, context)
TaskRunner->>PTY: create/attach PTY
TaskRunner-->>Main: Task status running
Main->>Renderer: TASK_STATUS_CHANGED (running)
Renderer->>Terminal: attach/reuse panel (panelPolicy)
PTY-->>TaskRunner: output / diagnostics
TaskRunner->>Main: TASK_DIAGNOSTICS
Main->>Renderer: TASK_DIAGNOSTICS
Renderer->>Renderer: update ProblemsPane
PTY-->>TaskRunner: exit
TaskRunner-->>Main: TASK_TRIGGER_RESULT (succeeded/failed)
Main->>Renderer: TASK_TRIGGER_RESULT (outcome)
sequenceDiagram
participant User
participant Main as Main Process
participant TaskRunner as TaskRunner
participant Renderer as Renderer
participant Terminal as Terminal Pane
Note over Main,TaskRunner: Workspace open auto-trigger
User->>Main: Open workspace
Main->>TaskRunner: loadTasks()
TaskRunner-->>Main: tasks loaded
Main->>Main: scheduleWorkspaceOpenTasks()
Main->>TaskRunner: runSingle(taskId, context)
TaskRunner-->>Main: Task started
Main->>Renderer: TASK_TRIGGER_RESULT (started)
Main->>Renderer: TASK_STATUS_CHANGED (running)
Renderer->>Terminal: create/route panel per policy
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 20fb54487c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (6)
.gitignore (1)
73-73: Remove duplicate.vscode/ignore entry.
.vscode/is already ignored at Line 26, so this duplicate can be removed to keep the file clean.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gitignore at line 73, Remove the duplicate ignore entry by deleting the redundant ".vscode/" line so the .gitignore only contains a single ".vscode/" entry (the existing one on Line 26); ensure no other changes are made to the file and commit the cleaned .gitignore.tests/unit/taskRunner.test.ts (1)
5-82: These tests don't exercise the new runner behavior yet.Every assertion here is against exported constants or locally constructed objects, so regressions in
TaskRunner.isTaskRunning(),getRunningExecutionByTaskId(), orpanelPolicy/closeOnExitpropagation would still pass. I'd add at least one behavioral test around a realTaskRunnerinstance with stubbed callbacks.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/unit/taskRunner.test.ts` around lines 5 - 82, Add a behavioral unit test that actually exercises TaskRunner: instantiate a TaskRunner, start a run (providing a stubbed start/stop callback or executor) with panelPolicy and closeOnExit set, then assert TaskRunner.isTaskRunning(taskId) is true and getRunningExecutionByTaskId(taskId) returns an execution whose panelPolicy and closeOnExit match; next simulate the task finishing via the stubbed callback and assert isTaskRunning becomes false and the running execution is removed. Use the TaskRunner methods (start/trigger/stop as available) and the getRunningExecutionByTaskId / isTaskRunning symbols to locate code to test.packages/renderer/src/components/panes/ProblemsPane.tsx (1)
56-64: Consider combining count calculations into a single pass.The
errorCountandwarningCounteach iterate the full diagnostics array. For large diagnostic lists, combining into a singleuseMemowould be more efficient.♻️ Optional: Single-pass count calculation
- const errorCount = useMemo(() => diagnostics.filter((d) => d.severity === 'error').length, [diagnostics]) - const warningCount = useMemo(() => diagnostics.filter((d) => d.severity === 'warning').length, [diagnostics]) + const { errorCount, warningCount } = useMemo(() => { + let errors = 0 + let warnings = 0 + for (const d of diagnostics) { + if (d.severity === 'error') errors++ + else if (d.severity === 'warning') warnings++ + } + return { errorCount: errors, warningCount: warnings } + }, [diagnostics])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/renderer/src/components/panes/ProblemsPane.tsx` around lines 56 - 64, The two separate useMemo calls (errorCount and warningCount) each iterate diagnostics; replace them with a single useMemo that scans diagnostics once and returns both counts (e.g., an object or tuple) so you compute errorCount and warningCount in one pass; update any references to use the returned values and ensure the dependency array still depends only on diagnostics and the callback handleClick remains unchanged.packages/renderer/src/hooks/useTasks.ts (1)
46-65: Nested state update insidesetRunningTaskscallback.Calling
setDiagnosticsinside thesetRunningTasksupdater function (line 50) works in practice due to React 18+ automatic batching, but it's unconventional. ThesetDiagnosticscall doesn't depend onprevfromsetRunningTasks, so it could be moved outside the callback for clarity.♻️ Optional: Move diagnostic clearing outside the updater
useEffect(() => { const unsub = window.api.onTaskStatusChanged((execution) => { + if (execution.status === 'running') { + // Clear diagnostics for this task when it starts + setDiagnostics((d) => d.filter((diag) => diag.source !== execution.taskId)) + } setRunningTasks((prev) => { if (execution.status === 'running') { - // Clear diagnostics for this task when it starts - setDiagnostics((d) => d.filter((diag) => diag.source !== execution.taskId)) // Add or update const existing = prev.findIndex((e) => e.executionId === execution.executionId)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/renderer/src/hooks/useTasks.ts` around lines 46 - 65, Move the diagnostic clearing out of the nested setRunningTasks updater: in the onTaskStatusChanged handler (window.api.onTaskStatusChanged) check if execution.status === 'running' and call setDiagnostics(d => d.filter(diag => diag.source !== execution.taskId)) outside the setRunningTasks(prev => { ... }) callback, then update runningTasks via setRunningTasks (using the same logic that adds/updates or filters by execution.executionId). Keep the rest of the handler/unsubscribe logic unchanged and ensure you still reference execution.taskId and execution.executionId when clearing diagnostics and updating runningTasks respectively.packages/main/src/index.ts (1)
1006-1043: Missingskippedresult emission for file-save triggered tasks.Unlike
scheduleWorkspaceOpenTasks(lines 929-940), theTASK_FILE_SAVEDhandler silently skips already-running tasks (line 1016) without emitting aTaskTriggerResult. For consistency and observability, consider emitting askippedresult.♻️ Emit skipped result for consistency
for (const task of tasks) { - if (taskRunner.isTaskRunning(task.id)) continue + if (taskRunner.isTaskRunning(task.id)) { + const result: TaskTriggerResult = { + taskId: task.id, + taskLabel: task.label, + source: 'fileSave', + outcome: 'skipped', + message: 'Already running', + } + getWc()?.send(IpcChannels.TASK_TRIGGER_RESULT, result) + continue + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/main/src/index.ts` around lines 1006 - 1043, The TASK_FILE_SAVED ipc handler currently ignores tasks that are already running; update the handler registered with ipcMain.on(IpcChannels.TASK_FILE_SAVED) so that when taskRunner.isTaskRunning(task.id) is true you still construct and send a TaskTriggerResult (using getWc()?.send(IpcChannels.TASK_TRIGGER_RESULT, ...)) with source: 'fileSave', taskId/taskLabel from task, outcome: 'skipped' and an optional message like 'already running' before continuing to the next task; keep the existing delay/run flow unchanged for non-skipped tasks.packages/renderer/src/components/layout/AppShell.tsx (1)
385-406: Problems panel does not close when diagnostics are cleared.When
taskDiagnostics.length === 0, the effect returns early (line 388) without removing or hiding the existing problems panel. If this is intentional (keeping the panel visible with "No problems"), theProblemsPanecomponent handles the empty state gracefully. However, consider whether the panel should auto-close when workspace diagnostics are fully resolved.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/renderer/src/components/layout/AppShell.tsx` around lines 385 - 406, The effect early-returns when taskDiagnostics.length === 0, so existing Problems panel is never closed; change the useEffect that reads dockviewApiRef.current and taskDiagnostics to handle the empty case by locating the existing panel (using dockviewApiRef.current.panels.find with id 'problems') and calling the dockview API to remove it (e.g., api.removePanel or the appropriate remove method) instead of returning early; otherwise keep the existing logic that updates or adds the panel (references: useEffect, dockviewApiRef, taskDiagnostics, problemsPanel, problemsPane, problemsPanel.api.updateParameters).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/main/src/index.ts`:
- Around line 882-908: initTaskRunner was changed to async but activateWorkspace
still calls it without awaiting, so tasks may not be loaded/scheduled before
activation completes; update the call site in activateWorkspace to await
initTaskRunner(rootPath) (or handle the returned Promise) so that
TaskRunner.loadTasks and subsequent scheduleWorkspaceOpenTasks finish before
activation proceeds, keeping the reference to initTaskRunner and
activateWorkspace to locate the change.
In `@packages/renderer/src/components/panes/TerminalPane.tsx`:
- Around line 92-110: Move the PTY attachment logic out of the mount-only block
and into a React effect that depends on params.taskPtyId (and/or
params.taskExecutionId); inside that effect update ptyIdRef.current, register
term.onData -> window.api.ptyWrite(id) and subscribe to window.api.onPtyData and
window.api.onPtyExit (using the id from params), and return a cleanup that
disposes the previous listeners (call the cleanupData/cleanupExit unsubscribers
and remove the term.onData listener) before binding new ones so reused panes
rebind to the new PTY and do not keep old subscriptions.
In `@packages/renderer/src/lib/terminal/terminalState.ts`:
- Around line 11-16: The terminal state currently includes task-bound terminals
(fields taskPtyId, taskExecutionId, taskId) which causes them to be persisted
and later restored as normal shells; update serializeTerminalState() to skip
serializing any TerminalState that has any of those task-bound fields set and
also ensure activeTerminalId is not set to the id of a skipped task-bound
terminal (or clear it) so task panels are excluded from restore; alternatively,
if you need to restore task panels, persist an explicit restore strategy in
createRestoredTerminalPanelParams() for terminal states containing
taskPtyId/taskExecutionId/taskId (same change should be applied to the other
serialization region noted around the 107-133 block).
---
Nitpick comments:
In @.gitignore:
- Line 73: Remove the duplicate ignore entry by deleting the redundant
".vscode/" line so the .gitignore only contains a single ".vscode/" entry (the
existing one on Line 26); ensure no other changes are made to the file and
commit the cleaned .gitignore.
In `@packages/main/src/index.ts`:
- Around line 1006-1043: The TASK_FILE_SAVED ipc handler currently ignores tasks
that are already running; update the handler registered with
ipcMain.on(IpcChannels.TASK_FILE_SAVED) so that when
taskRunner.isTaskRunning(task.id) is true you still construct and send a
TaskTriggerResult (using getWc()?.send(IpcChannels.TASK_TRIGGER_RESULT, ...))
with source: 'fileSave', taskId/taskLabel from task, outcome: 'skipped' and an
optional message like 'already running' before continuing to the next task; keep
the existing delay/run flow unchanged for non-skipped tasks.
In `@packages/renderer/src/components/layout/AppShell.tsx`:
- Around line 385-406: The effect early-returns when taskDiagnostics.length ===
0, so existing Problems panel is never closed; change the useEffect that reads
dockviewApiRef.current and taskDiagnostics to handle the empty case by locating
the existing panel (using dockviewApiRef.current.panels.find with id 'problems')
and calling the dockview API to remove it (e.g., api.removePanel or the
appropriate remove method) instead of returning early; otherwise keep the
existing logic that updates or adds the panel (references: useEffect,
dockviewApiRef, taskDiagnostics, problemsPanel, problemsPane,
problemsPanel.api.updateParameters).
In `@packages/renderer/src/components/panes/ProblemsPane.tsx`:
- Around line 56-64: The two separate useMemo calls (errorCount and
warningCount) each iterate diagnostics; replace them with a single useMemo that
scans diagnostics once and returns both counts (e.g., an object or tuple) so you
compute errorCount and warningCount in one pass; update any references to use
the returned values and ensure the dependency array still depends only on
diagnostics and the callback handleClick remains unchanged.
In `@packages/renderer/src/hooks/useTasks.ts`:
- Around line 46-65: Move the diagnostic clearing out of the nested
setRunningTasks updater: in the onTaskStatusChanged handler
(window.api.onTaskStatusChanged) check if execution.status === 'running' and
call setDiagnostics(d => d.filter(diag => diag.source !== execution.taskId))
outside the setRunningTasks(prev => { ... }) callback, then update runningTasks
via setRunningTasks (using the same logic that adds/updates or filters by
execution.executionId). Keep the rest of the handler/unsubscribe logic unchanged
and ensure you still reference execution.taskId and execution.executionId when
clearing diagnostics and updating runningTasks respectively.
In `@tests/unit/taskRunner.test.ts`:
- Around line 5-82: Add a behavioral unit test that actually exercises
TaskRunner: instantiate a TaskRunner, start a run (providing a stubbed
start/stop callback or executor) with panelPolicy and closeOnExit set, then
assert TaskRunner.isTaskRunning(taskId) is true and
getRunningExecutionByTaskId(taskId) returns an execution whose panelPolicy and
closeOnExit match; next simulate the task finishing via the stubbed callback and
assert isTaskRunning becomes false and the running execution is removed. Use the
TaskRunner methods (start/trigger/stop as available) and the
getRunningExecutionByTaskId / isTaskRunning symbols to locate code to test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b3975fee-e969-4483-9c74-4fdac6804198
📒 Files selected for processing (16)
.gitignoredocs/IDE_BUILD_PLAN.mdpackages/main/src/index.tspackages/main/src/preload.tspackages/main/src/tasks/taskRunner.tspackages/renderer/src/components/layout/AppShell.tsxpackages/renderer/src/components/layout/DockviewContainer.tsxpackages/renderer/src/components/panes/EditorPane.tsxpackages/renderer/src/components/panes/ProblemsPane.tsxpackages/renderer/src/components/panes/TerminalPane.tsxpackages/renderer/src/hooks/useTasks.tspackages/renderer/src/lib/terminal/terminalState.tspackages/renderer/src/styles/problems-pane.csspackages/shared/src/index.tstests/unit/app.test.tsxtests/unit/taskRunner.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: claude-review
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{css,scss,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use CSS variable token system with
data-themeattribute for theming, supporting dark and light mode
Files:
packages/renderer/src/components/layout/DockviewContainer.tsxtests/unit/app.test.tsxpackages/renderer/src/components/panes/EditorPane.tsxpackages/renderer/src/styles/problems-pane.csspackages/renderer/src/components/panes/TerminalPane.tsxpackages/renderer/src/components/panes/ProblemsPane.tsxpackages/renderer/src/components/layout/AppShell.tsx
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place all new tests in the /tests directory
Files:
tests/unit/app.test.tsxtests/unit/taskRunner.test.ts
🧠 Learnings (4)
📚 Learning: 2026-03-29T20:00:59.299Z
Learnt from: CR
Repo: Cheezeiii365/aIDE PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-29T20:00:59.299Z
Learning: Applies to renderer/**/*layout*.{ts,tsx} : Use Dockview 5.x for layout management of tiling panes
Applied to files:
packages/renderer/src/components/layout/DockviewContainer.tsxpackages/renderer/src/components/panes/TerminalPane.tsxpackages/renderer/src/components/panes/ProblemsPane.tsxpackages/renderer/src/components/layout/AppShell.tsx
📚 Learning: 2026-03-25T11:00:59.388Z
Learnt from: Cheezeiii365
Repo: Cheezeiii365/aIDE PR: 4
File: packages/renderer/src/components/FileTree/ContextMenu.tsx:16-20
Timestamp: 2026-03-25T11:00:59.388Z
Learning: Since aIDE does not support Windows, path-handling utilities and related code should assume POSIX-style separators (`/`) (e.g., helpers like `dirname`/`basename` that split on `/`). During review, do not require Windows-style backslash (`\\`) support or `path.sep`/cross-platform normalization unless the project explicitly adds Windows support.
Applied to files:
packages/renderer/src/components/layout/DockviewContainer.tsxpackages/renderer/src/components/panes/EditorPane.tsxpackages/renderer/src/lib/terminal/terminalState.tspackages/main/src/tasks/taskRunner.tspackages/renderer/src/components/panes/TerminalPane.tsxpackages/renderer/src/hooks/useTasks.tspackages/renderer/src/components/panes/ProblemsPane.tsxpackages/main/src/preload.tspackages/main/src/index.tspackages/renderer/src/components/layout/AppShell.tsxpackages/shared/src/index.ts
📚 Learning: 2026-03-29T20:00:59.299Z
Learnt from: CR
Repo: Cheezeiii365/aIDE PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-29T20:00:59.299Z
Learning: Applies to renderer/**/*terminal*.{ts,tsx} : Use xterm.js with node-pty for terminal implementation
Applied to files:
packages/renderer/src/lib/terminal/terminalState.tspackages/renderer/src/components/panes/TerminalPane.tsx
📚 Learning: 2026-03-29T20:00:59.300Z
Learnt from: CR
Repo: Cheezeiii365/aIDE PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-29T20:00:59.300Z
Learning: Always update IDE_BUILD_PLAN.md when making changes to the codebase
Applied to files:
docs/IDE_BUILD_PLAN.md
🔇 Additional comments (16)
.gitignore (1)
74-74: Good addition for workspace-local file.Ignoring
aide.code-workspaceis a solid change to avoid committing personal/editor workspace state.packages/renderer/src/components/layout/DockviewContainer.tsx (1)
16-32: Problems pane registration is wired cleanly.Adding it to the shared Dockview component map keeps pane creation and layout restore on the same path as the existing panes.
packages/renderer/src/components/panes/EditorPane.tsx (1)
136-143: Good spot for the file-save trigger.Keeping
notifyFileSaved()inside the successful write branch avoids firing save-triggered tasks after a failed disk write.tests/unit/app.test.tsx (1)
81-86: Window API mock stays in sync.Keeping these additions on the typed
WindowApimock preserves the compile-time contract check for renderer tests.packages/main/src/tasks/taskRunner.ts (1)
101-118: Nice to keep task-routing data onTaskExecution.Exposing both the running-task lookup and the presentation-derived fields from the runner lets callers stay
TaskExecution-driven instead of reopening task definitions to decide panel routing.Also applies to: 327-335
packages/renderer/src/styles/problems-pane.css (1)
1-127: Well-structured CSS with proper theming support.The stylesheet correctly uses CSS variables (
--text-primary,--bg-primary,--error, etc.) throughout for theming support. The BEM naming convention is consistent, and the fallback on line 105 (var(--info, var(--text-secondary))) is good defensive coding. The sticky file headers and text truncation with ellipsis are nice UX touches.packages/main/src/preload.ts (1)
192-228: Task system IPC extensions are correctly implemented.The new methods follow established patterns:
runTaskcorrectly forwards the optionalcontextparameter to the IPC handlernotifyFileSavedappropriately usessend(fire-and-forget) rather thaninvokeonTaskTriggerResultfollows the standard listener pattern with proper cleanuppackages/renderer/src/components/panes/ProblemsPane.tsx (2)
36-54: Efficient grouping and sorting implementation.The
useMemocorrectly groups diagnostics by file and sorts them by severity then line number. The dependency ondiagnosticsarray reference is appropriate.
66-119: Clean rendering with good accessibility.Using
<button>elements for clickable diagnostics is the right choice for keyboard accessibility. The empty state and severity icons provide clear visual feedback.packages/renderer/src/hooks/useTasks.ts (1)
75-90: Editor context gathering looks correct.The code properly extracts the active file path, selected text (or undefined if empty), and line number from the CodeMirror editor state. This aligns with the
TaskRunContextinterface and theActiveEditorStatetype from context snippet 4.packages/renderer/src/components/layout/AppShell.tsx (2)
298-370: Terminal routing for task executions is well-implemented.The panel policy logic (
shared/dedicated/new) correctly determines panel reuse. ThetaskTerminalMapRefproperly tracks execution-to-panel mappings for cleanup. The 500ms delay before closing on exit (line 363) is a nice touch to let users see final output.Minor: Line 360 checks
apiredundantly since it's already checked at line 302.
408-411: Diagnostics correctly cleared on workspace switch.This ensures stale diagnostics from a previous workspace don't persist when switching contexts.
packages/main/src/index.ts (1)
971-984: Task run context forwarding looks correct.The optional
contextparameter is properly destructured and forwarded to the task runner. The fields align with theTaskRunContextinterface.packages/shared/src/index.ts (3)
158-159: New IPC channels follow established conventions.The channel names
task:file-savedandtask:trigger-resultfollow the existingtask:*namespace pattern.
649-663: New task types are well-defined.
TaskRunContextcorrectly marks all fields as optional since the editor context may not always be availableTaskTriggerSourcecovers all trigger scenarios (workspaceOpen, fileSave, manual)TaskTriggerResultprovides complete outcome information including optional error message
769-779: WindowApi updates are consistent with implementations.The updated method signatures match the preload bridge and renderer usage:
runTaskaccepts optionalTaskRunContextnotifyFileSavedis fire-and-forget (void return)onTaskTriggerResultfollows the standard listener pattern
Capture workspaceActivationSeq at scheduling time in both scheduleWorkspaceOpenTasks and TASK_FILE_SAVED handlers. Delayed callbacks now no-op when the activation sequence has changed, preventing tasks from executing against a different workspace's runner after a switch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a shared/dedicated task terminal panel is reused for a new execution, updateParameters sets a new taskPtyId but the PTY I/O listeners were only wired on mount. Adds a useEffect that watches taskPtyId, tears down old listeners, and rebinds to the new PTY. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The early return on taskDiagnostics.length === 0 prevented the Problems panel from receiving an empty array after reruns or workspace switches, leaving stale errors visible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
initTaskRunner was made async but called without await, causing a race where workspace-open tasks might not be loaded before activation proceeds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Task panels with taskPtyId/taskExecutionId/taskId were being persisted alongside normal terminals. On restore they became orphaned shells since createRestoredTerminalPanelParams has no task metadata. Skip them in serializeTerminalState and in the activeTerminalId assignment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
taskRunner.tsfor executing and managing tasksProblemsPane.tsx) for displaying diagnostics with stylingTest plan
pnpm testto ensure new and existing unit tests pass🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation