Skip to content

feat: task runner and problems pane#60

Merged
Cheezeiii365 merged 7 commits into
mainfrom
taskparity
Mar 30, 2026
Merged

feat: task runner and problems pane#60
Cheezeiii365 merged 7 commits into
mainfrom
taskparity

Conversation

@Cheezeiii365
Copy link
Copy Markdown
Owner

@Cheezeiii365 Cheezeiii365 commented Mar 30, 2026

Summary

  • Add functional task runner system with taskRunner.ts for executing and managing tasks
  • Implement Problems pane (ProblemsPane.tsx) for displaying diagnostics with styling
  • Extend AppShell, terminal, and shared types to support task parity features
  • Add unit tests for the task runner

Test plan

  • Verify task runner executes and reports task status correctly
  • Confirm Problems pane renders diagnostics from tasks
  • Run pnpm test to ensure new and existing unit tests pass
  • Test terminal integration with task output

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Tasks auto-run on workspace open and on file save; run requests can include editor context.
    • Task trigger notifications indicate started, skipped, or failed outcomes.
    • Problems pane added to view task diagnostics with severity grouping and file-navigation.
    • Terminals can attach to task-owned processes and panels may be shared, dedicated, or new (auto-close on success).
  • Documentation

    • Build plan updated; new multi-workspace notes added.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 47a4cbba-9159-4be5-82a0-54cb04869828

📥 Commits

Reviewing files that changed from the base of the PR and between 20fb544 and bd391bf.

📒 Files selected for processing (5)
  • docs/multiwork.md
  • packages/main/src/index.ts
  • packages/renderer/src/components/layout/AppShell.tsx
  • packages/renderer/src/components/panes/TerminalPane.tsx
  • packages/renderer/src/lib/terminal/terminalState.ts

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Configuration & Docs
/.gitignore, docs/IDE_BUILD_PLAN.md
Added VS Code ignore entries; marked Phase 4 task-runner milestones and documented run triggers, terminal routing, and editor-context behavior.
Shared Types & Preload Bridge
packages/shared/src/index.ts, packages/main/src/preload.ts
Added TASK_FILE_SAVED and TASK_TRIGGER_RESULT channels; introduced TaskRunContext, TaskTriggerResult, TaskTriggerSource; extended TaskExecution with panelPolicy and closeOnExit; updated WindowApi with runTask(..., context?), notifyFileSaved, and onTaskTriggerResult.
Main: IPC & Task Scheduling
packages/main/src/index.ts
Made initTaskRunner async; added workspace-open scheduling with singleton guard and delayed per-task scheduling; extended TASK_RUN handler to accept optional TaskRunContext; added TASK_FILE_SAVED listener that resolves file-save tasks, respects delays, skips already-running tasks, and emits TASK_TRIGGER_RESULT.
Main: Task Runner Enhancements
packages/main/src/tasks/taskRunner.ts
Added isTaskRunning() and getRunningExecutionByTaskId(); include panelPolicy and closeOnExit on TaskExecution instances.
Renderer: Hooks & State
packages/renderer/src/hooks/useTasks.ts, packages/renderer/src/lib/terminal/terminalState.ts
Added diagnostics state and clear actions; subscribe to task diagnostics and clear per-task diagnostics on run; capture active editor context (file, selection, line) and pass as TaskRunContext; added optional taskPtyId, taskExecutionId, taskId to terminal params and exclude task-bound terminals from serialized layout.
Renderer: Layout & Panels
packages/renderer/src/components/layout/AppShell.tsx, packages/renderer/src/components/layout/DockviewContainer.tsx
Subscribed to task status and trigger-result events to create/reuse Dockview terminal panels by panelPolicy, schedule closure for closeOnExit/new panels, show failed-trigger toasts, keep Problems pane in sync, and registered ProblemsPane in Dockview components.
Renderer: Panes & Terminal
packages/renderer/src/components/panes/EditorPane.tsx, packages/renderer/src/components/panes/TerminalPane.tsx, packages/renderer/src/components/panes/ProblemsPane.tsx
On editor save, notify main of saved file; TerminalPane can attach to task-owned PTYs (rebinds on PTY id change) and uses disposable refs for cleanup; added ProblemsPane component that groups/sorts diagnostics by file and severity and opens files on click.
Renderer: Styles
packages/renderer/src/styles/problems-pane.css
New stylesheet for Problems pane layout, empty state, grouped lists, sticky headers, severity indicators, and item styles.
Tests
tests/unit/app.test.tsx, tests/unit/taskRunner.test.ts
Updated WindowApi test mock with new methods; added unit tests validating new IPC channel constants and structural type shapes for TaskRunContext, TaskTriggerResult, and TaskExecution.

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)
Loading
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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 I bounced through code with nimble paws,

Workspace opens, tasks obey the laws.
Saved a file — a trigger hops to life,
Terminals gather, problems filed in sight.
A rabbit cheers: diagnostics take flight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: task runner and problems pane' clearly identifies the two main deliverables of the changeset: implementing a task runner system and a problems pane UI component.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taskparity

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread packages/main/src/index.ts Outdated
Comment thread packages/renderer/src/components/layout/AppShell.tsx
Comment thread packages/renderer/src/components/layout/AppShell.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(), or panelPolicy / closeOnExit propagation would still pass. I'd add at least one behavioral test around a real TaskRunner instance 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 errorCount and warningCount each iterate the full diagnostics array. For large diagnostic lists, combining into a single useMemo would 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 inside setRunningTasks callback.

Calling setDiagnostics inside the setRunningTasks updater function (line 50) works in practice due to React 18+ automatic batching, but it's unconventional. The setDiagnostics call doesn't depend on prev from setRunningTasks, 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: Missing skipped result emission for file-save triggered tasks.

Unlike scheduleWorkspaceOpenTasks (lines 929-940), the TASK_FILE_SAVED handler silently skips already-running tasks (line 1016) without emitting a TaskTriggerResult. For consistency and observability, consider emitting a skipped result.

♻️ 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"), the ProblemsPane component 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4b4a0e5 and 20fb544.

📒 Files selected for processing (16)
  • .gitignore
  • docs/IDE_BUILD_PLAN.md
  • packages/main/src/index.ts
  • packages/main/src/preload.ts
  • packages/main/src/tasks/taskRunner.ts
  • packages/renderer/src/components/layout/AppShell.tsx
  • packages/renderer/src/components/layout/DockviewContainer.tsx
  • packages/renderer/src/components/panes/EditorPane.tsx
  • packages/renderer/src/components/panes/ProblemsPane.tsx
  • packages/renderer/src/components/panes/TerminalPane.tsx
  • packages/renderer/src/hooks/useTasks.ts
  • packages/renderer/src/lib/terminal/terminalState.ts
  • packages/renderer/src/styles/problems-pane.css
  • packages/shared/src/index.ts
  • tests/unit/app.test.tsx
  • tests/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-theme attribute for theming, supporting dark and light mode

Files:

  • packages/renderer/src/components/layout/DockviewContainer.tsx
  • tests/unit/app.test.tsx
  • packages/renderer/src/components/panes/EditorPane.tsx
  • packages/renderer/src/styles/problems-pane.css
  • packages/renderer/src/components/panes/TerminalPane.tsx
  • packages/renderer/src/components/panes/ProblemsPane.tsx
  • packages/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.tsx
  • tests/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.tsx
  • packages/renderer/src/components/panes/TerminalPane.tsx
  • packages/renderer/src/components/panes/ProblemsPane.tsx
  • packages/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.tsx
  • packages/renderer/src/components/panes/EditorPane.tsx
  • packages/renderer/src/lib/terminal/terminalState.ts
  • packages/main/src/tasks/taskRunner.ts
  • packages/renderer/src/components/panes/TerminalPane.tsx
  • packages/renderer/src/hooks/useTasks.ts
  • packages/renderer/src/components/panes/ProblemsPane.tsx
  • packages/main/src/preload.ts
  • packages/main/src/index.ts
  • packages/renderer/src/components/layout/AppShell.tsx
  • packages/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.ts
  • packages/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-workspace is 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 WindowApi mock preserves the compile-time contract check for renderer tests.

packages/main/src/tasks/taskRunner.ts (1)

101-118: Nice to keep task-routing data on TaskExecution.

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:

  • runTask correctly forwards the optional context parameter to the IPC handler
  • notifyFileSaved appropriately uses send (fire-and-forget) rather than invoke
  • onTaskTriggerResult follows the standard listener pattern with proper cleanup
packages/renderer/src/components/panes/ProblemsPane.tsx (2)

36-54: Efficient grouping and sorting implementation.

The useMemo correctly groups diagnostics by file and sorts them by severity then line number. The dependency on diagnostics array 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 TaskRunContext interface and the ActiveEditorState type 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. The taskTerminalMapRef properly 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 api redundantly 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 context parameter is properly destructured and forwarded to the task runner. The fields align with the TaskRunContext interface.

packages/shared/src/index.ts (3)

158-159: New IPC channels follow established conventions.

The channel names task:file-saved and task:trigger-result follow the existing task:* namespace pattern.


649-663: New task types are well-defined.

  • TaskRunContext correctly marks all fields as optional since the editor context may not always be available
  • TaskTriggerSource covers all trigger scenarios (workspaceOpen, fileSave, manual)
  • TaskTriggerResult provides 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:

  • runTask accepts optional TaskRunContext
  • notifyFileSaved is fire-and-forget (void return)
  • onTaskTriggerResult follows the standard listener pattern

Comment thread packages/main/src/index.ts
Comment thread packages/renderer/src/components/panes/TerminalPane.tsx
Comment thread packages/renderer/src/lib/terminal/terminalState.ts
Cheezeiii365 and others added 5 commits March 30, 2026 09:12
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>
@Cheezeiii365 Cheezeiii365 merged commit 761575b into main Mar 30, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant