Adds task lineage commit associations: a new API route stores and exposes which commits belong to which task, the `TaskChangesTab` surfaces these lineage links visually, and documentation covers the reconciliation model. Includes comprehensive tests for both the route and component.
Fusion-Task-Id: FN-3998
When a branch contained commits already on main (duplicate cherry-picks),
the merger's local squash collapsed to an empty commit. The merger then
recorded that empty commit's SHA on mergeDetails.commitSha. The actual
content landed later on main as a different SHA via PR merge, but the
task kept pointing at the orphaned empty commit.
Symptom: TaskCard showed "N files changed" (falling back to
task.modifiedFiles), but the Changes tab in the modal showed nothing
because the API hit `git diff sha^..sha` on the empty commit and
returned no files.
Two fixes:
1. merger.ts: detect empty squash commits and skip storing commitSha,
logging clearly. recoverInterruptedMergingTasks → findLandedTaskCommit
already exists to backfill the right SHA when the real commit lands;
a missing commitSha is a known fallback path the UI already handles.
2. TaskChangesTab.tsx: when the API returns no files for a done task,
fall back to task.modifiedFiles (paths only, no patches) with a clear
note. Mirrors the existing 3-tier fallback in TaskCard.tsx:1090-1124
so card and modal always agree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parallel subagent pass: four typescript-pro agents on non-overlapping scopes.
Patterns applied:
- catch (err: any) { ... err.message ... } → catch (err) { ... getErrorMessage(err) ... }
using the new @fusion/core helper. Bare catch {} where the error was unused.
- SQLite row types: defined typed XxxRow interfaces per table and cast
.all()/.get() results via `as unknown as XxxRow[]` (the double cast is
required because better-sqlite3 returns Record<string, SQLOutputValue>).
- rowToX(row: any) converters: typed argument with the matching row interface.
- Dynamic settings key writes: (settings as Record<string, unknown>)[key].
- React event handlers and setState callbacks: inferred types or concrete
React.{Mouse,Change,Form}Event<...> where needed.
- pi-claude-cli: local PiMessage / PiContext duck types to avoid re-typing
pi-ai concrete shapes; typed Claude stream event message fields.
72 files changed, ~400 anys eliminated. Typecheck passes across the workspace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Fix TaskChangesTab overcounting changes for done tasks by handling missing commit SHA gracefully
- Add /api/tasks/:id/diff endpoint with fallback for done tasks without merge commit info
- Add comprehensive tests for both TaskChangesTab component and diff route edge cases
- Document done-task Changes tab fallback behavior in README
- Add task-changes-file-list--compact CSS modifier class with tighter padding, gaps, and stat margins
- Apply compact modifier to TaskChangesTab file list container
- Add regression tests verifying compact class is present on TaskChangesTab and absent on CommitDiffTab
- Document compact spacing treatment in dashboard README
- Reflow Changes-tab header stats to a second line for better layout
- Add CSS styles for two-line header stats display
- Fix useTerminal hook to clear buffered scrollback after first subscriber replay
- Add tests for TaskChangesTab header stats rendering
- Update README description for Changes tab header
- Refactor TaskChangesTab actions header to use a two-row layout for better readability
- Add CSS for .changes-header-row-top and .changes-header-row-bottom styling
- Reorganize action buttons and filters across two rows with proper spacing
- Improve responsive behavior of the changes tab header actions
- Create ChangesDiffModal component with unified/split diff views, syntax highlighting, and file stats
- Add expand button to TaskChangesTab to open changes in full-screen modal
- Add comprehensive CSS styles for diff modal, line numbers, and responsive layout
- Add full test coverage for ChangesDiffModal (rendering, diff modes, navigation, keyboard shortcuts)
- Add expand button tests to TaskChangesTab test suite
- Add word wrap state and toggle button to TaskChangesTab component
- Add CSS styles for word wrap toggle in diff viewer
- Add tests for word wrap toggle functionality
- Add file navigation dropdown/keyboard support to the TaskChangesTab component
- Reduce horizontal margins in diff display for better readability
- Add comprehensive tests for file navigation behavior
- Include changeset for patch release
- Add truncatePath utility function with configurable segments and placeholder
- Apply middle truncation to file paths in ChangedFilesModal sidebar
- Apply middle truncation to file paths in TaskChangesTab
- Remove unused CSS truncation styles replaced by the new utility
- Add comprehensive test suite for truncatePath (106 tests)
- Server /tasks/:id/diff and /tasks/:id/file-diffs now both use
resolveDiffBase() for consistent file lists across card and modal
- Both endpoints handle done tasks via mergeDetails.commitSha,
returning structured { files, stats } from the merge commit
- TaskChangesTab uses fetchTaskDiff for all columns (no more
fetchCommitDiff/parsePatch client-side path for done tasks)
- useChangedFiles hook simplified — server handles done tasks
- Done task cards show "N files changed" button using mergeDetails
- Updated tests for new unified data flow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add theme-aware CSS classes for changed-file status badges (added, modified, deleted, renamed)
- Update ChangedFilesModal, CommitDiffTab, and TaskChangesTab to use theme-aware status classes
- Add comprehensive tests for ChangedFilesModal and TaskChangesTab status styling
- Refactor stuck-task-detector to extract StuckTaskConfig and simplify detection logic
- Clean up 370+ lines of redundant test code in stuck-task-detector tests
- Update dashboard README with theme-aware styling notes
- Pass throughChangedFiles option in executor for better diff handling
- Refactor TaskChangesTab to use merge commit diff for done/archived tasks instead of branch diff
- Add CommitDiffTab component integration for displaying merge commit changes
- Remove legacy API endpoints and tests for branch-based diff on completed tasks
- Add comprehensive test suite for TaskChangesTab covering all task lifecycle states
- Document merge commit diff behavior in dashboard README
- Add highlightDiff utility React component for diff rendering
- Add CSS styles for diff-add (green), diff-del (red), diff-hunk (blue) line highlighting
- Integrate highlightDiff in TaskChangesTab for inline diffs
- Integrate highlightDiff in ChangedFilesModal for file diffs
- Add unit tests for highlightDiff utility
fix: update scheduler filesystem path from .kb to .fusion for task validation
style: clean up TaskDetailModal styling with reusable CSS classes
test: add comprehensive tests for file-service operations with mocked filesystem
- Add baseCommitSha field to tasks for diff computation baseline
- Track modified files in executor and store in database
- Add /api/tasks/:id/diff endpoint to serve unified diffs
- Add getTaskDiff() API client function in dashboard
- Create TaskChangesTab component with file list and diff viewer
- Integrate Changes tab into TaskDetailModal with proper styling
- Add changeset for the new diff viewer feature