Commit Graph

615 Commits

Author SHA1 Message Date
gsxdsm
d893a026df FN-7971: hide GitLab import tab when GitLab is disabled
Hide the Import Tasks GitLab provider affordance when gitlabEnabled is off, coerce restored GitLab state to GitHub, and document the behavior.

- Gate GitLab provider tab visibility on effective gitlabEnabled and wait for settings before replaying persisted GitLab auto-load
- Coerce disabled GitLab provider preference to GitHub without firing GitLab fetch/import requests
- Cover hide/show/coerce paths in GitHubImportModal tests and update dashboard guide copy
- Add patch changeset for the published package

Files changed:
 .changeset/fn-7971-hide-gitlab-when-disabled.md    |  7 +++
 docs/dashboard-guide.md                            |  4 +-
 .../dashboard/app/components/GitHubImportModal.tsx | 27 ++++++++--
 .../__tests__/GitHubImportModal.test.tsx           | 62 +++++++++++++++++++---
 4 files changed, 88 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7971

Fusion-Task-Lineage: e645a4a7-85e0-4635-8dad-f5839390e5c5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-15 12:47:14 -07:00
gsxdsm
bc2d22df6e feat(dashboard): offer AI translation in Import Tasks preview (#2128)
## Summary

Import Tasks can now offer on-demand AI translation when a selected
GitHub or GitLab issue/PR title and body appear to be in a different
language than the active dashboard locale.

- Detect foreign-language content with a conservative client heuristic
(Unicode scripts + Latin stopwords)
- Show an opt-in banner: **Translate**, then **Show original / Show
translation**, plus **Dismiss**
- Call new `POST /api/ai/translate-text` (shared AI-helper rate limit
with refine/draft)
- Translation is **display-only** in the preview; imported task text
stays the original source language

## Why

Operators working in a non-English dashboard (or reading
non-dashboard-language issues) needed a way to understand import
candidates without leaving the preview or changing what gets imported.

## Test plan

- [x] Unit tests for language detection (`detectContentLanguage`)
- [x] Unit tests for translate request validation, response parsing, and
AI agent path
- [x] GitHub import modal: French content shows translate controls;
English content does not
- [x] Dashboard typecheck clean for app + server packages
- [ ] Manual: open Import Tasks with dashboard language English, select
a French/Korean issue, translate and toggle original
- [ ] Manual: confirm Import still creates the task with original
title/body
- [ ] Manual: dismiss banner for a selection and confirm it stays
dismissed for that item

## Notes

- Comments are not translated (title + body only)
- zh-CN / zh-TW share a CJK family so Chinese content does not prompt
translation when the UI is either Chinese locale
- Secondary locale catalogs have empty placeholders for the new
`git.translate*` keys (runtime falls back to English)
2026-07-15 02:18:43 -07:00
gsxdsm
a242f1b449 fix(FN-7952): migrate bundled plugins to PostgreSQL (#2111)
## Summary

Bundled plugins now persist shared runtime state in project-scoped
PostgreSQL tables instead of maintaining independent SQLite authority.
Reports, CLI Printing Press, Compound Engineering, Roadmap, Even
Realities, and WhatsApp all follow the same ownership and startup
contract as Fusion core.

## Design decisions

- Plugin schema hooks run through the host’s PostgreSQL owner and
enforce project isolation.
- The SDK exposes the host contract needed by bundled plugins without
importing engine internals.
- Legacy Roadmap ownership fixtures use the supported empty-owner
sentinel, preserving current composite primary/foreign keys while
exercising backfill behavior.
- The lockfile travels with the Even Realities PostgreSQL dependency so
packaged installs remain reproducible.

## Validation

- All six affected plugin builds pass.
- Affected plugin suites pass: 773 tests across Printing Press, Compound
Engineering, Even Realities, Reports, Roadmap, and WhatsApp.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 40 files.

## Stack

- Depends on #2110 → #2109 → #2108.
- The documentation/release PR completes the stack.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Breaking Changes**
* PostgreSQL is now required for runtime storage; SQLite files are used
only as one-time migration inputs.
  * The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed.

* **New Features**
* Added project-isolated PostgreSQL storage for plugins, reports, tasks,
notifications, and other plugin data.
  * Added agent tools for reports and CLI service drafts.
  * Added PostgreSQL schema initialization support for plugin authors.

* **Bug Fixes**
  * Improved migration and recovery of legacy plugin state.
* Prevented cross-project data access and strengthened transactional
schema updates.

* **Documentation**
* Updated storage, migration, deployment, plugin authoring, CLI, and
dashboard guidance for PostgreSQL.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 00:27:59 -07:00
gsxdsm
03966ecb79 Fix multi-project branch-group route store scoping (#2085)
## Summary

Conflict resolution for closed
[#2074](https://github.com/Runfusion/Fusion/pull/2074) (FN-001
multi-project branch-group store scoping), rebased onto current `main`.

#2074 closed when its fork head was briefly reset to `main` during a ref
update; maintainer write access to the fork head only works while the PR
is open, so that PR could not be reopened without new fork commits.

This branch carries the same fix:

- Request-scoped `TaskStore` for branch-group
list/read/assign/promote/abandon
- Integrated reconcile/close uses the request store for cwd +
persistence
- Compatible with async branch-group store APIs and main’s
CentralProjectIdentity (`projectId` trim)
- Postgres durable FN-7438 tests + padded `projectId` regression

## Verification

- `FUSION_DASHBOARD_DEEP=1 pnpm --filter @fusion/dashboard exec vitest
run --project dashboard-api src/__tests__/routes-branch-groups.test.ts
src/__tests__/integrated-routers-group-pr-token.test.ts
src/__tests__/routes-context-project-identity.test.ts
--silent=passed-only --reporter=dot` — 3 files, 41 tests passed.

---------

Co-authored-by: Tchorizo <295840812+Tchorizo@users.noreply.github.com>
Co-authored-by: Fusion <noreply@runfusion.ai>
2026-07-14 00:12:22 -07:00
gsxdsm
4e7e013d6f FN-7947: add Plan action to context menu for pre-execution task cards
Adds a Plan action to Board/List task context menus so triage/hold/intake cards can jump straight into Planning Mode without duplicating a task.

- Add `onPlan` handler and `isPreExecutionHoldColumn` gate to `TaskContextMenu` so Plan only appears for pre-execution (triage/intake/hold) columns, and only when a host wires the handler
- Wire the Plan action through `Board.tsx`, `Column.tsx`, `ListView.tsx`, and `WorktreeGroup.tsx` so both board and list views expose the new menu item
- Surface the Plan entry point on `TaskCard.tsx`
- Add test coverage in `TaskContextMenu.test.tsx`, `TaskCard.test.tsx`, and `ListView.test.tsx` for the new gating/wiring behavior
- Document the new action in `docs/dashboard-guide.md`
- Add a minor changeset for `@runfusion/fusion`

Files changed:
 .changeset/fn-7947-plan-context-menu-action.md     |  7 ++
 docs/dashboard-guide.md                            | 10 ++-
 packages/dashboard/app/components/Board.tsx        | 10 ++-
 packages/dashboard/app/components/Column.tsx       |  4 +
 packages/dashboard/app/components/ListView.tsx     | 15 +++-
 packages/dashboard/app/components/TaskCard.tsx     | 24 +++++-
 packages/dashboard/app/components/TaskContextMenu.tsx   | 18 ++++
 packages/dashboard/app/components/WorktreeGroup.tsx     |  9 ++
 packages/dashboard/app/components/__tests__/ListView.test.tsx     | 21 +++++
 packages/dashboard/app/components/__tests__/TaskCard.test.tsx     | 96 ++++++++++++++++++++++
 packages/dashboard/app/components/__tests__/TaskContextMenu.test.tsx  | 32 ++++++++
 11 files changed, 236 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-7947

Fusion-Task-Lineage: 41c759a2-e76b-4771-9421-c9805c4596e5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 10:14:22 -07:00
gsxdsm
7cc622bed2 FN-7946: auto-retry stuck Planning Mode AI generation up to 3 times
Planning Mode now automatically retries a stuck or terminally-errored AI
generation session up to three times before falling back to the permanent
Retry/Dismiss error panel, reducing manual retries for transient failures.

- Add a bounded (MAX_PLANNING_AUTO_RETRIES = 3) client-side auto-retry that
  reuses the existing /planning/:id/retry endpoint whenever the SSE stream's
  onError, a session reload, or the stuck-session poll observes a terminal
  "error" status.
- Track the retry budget in refs (planningAutoRetryAttemptRef,
  planningAutoRetryInFlightRef) so async SSE/poll/loadSession handlers share
  a single in-flight guard, with the current attempt mirrored into state
  (isAutoRetrying/autoRetryAttempt) for the UI.
- Reset the retry budget whenever the session makes real progress (reaches
  a new question or a completed summary), and surface the permanent
  Retry/Dismiss error view once the budget is exhausted.
- Show a "Retrying... (attempt N of 3)" loading message while an automatic
  retry is in flight, distinct from the manual Retry button state.
- Fix a stuck-poll edge case where a terminal error discovered only by the
  poll (missed SSE event) after the auto-retry budget was exhausted left
  the modal spinning on "Generating next question..." forever instead of
  showing the error view.
- Document the new auto-retry behavior in docs/dashboard-guide.md and add a
  minor changeset for @runfusion/fusion.
- Extend PlanningModeModal.planning-flow.test.tsx with coverage for the
  auto-retry budget, single-flight behavior, and the poll-discovered
  terminal-error fallback.

Files changed:
 .changeset/fn-7946-planning-auto-retry.md          |   7 +
 docs/dashboard-guide.md                            |   3 +
 .../dashboard/app/components/PlanningModeModal.tsx | 339 ++++++++++++++------
 .../PlanningModeModal.planning-flow.test.tsx       | 353 ++++++++++++++++++---
 4 files changed, 567 insertions(+), 135 deletions(-)

Fusion-Task-Id: FN-7946
Fusion-Task-Lineage: 42e911dc-9639-46ab-bb4f-bc9060413140
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 09:50:48 -07:00
gsxdsm
f0888d43c3 FN-7945: route List-view task opens through the movable popup when Open tasks as popups is on
Extends the existing board/right-dock "Open tasks as popups" routing so ordinary List row/card and keyboard opens use the same shared movable/resizable FloatingWindow instead of the docked split-pane/mobile detail.

- Add openMobileTasksInPopup prop to ListView, threaded through App -> MainContent -> ListView (dashboard/types.ts)
- handleRowClick routes to onPopOut (popOutTaskDetail) when the setting is on, on both desktop split-pane and mobile/tablet single-pane; docked behavior is preserved when the setting is off
- Restore Enter/Space keyboard activation on list rows to invoke the same handleRowClick path, alongside existing context-menu key handling
- Update docs/dashboard-guide.md and docs/settings-reference.md to describe List row/card opens as part of the popup routing surface, and refresh the Appearance settings help copy/FNXC comment accordingly
- Add changeset (.changeset/fn-7945-list-view-task-popup.md, minor) describing the user-facing behavior
- Extend ListView.test.tsx coverage for the new popup routing and restored keyboard activation

Files changed:
 .changeset/fn-7945-list-view-task-popup.md         |  7 ++
 docs/dashboard-guide.md                            |  4 +-
 docs/settings-reference.md                         |  2 +-
 packages/dashboard/app/App.tsx                     |  1 +
 packages/dashboard/app/components/ListView.tsx     | 48 +++++++++----
 .../app/components/__tests__/ListView.test.tsx     | 80 +++++++++++++++++++++-
 .../app/components/dashboard/MainContent.tsx       |  2 +
 .../dashboard/app/components/dashboard/types.ts    |  1 +
 .../settings/sections/AppearanceSection.tsx        |  4 +-
 9 files changed, 127 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-7945

Fusion-Task-Lineage: 784cb4ee-c493-4ace-bf8b-0e3dbaaef9a3

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 09:27:29 -07:00
gsxdsm
7246df22f6 FN-7944: add setting to keep task popups attached to their Board/List view
Adds an opt-in project setting so open task-detail popups stay attached to the Board or List view where they were opened, instead of floating over every main-content view.

- New project setting taskPopupsBoardListOnly (default: off) in settings-schema.ts and ProjectSettings type, with default preserved via settings-defaults tests.
- usePoppedOutTasks now stores each popup's originating TaskView alongside its task snapshot (PoppedOutTaskEntry), keeping legacy tasks output for existing callers.
- App.tsx adds isTaskPopupVisibleForView() gating helper and filters popped-out entries to the current view for rendering/keyboard-close handling, while hidden popups remain mounted in hook state (not cleared) so switching back to the originating view restores them with shared persisted geometry.
- Settings -> Appearance gets a new "Keep task popups on their Board/List view" checkbox (AppearanceSection.tsx) with i18n strings and updated settings search text in SettingsModal.
- Documentation updated in docs/dashboard-guide.md and docs/settings-reference.md to describe the render-only hide/restore behavior.
- New/updated tests: App.taskPopupViewGating.test.tsx, usePoppedOutTasks.test.ts, AppearanceSection.test.tsx, settings-default-descriptions.test.tsx, settings-defaults.test.ts.

Files changed:
 docs/dashboard-guide.md                            |   5 +-
 docs/settings-reference.md                         |   1 +
 .../core/src/__tests__/settings-defaults.test.ts   |  13 +++
 packages/core/src/settings-schema.ts               |   5 +
 packages/core/src/types.ts                         |   7 ++
 packages/dashboard/app/App.tsx                     |  49 +++++++--
 .../app/__tests__/App.taskPopupViewGating.test.tsx | 113 +++++++++++++++++++++
 .../dashboard/app/components/SettingsModal.tsx     |   3 +-
 .../settings/sections/AppearanceSection.tsx        |   8 ++
 .../sections/__tests__/AppearanceSection.test.tsx  |  21 ++++
 .../settings-default-descriptions.test.tsx         |   1 +
 .../app/hooks/__tests__/usePoppedOutTasks.test.ts  |  14 +++
 packages/dashboard/app/hooks/useAppSettings.ts     |   4 +
 packages/dashboard/app/hooks/usePoppedOutTasks.ts  |  27 +++--
 packages/i18n/locales/en/app.json                  |   2 +
 15 files changed, 255 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7944
Fusion-Task-Lineage: 4b8ced0e-1853-429f-8482-163821a35ae6
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 08:58:51 -07:00
gsxdsm
6b78633b07 FN-7943: keep Quick Chat open when portaled model/thinking-level dropdowns are clicked
Quick Chat's outside-pointer dismissal now recognizes body-portaled dropdown menus (model, thinking-level, agent, dependency, node, priority) as part of the panel instead of treating them as outside clicks.

- Extend FloatingWindow's outside-pointerdown safe-surface selector to include the portaled dropdown classes used by model combobox, model nested menu, dependency, node picker, agent picker, and priority picker menus
- Add regression tests covering pointerdown on each portaled dropdown surface and on a child element inside a portaled dropdown, asserting onClose is not called
- Update dashboard-guide docs to describe that these portal dropdowns are treated as part of the Quick Chat panel for outside-click purposes

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/FloatingWindow.tsx    | 19 +++++++-
 .../components/__tests__/FloatingWindow.test.tsx   | 50 ++++++++++++++++++++++
 3 files changed, 69 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7943

Fusion-Task-Lineage: fa91bd43-241c-48b0-8858-16521f383784

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 08:15:25 -07:00
gsxdsm
d4001ab0ee feat: make merger AI model configurable under Global and Project Models
Add a dedicated merger model lane (project + global provider/model/thinking) so merge-agent sessions no longer share only the default model, without inheriting executor/planner/reviewer lanes.
2026-07-13 08:10:56 -07:00
gsxdsm
1f9dcea4b6 FN-7935: route mailbox artifact View task to the popped-out task-detail window
Mailbox artifact "View task" now opens the producing task in the same shared, movable/resizable floating task-detail window used elsewhere in the dashboard, instead of the docked task-detail modal.

- MainContent's MailboxView onOpenTask handler now calls popOutTaskDetail(task) after fetchTaskDetail resolves, instead of openDetailTask(task), matching DocumentsView's artifact-task open path
- add regression test verifying mailbox artifact "View task" clicks resolve the task and route to popOutTaskDetail (not openDetailTask)
- update docs/dashboard-guide.md to describe the shared movable/resizable task-detail window behavior
- add changeset (patch) documenting the fix for @runfusion/fusion

Files changed:
 .changeset/fn-7935-mailbox-artifact-view-task-popout.md                        |  7 ++
 docs/dashboard-guide.md                                                        |  2 +-
 packages/dashboard/app/components/dashboard/MainContent.tsx                    |  8 ++-
 .../MainContent.mailbox-view-task.test.tsx                                     | 83 ++++++++++++++++++++++
 4 files changed, 97 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7935

Fusion-Task-Lineage: 51374962-aa36-4390-a6b5-b519e7fc2bf2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 00:50:30 -07:00
gsxdsm
29560021d3 FN-7934: fix chat brain popup clipping in narrow floating windows
Fixes the in-chat model/thinking (Brain) popup being cut off inside a narrow floating Chat window or compact dock on a wide desktop viewport.

- Key the popover's viewport-fitting inset layout on ChatView's .chat-view--narrow class (chat surface width) instead of only the @media (max-width: 768px) browser-viewport query, so narrow floating/docked chat surfaces get the fitted layout too.
- Add narrow-surface CSS rules for .chat-thinking-level-root, .chat-thinking-popover, .chat-thinking-agent-list, and .chat-thinking-popover-list to constrain position/width/max-height to the chat surface.
- Add a CSS-contract regression test asserting both the desktop popover sizing and the new narrow-surface rules stay in sync.
- Update docs/dashboard-guide.md to describe the popup staying fitted to the chat surface for narrow floating Chat windows/compact docks, not just mobile/tablet viewports.
- Add a patch changeset for @runfusion/fusion documenting the fix.

Files changed:
 .changeset/fn-7934-chat-narrow-model-popup.md      |  7 +++++
 docs/dashboard-guide.md                            |  3 +-
 packages/dashboard/app/components/ChatView.css     | 22 +++++++++++++++
 .../__tests__/ChatThinkingLevelControl.test.tsx    | 32 ++++++++++++++++++++++
 4 files changed, 63 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7934

Fusion-Task-Lineage: 30c461c5-a153-4005-8a8c-24f02916a934

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 00:48:02 -07:00
gsxdsm
9ba8a2e575 FN-7932: add per-lane Reviewer and Planning thinking-level overrides
Adds validatorThinkingLevel and planningThinkingLevel task fields so the Reviewer and Planning AI lanes can override reasoning effort independently of the shared task thinkingLevel, with dashboard UI, storage, and runtime fallback wiring.

- Add validatorThinkingLevel and planningThinkingLevel to Task/TaskCreateInput types (packages/core/src/types.ts)
- Persist the new fields in the SQLite schema and store read/write/replication paths (packages/core/src/db.ts, store.ts, mesh-task-replication.ts)
- Wire executor and triage lanes to fall back per-lane thinking level -> task.thinkingLevel -> existing settings/lane fallback (packages/engine/src/executor.ts, triage.ts)
- Add per-lane thinking-level selectors to the ModelSelectorTab UI, alongside the existing thinking-level control (packages/dashboard/app/components/ModelSelectorTab.tsx)
- Expose the new fields through the legacy task API and task-workflow routes (packages/dashboard/app/api/legacy.ts, packages/dashboard/src/routes/register-task-workflow-routes.ts)
- Document the new settings in dashboard-guide.md and settings-reference.md
- Add a minor changeset and unit/integration test coverage for store persistence, routes, UI, and agent-session helpers

Files changed:
 .changeset/per-lane-task-thinking.md               |   7 ++
 docs/dashboard-guide.md                            |   2 +
 docs/settings-reference.md                         |   2 +-
 .../src/__tests__/store-thinking-levels.test.ts    |  43 +++++++
 packages/core/src/db.ts                            |  15 ++-
 packages/core/src/mesh-task-replication.ts         |   4 +
 packages/core/src/store.ts                         |  24 +++-
 packages/core/src/types.ts                         |  12 ++
 packages/dashboard/app/api/legacy.ts               |   2 +
 .../dashboard/app/components/ModelSelectorTab.tsx  | 126 ++++++++++++++++++++-
 .../components/__tests__/ModelSelectorTab.test.tsx |  50 +++++++-
 .../src/__tests__/routes-tasks-ops.test.ts         |  74 ++++++++++++
 .../src/routes/register-task-workflow-routes.ts    |  19 +++-
 .../src/__tests__/agent-session-helpers.test.ts    |  15 +++
 packages/engine/src/executor.ts                    |  16 ++-
 packages/engine/src/triage.ts                      |   8 +-
 16 files changed, 395 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-7932

Fusion-Task-Lineage: 4202f774-aab9-41d2-86a0-f5277dd0f848

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 00:44:59 -07:00
gsxdsm
967f3dd900 FN-7923: align task-card cost badge bottom-right with other footer chips
Narrative: Reworked TaskCard footer/meta layout so the cost badge (and its sibling footer-right chips) render inline at the bottom-right of the card-meta row when the footer has no leading content, instead of always sitting in a separate footer row beside the time badge.

- Extracted the footer-right chip cluster (cost, time, retry, near-duplicate, undo-of, GitHub tracking) into a shared `footerRightCluster` render, computed once instead of duplicated inline.
- Added `footerHasLeadingContent`/`footerRightHasContent`/`placeFooterRightInMeta` derivations so the cluster moves into `.card-meta` (bottom-right, inline with other tags) when there's no files-changed button or GitHub-import leading content, and the meta row is visible; otherwise it keeps the existing `.card-footer-row` placement for in-progress/tracked cards.
- Updated dashboard-guide.md wording to describe the cost badge as appearing 'with the card's other footer/meta chips' rather than 'beside the execution-time badge'.
- Extended TaskCard.test.tsx coverage for the new placement behavior.
- Desktop local-runtime.ts: kept the previously-unused `reason` parameter on `requestRestart` explicitly referenced (void reason) for API parity/lint cleanliness, unrelated cosmetic cleanup carried in the same branch.

Files changed:
 docs/dashboard-guide.md                            |   2 +-
 packages/dashboard/app/components/TaskCard.tsx     | 242 +++++++++++----------
 .../app/components/__tests__/TaskCard.test.tsx     |  96 +++++++-
 packages/desktop/src/local-runtime.ts              |   4 +-
 4 files changed, 222 insertions(+), 122 deletions(-)

Fusion-Task-Id: FN-7923

Fusion-Task-Lineage: 7e4c3109-f39e-45c0-af13-358ce54f945c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 23:56:13 -07:00
gsxdsm
30d2e3660d FN-7927: fix Refine feedback modal self-dismissing immediately after opening
The task-detail Refine overlay used a raw onClick backdrop handler with a stopPropagation-wrapped inner modal, so the same click/touch sequence that opened Refine could bubble into the backdrop handler and close it right away; route it through the shared useOverlayDismiss contract instead so it behaves like every other dashboard modal.

- Compute refineOverlayDismissProps via useOverlayDismiss(handleCloseRefineModal) and spread it onto the refine overlay instead of a plain onClick handler
- Drop the redundant stopPropagation-only onClick from the inner .detail-refine-modal div now that the overlay itself no longer misfires on the opening interaction
- Update docs/dashboard-guide.md to document that the Refine modal (Board and List entry points) stays open until an explicit close or an enabled backdrop dismissal
- Add TaskDetailModal.refine.test.tsx regression coverage for the modal staying open across the opening interaction and honoring the dismiss-preference gate
- Add a patch changeset summarizing the fix for @runfusion/fusion release notes

Files changed:
 .changeset/fn-7927-refine-modal.md                 |   7 +
 docs/dashboard-guide.md                            |   8 +-
 .../dashboard/app/components/TaskDetailModal.tsx   |  12 +-
 .../__tests__/TaskDetailModal.refine.test.tsx      | 182 +++++++++++++++++++++
 4 files changed, 201 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7927

Fusion-Task-Lineage: c7e7cd4a-d103-47e6-93ce-6577147b4795

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 23:37:54 -07:00
gsxdsm
e84fda936a FN-7918: make chat go-to-top contextual and inline edit pencil compact
Reworks chat message footer affordances: the scroll-to-top control now only becomes visible once a message's top is actually clipped above the visible thread viewport, and the edit pencil moves from a standalone action row into the timestamp footer beside user messages.

- ChatView measures assistant message tops on scroll/message changes (rAF-scheduled) and tracks which message IDs are currently clipped above the `.chat-messages` container edge
- StandardChatMessageItem accepts a new `isTopClipped` prop; the go-to-top button stays DOM-mounted (for tests/a11y) but is visually hidden via CSS until clipped
- Merged the assistant thinking/copy/scroll-to-top actions into a single collapsible footer row instead of separate action rows
- Moved the user-message edit pencil into an inline `chat-message-time-row` next to the relative timestamp instead of a standalone action row above it
- Updated ChatView.css for the new inline layout, collapsed-row state, and hidden/visible scroll-to-top button states
- Updated message-edit and scroll-to-top tests to cover the new inline placement and clipped-visibility behavior
- Added changeset and docs/dashboard-guide.md note describing the new behavior

Files changed:
 .changeset/fn-7918-chat-inline-icons.md            |  7 ++
 docs/dashboard-guide.md                            |  6 +-
 packages/dashboard/app/components/ChatView.css     | 80 +++++++++++++++-------
 packages/dashboard/app/components/ChatView.tsx     | 52 +++++++++++++-
 .../app/components/StandardChatSurface.tsx         | 33 +++++++--
 .../__tests__/ChatView.message-edit.test.tsx       | 34 ++++++++-
 .../__tests__/ChatView.scroll-to-top.test.tsx      | 75 +++++++++++++++++++-
 7 files changed, 253 insertions(+), 34 deletions(-)

Fusion-Task-Id: FN-7918
Fusion-Task-Lineage: 76206cd2-94a8-47be-b282-94943e184d01
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 23:24:03 -07:00
gsxdsm
2aefaad319 FN-7924: Add View task link to artifact-registration mail notifications
Artifact-registration mail messages now expose the task that produced the artifact so users can jump straight to it from the mailbox.

- MailboxArtifactAttachment renders a "View task" button when message.metadata.taskId is present and an onOpenTask handler is supplied, alongside the existing Open artifact affordance
- MailboxModal and MailboxView thread taskId metadata and onOpenTask through to MailboxArtifactAttachment for both the message-list and detail-pane renders
- MainContent wires MailboxView's onOpenTask to the shared fetchTaskDetail -> openDetailTask path, with a toast on failure, so mailbox reuses the existing task-detail flow
- docs/dashboard-guide.md documents the new View task affordance for artifact notifications
- adds a minor changeset for @runfusion/fusion describing the new mail notification behavior
- extends MailboxArtifactAttachment and MailboxView tests to cover the new taskId/onOpenTask wiring

Files changed:
 .changeset/fn-7924-artifact-mail-view-task-link.md |  7 ++++
 docs/dashboard-guide.md                            |  2 +-
 .../app/components/MailboxArtifactAttachment.tsx   | 20 ++++++++++
 packages/dashboard/app/components/MailboxModal.css |  2 +-
 packages/dashboard/app/components/MailboxModal.tsx |  6 +++
 packages/dashboard/app/components/MailboxView.tsx  |  6 +++
 .../__tests__/MailboxArtifactAttachment.test.tsx   | 35 ++++++++++++++++-
 .../app/components/__tests__/MailboxView.test.tsx  | 45 +++++++++++++++++++++-
 .../app/components/dashboard/MainContent.tsx       |  6 +++
 9 files changed, 124 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7924

Fusion-Task-Lineage: 800102e1-9025-40da-8130-9ab0e8acd747

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 23:06:05 -07:00
gsxdsm
313956df5a FN-7916: fix chat model selector dismissing before selection on mobile/tablet
Fix the in-chat Brain popup's model picker on touch viewports: pointerdown outside-close was treating the portaled CustomModelDropdown menu as outside the popup, dismissing it before the tap could register a model selection, and the mobile popover was mis-anchored off-screen.

- ChatThinkingLevelControl: treat pointerdown targets inside the portaled `.model-combobox-dropdown--portal` menu as inside the popup so touch taps select the model instead of closing the popup first
- ChatView.css: clamp the popover to the viewport width via max-width/max-inline-size, and on mobile anchor it to the chat input area with tokenized left/right gutters instead of a collapsing left:0 width
- Add a portal-aware regression test covering pointerdown-inside-portal selection, genuine outside-pointerdown close, and the mobile CSS anchoring contract
- Add changeset (patch) and update dashboard guide docs to describe mobile/tablet behavior

Files changed:
 .changeset/fn-7916-chat-mobile-model-selector.md   |  7 ++
 docs/dashboard-guide.md                            |  3 +-
 .../app/components/ChatThinkingLevelControl.tsx    | 10 ++-
 packages/dashboard/app/components/ChatView.css     | 17 +++-
 .../ChatThinkingLevelControl.portal.test.tsx       | 97 ++++++++++++++++++++++
 5 files changed, 130 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7916

Fusion-Task-Lineage: bcc2d9ad-0be6-4e23-b643-eebf93aae3c6

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 22:49:51 -07:00
gsxdsm
daf3f15fd1 FN-7909: add room-level thinking effort override for Chat Rooms
Adds a per-room thinking-effort (reasoning level) override for Chat Rooms so all room responders can share a consistent override instead of relying only on per-agent/global defaults.

- Persist `chat_rooms.thinkingLevel` with a new core DB migration and store read/write support
- Extend chat-store and chat-types with thinkingLevel plumbing for room create/update
- Wire the dashboard chat room API/routes and legacy handlers to accept and return thinkingLevel
- Add a ChatView room settings control (with CSS) and useChatRooms hook support for setting/clearing the override
- Resolve room responder defaultThinkingLevel from the room override when present
- Update docs (dashboard-guide, settings-reference) and add a minor changeset for the feature

Files changed:
 .changeset/fn-7909-room-thinking-level.md          |  7 +++
 docs/dashboard-guide.md                            |  1 +
 docs/settings-reference.md                         |  2 +-
 packages/core/src/__tests__/chat-store.test.ts     | 21 ++++++++
 packages/core/src/__tests__/db-migrate.test.ts     | 57 ++++++++++++++++++++++
 packages/core/src/chat-store.ts                    | 12 ++++-
 packages/core/src/chat-types.ts                    | 10 ++++
 packages/core/src/db.ts                            | 28 ++++++++++-
 packages/dashboard/app/api/__tests__/chat-rooms-api.test.ts       |  8 +--
 packages/dashboard/app/api/legacy.ts               |  4 +-
 packages/dashboard/app/components/ChatView.css     | 16 ++++++
 packages/dashboard/app/components/ChatView.tsx     | 29 ++++++++++-
 packages/dashboard/app/components/__tests__/ChatView.rooms.test.tsx   | 24 +++++++++
 packages/dashboard/app/hooks/__tests__/useChatRooms.test.ts       | 22 +++++++++
 packages/dashboard/app/hooks/useChatRooms.ts       | 16 ++++++
 packages/dashboard/src/__tests__/chat-room-routes.test.ts         | 26 ++++++++++
 packages/dashboard/src/__tests__/chat.rooms.test.ts     | 42 ++++++++++++++++
 packages/dashboard/src/chat.ts                     |  8 +++
 packages/dashboard/src/routes/register-chat-room-routes.ts        | 21 ++++++--
 19 files changed, 338 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-7909

Fusion-Task-Lineage: 2741eca9-5305-4f6c-81bf-ae644a9fe307

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 22:12:18 -07:00
gsxdsm
8835c6cb48 FN-7908: add in-chat model/agent switcher to brain-icon popup
Extend the chat brain-icon popup and its backing session PATCH route so an
active Direct chat's model or agent can be switched mid-conversation instead
of only being set at creation time.

- Add a Model/Agent section to ChatThinkingLevelControl (the brain-icon
  popup) for picking a model provider/model or retargeting to a real agent
  without leaving the chat.
- Extend PATCH /api/chat/sessions/:id to accept modelProvider/modelId (as a
  validated pair via the existing validateModelPair helper) and agentId,
  forwarding only the keys present in the body so omitted fields leave the
  session's stored target untouched.
- Add chat-store updateSession support for the agentId clause alongside the
  existing model/thinkingLevel fields, and a useChat.setSessionModel hook
  for the dashboard to call the new PATCH capability.
- Update i18n locale strings (en/es/fr/ko/zh-CN/zh-TW) and dashboard-guide.md
  docs for the new switcher UI.
- Add unit/integration test coverage across chat-store, chat-manager,
  chat-routes, useChat, ChatThinkingLevelControl, and ChatView for the new
  model/agent switch behavior.
- Add changeset fn-7908-chat-model-agent-switcher.md (minor,
  @runfusion/fusion).

Files changed:
 .changeset/fn-7908-chat-model-agent-switcher.md    |   7 +
 docs/dashboard-guide.md                            |   3 +-
 packages/core/src/__tests__/chat-store.test.ts     |  21 ++
 packages/core/src/chat-store.ts                    |   8 +
 packages/core/src/chat-types.ts                    |   2 +
 packages/dashboard/app/api/legacy.ts               |  11 +-
 .../app/components/ChatThinkingLevelControl.tsx    | 219 ++++++++++++++++++---
 packages/dashboard/app/components/ChatView.css     | 135 ++++++++++++-
 packages/dashboard/app/components/ChatView.tsx     |  23 ++-
 .../__tests__/ChatThinkingLevelControl.test.tsx    | 109 +++++++++-
 .../__tests__/ChatView.thinking-level.test.tsx     |  67 ++++++-
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 166 +++++++++++++++-
 packages/dashboard/app/hooks/useChat.ts            |  56 ++++++
 .../dashboard/src/__tests__/chat-manager.test.ts   |  38 ++++
 .../dashboard/src/__tests__/chat-routes.test.ts    | 117 ++++++++++-
 .../dashboard/src/routes/register-chat-routes.ts   |  48 ++++-
 packages/i18n/locales/en/app.json                  |   8 +-
 packages/i18n/locales/es/app.json                  |   8 +-
 packages/i18n/locales/fr/app.json                  |   8 +-
 packages/i18n/locales/ko/app.json                  |   8 +-
 packages/i18n/locales/zh-CN/app.json               |   8 +-
 packages/i18n/locales/zh-TW/app.json               |   8 +-
 22 files changed, 1007 insertions(+), 71 deletions(-)

Fusion-Task-Id: FN-7908

Fusion-Task-Lineage: b1104865-9b0c-4d77-973e-89152fe245e0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 21:33:50 -07:00
gsxdsm
03bca1787b FN-7907: Add project chat default (model/agent) setting and New Chat default behavior
Adds a project-scoped Direct-chat default (model pair or durable agent) plus a New Chat behavior toggle (prompt vs. always-use-default), surfaced in Project Models settings using the standard model dropdown.

- Add ProjectSettings fields: chatNewSessionMode, chatDefaultKind, chatDefaultAgentId, chatDefaultModelProvider, chatDefaultModelId, chatDefaultThinkingLevel
- Extend settings-schema validation for the new chat default fields
- Add a "Chat" subsection to ProjectModelsSection with New Chat behavior selector, model/agent target toggle, and the standard CustomModelDropdown for model selection
- Update ChatView.tsx handleNewChat() flow to honor the configured default (prompt vs. immediate session creation)
- Add i18n strings across en/es/fr/ko/zh-CN/zh-TW locales and regenerate resources.d.ts
- Add changeset (@runfusion/fusion minor) and update docs/settings-reference.md and docs/dashboard-guide.md
- Add settings-parity, ChatView new-chat-default, and ProjectModelsSection chatDefault test coverage

Files changed:
 .changeset/fn-7907-chat-default.md                 |   7 +
 docs/dashboard-guide.md                            |   3 +-
 docs/settings-reference.md                         |   8 +
 packages/core/src/__tests__/settings-parity.test.ts     |  20 ++
 packages/core/src/settings-schema.ts               |   6 +
 packages/core/src/types.ts                         |  15 +
 packages/dashboard/app/components/ChatView.tsx     |  93 +++++-
 packages/dashboard/app/components/__tests__/ChatView.new-chat-default.test.tsx   | 357 +++++++++++++++++++++
 packages/dashboard/app/components/settings/sections/ProjectModelsSection.tsx     |  77 +++++
 packages/dashboard/app/components/settings/sections/__tests__/ProjectModelsSection.chatDefault.test.tsx |  193 +++++++++++
 packages/i18n/locales/en/app.json                  |  20 +-
 packages/i18n/locales/es/app.json                  |  20 +-
 packages/i18n/locales/fr/app.json                  |  20 +-
 packages/i18n/locales/ko/app.json                  |  20 +-
 packages/i18n/locales/zh-CN/app.json               |  20 +-
 packages/i18n/locales/zh-TW/app.json               |  20 +-
 packages/i18n/src/resources.d.ts                   |  18 ++
 17 files changed, 899 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7907

Fusion-Task-Lineage: 86a81b9c-7e0c-4033-9e2a-6f7380810fe9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 20:54:10 -07:00
gsxdsm
41168e273c FN-7905: surface resolved default in chat thinking-level labels
Chat thinking-level Default entries hardcoded "off" instead of showing the project/global resolved default, misleading operators about which level would actually apply.

- ChatView now fetches Settings via fetchSettings on mount and derives resolvedDefaultThinkingLevel from settings.defaultThinkingLevel (falling back to "off")
- Threads resolvedDefaultThinkingLevel into NewChatDialog and the in-chat ChatThinkingLevelControl (Brain popup) so both surfaces show e.g. "Default (medium)" instead of always "Default (off)"
- ChatThinkingLevelControl accepts a new optional defaultThinkingLevel prop (defaults to "off" for backward compatibility) used only for the Default/clear option label
- Updates dashboard-guide.md to document the resolved-default label behavior in both the New Chat dialog and the in-chat Brain popup
- Adds/updates tests: new ChatThinkingLevelControl coverage for the label prop, new ChatView.thinking-level test coverage for the resolved default, and mocks fetchSettings in the other ChatView test suites that render ChatView
- Adds a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7905-chat-thinking-default.md        |  7 ++++
 docs/dashboard-guide.md                            |  5 +--
 .../app/components/ChatThinkingLevelControl.tsx    |  9 +++--
 packages/dashboard/app/components/ChatView.tsx     | 36 ++++++++++++++++---
 .../__tests__/ChatThinkingLevelControl.test.tsx    | 16 +++++++++
 .../__tests__/ChatView.chat-commands.test.tsx      |  1 +
 .../__tests__/ChatView.content-search.test.tsx     |  1 +
 .../__tests__/ChatView.context-window.test.tsx     |  1 +
 .../__tests__/ChatView.copy-response.test.tsx      |  1 +
 .../__tests__/ChatView.core-contracts.test.tsx     |  1 +
 .../__tests__/ChatView.core-interactions.test.tsx  |  1 +
 .../components/__tests__/ChatView.core.test.tsx    |  1 +
 .../__tests__/ChatView.default-model-icon.test.tsx |  1 +
 .../__tests__/ChatView.hash-mention.test.tsx       |  1 +
 .../components/__tests__/ChatView.mobile.test.tsx  |  1 +
 .../__tests__/ChatView.sessions-rooms.test.tsx     |  1 +
 .../__tests__/ChatView.streaming-thread.test.tsx   |  1 +
 .../__tests__/ChatView.thinking-level.test.tsx     | 42 ++++++++++++++++++++++
 18 files changed, 119 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7905

Fusion-Task-Lineage: 7290aa8a-f812-43c3-8ba5-fc31a3f4579e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 20:19:36 -07:00
gsxdsm
9f8db7d1b5 FN-7903: wire thinkingLevel into AI session creation for automation steps
Threads the persisted per-step Thinking Level (from FN-7900) into runtime AI session creation and task spawning, so scheduled, routine, and manual automation runs actually apply the chosen reasoning effort instead of only storing it.

- CronRunner passes step.thinkingLevel through AiPromptExecutor to createFnAgent's defaultThinkingLevel for scheduled AI-prompt steps
- RoutineRunner forwards step.thinkingLevel to the shared AiPromptExecutor seam for routine AI-prompt steps
- Cron/routine create-task steps map step.thinkingLevel onto TaskCreateInput.thinkingLevel so spawned tasks inherit the configured reasoning effort
- Dashboard's inline/manual AI-prompt and create-task automation routes apply the same defaultThinkingLevel / TaskCreateInput.thinkingLevel behavior
- Updated docs (dashboard-guide.md, settings-reference.md) to describe the now-active runtime behavior
- Added a changeset for @runfusion/fusion (minor) and expanded cron-runner/routine-runner/routes-automation test coverage

Files changed:
 .changeset/fn-7903-automation-thinking-level.md    |  7 ++
 docs/dashboard-guide.md                            |  5 +-
 docs/settings-reference.md                         |  2 +-
 .../src/__tests__/routes-automation.test.ts        | 67 +++++++++++++++++++
 packages/dashboard/src/routes.ts                   | 10 +++
 packages/engine/src/__tests__/cron-runner.test.ts  | 75 +++++++++++++++++++++-
 .../engine/src/__tests__/routine-runner.test.ts    | 68 +++++++++++++++++++-
 packages/engine/src/cron-runner.ts                 | 21 +++++-
 packages/engine/src/routine-runner.ts              | 11 +++-
 9 files changed, 255 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7903

Fusion-Task-Lineage: c7eb4660-975d-4c5d-820e-0f1a3ac8b6a6

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 20:09:57 -07:00
gsxdsm
23cb061af2 FN-7898: add in-chat thinking-level control next to the attach button
Adds a Brain-icon popover control in the chat composer that lets users change an existing session's reasoning-effort level mid-conversation, extending the existing create-time-only thinking-level picker.

- Add ChatThinkingLevelControl component (Brain-icon trigger + popover) wired into ChatView's direct-session composer, gated to non-CLI model-loop sessions only
- Extend PATCH /api/chat/sessions/:id to accept an optional thinkingLevel field, validated via existing validateThinkingLevel helper; null/empty string explicitly clears back to the inherited default, omitting the key leaves it untouched
- Add useChat().setSessionThinkingLevel hook method to call the new PATCH capability
- Add i18n strings (thinkingLevelButton) across all locales and regenerate packages/i18n/src/resources.d.ts
- Add changeset for @runfusion/fusion (minor) and update docs/dashboard-guide.md

Files changed:
 .changeset/fn-7898-chat-thinking-level-control.md  |   7 +
 docs/dashboard-guide.md                            |   2 +
 packages/dashboard/app/api/legacy.ts               |   4 +-
 .../app/components/ChatThinkingLevelControl.tsx    | 133 +++++++++++
 packages/dashboard/app/components/ChatView.css     |  73 ++++++
 packages/dashboard/app/components/ChatView.tsx     |  20 ++
 .../__tests__/ChatThinkingLevelControl.test.tsx    | 103 ++++++++
 .../__tests__/ChatView.message-edit.test.tsx       |   1 +
 .../components/__tests__/ChatView.test-harness.tsx |   1 +
 .../__tests__/ChatView.thinking-level.test.tsx     | 262 +++++++++++++++++++++
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 108 +++++++++
 packages/dashboard/app/hooks/useChat.ts            |  59 +++++
 .../dashboard/src/__tests__/chat-routes.test.ts    |  83 +++++++
 .../dashboard/src/routes/register-chat-routes.ts   |  35 ++-
 packages/i18n/locales/en/app.json                  |   1 +
 packages/i18n/locales/es/app.json                  |   1 +
 packages/i18n/locales/fr/app.json                  |   1 +
 packages/i18n/locales/ko/app.json                  |   1 +
 packages/i18n/locales/zh-CN/app.json               |   1 +
 packages/i18n/locales/zh-TW/app.json               |   1 +
 packages/i18n/src/resources.d.ts                   |  96 ++++++--
 21 files changed, 970 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-7898

Fusion-Task-Lineage: a052a6ef-d2d3-45af-9b92-221996780b1b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 20:00:50 -07:00
gsxdsm
635d78248b FN-7900: persist thinkingLevel override for schedule and routine AI steps
Adds a persisted, optional per-step reasoning-effort (thinkingLevel) override for AI-capable schedule and routine automation steps, surfaced in the editors and validated at the route layer.

- Add optional AutomationStep.thinkingLevel field (packages/core/src/automation.ts), riding the existing JSON steps blob so no DB migration is needed; runtime application of the level is deferred to a follow-up.
- Validate thinkingLevel in dashboard route step validation against the shared THINKING_LEVELS set, rejecting unknown values (packages/dashboard/src/routes.ts).
- Add Thinking Level controls to RoutineEditor, ScheduleForm, and ScheduleStepsEditor so users can set/inherit the override per step.
- Extend core and dashboard test suites (automation-store, routine-store, RoutineEditor, ScheduleForm, ScheduleStepsEditor, routes-automation) to cover persistence, validation, and UI behavior.
- Update dashboard-guide.md docs and add a minor changeset for the new feature.

Files changed:
 .changeset/fn-7900-automation-thinking-level.md    |   7 +
 docs/dashboard-guide.md                            |   3 +-
 .../core/src/__tests__/automation-store.test.ts    |  45 ++++++
 packages/core/src/__tests__/routine-store.test.ts  |  46 +++++++
 packages/core/src/automation.ts                    |   9 ++
 .../dashboard/app/components/RoutineEditor.tsx     |  21 ++-
 packages/dashboard/app/components/ScheduleForm.tsx |  28 +++-
 .../app/components/ScheduleStepsEditor.tsx         |  21 ++-
 .../components/__tests__/RoutineEditor.test.tsx    |  99 +++++++++++++-
 .../app/components/__tests__/ScheduleForm.test.tsx | 137 +++++++++++++++++--
 .../__tests__/ScheduleStepsEditor.test.tsx         |  83 +++++++++--
 .../src/__tests__/routes-automation.test.ts        | 152 +++++++++++++++++++++
 packages/dashboard/src/routes.ts                   |  10 ++
 13 files changed, 622 insertions(+), 39 deletions(-)

Fusion-Task-Id: FN-7900

Fusion-Task-Lineage: 812a9a8c-ad0f-462f-b1c6-9900f70e4261

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 19:43:41 -07:00
gsxdsm
7a51f95b38 FN-7901: persist thinkingLevel for insight model selection
Adds a persisted Thinking Level (reasoning-effort) selector to manual insight generation, threading the selection through the dashboard API, insight run metadata, and retries.

- Add inline Thinking Level selector to the InsightsView model-config popover, persisted to localStorage (fusion-insight-thinking)
- Thread thinkingLevel through triggerInsightRun (legacy API client) and useInsights.runInsights
- Validate and store thinkingLevel in insight run inputMetadata.metadata on the POST /insights/run route; resolve it via resolvePlanningThinkingLevel for the actual generation call
- Recover and reapply the original run's thinkingLevel on retry (retryInsightRunLifecycle) so retries reuse the same reasoning-effort setting
- Export resolvePlanningThinkingLevel from @fusion/engine
- Document the new Thinking Level selector in docs/dashboard-guide.md
- Add a minor changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7901-insight-thinking-level.md       |  7 ++
 docs/dashboard-guide.md                            |  1 +
 .../app/__tests__/insight-model-selector.test.tsx  | 41 ++++++++++-
 packages/dashboard/app/api/legacy.ts               |  2 +
 packages/dashboard/app/components/InsightsView.tsx | 24 +++++-
 .../app/hooks/__tests__/useInsights.test.ts        | 36 ++++++++-
 packages/dashboard/app/hooks/useInsights.ts        |  6 +-
 .../src/__tests__/insights-routes.test.ts          | 86 ++++++++++++++++++++++
 packages/dashboard/src/insights-routes.ts          | 36 ++++++++-
 packages/engine/src/index.ts                       |  1 +
 10 files changed, 227 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7901

Fusion-Task-Lineage: a6249526-e97d-403e-b853-e497d16f425b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 19:39:42 -07:00
gsxdsm
b98314923c FN-7899: add thinking-level editing to Agent Detail, Onboarding, and bulk task model selectors
Bring thinking-level (reasoning effort) editing to every remaining model selector surface that previously lacked it, so operators can set it consistently from Agent Detail, Agent Onboarding, and the List view's bulk task editor, in addition to the batch-update-models API and route that back them.

- Agent Detail config tab: persist/edit a built-in agent's runtimeConfig.thinkingLevel inline via the shared model dropdown, with dirty-state and reset tracking.
- Agent Onboarding modal: replace the read-only thinking-level input with an editable control wired into the same model dropdown used for creation.
- List view bulk edit toolbar: add a "no change" / "use default" / explicit-level thinking selector alongside executor/reviewer model and node overrides, wired through to the bulk apply action.
- Dashboard API client (`batchUpdateTaskModels`) and `/api/tasks/batch-update-models` route: accept and validate an optional `thinkingLevel` field (against `THINKING_LEVELS`), applying it per task alongside existing model/node updates.
- Update dashboard-guide.md docs and add regression tests across AgentDetailView, AgentOnboardingModal, ListView, and the batch-update-models route.
- Add a minor changeset documenting the feature for release notes.

Files changed:
 .changeset/thinking-level-selector-parity.md       |  7 ++
 docs/dashboard-guide.md                            |  5 +-
 packages/dashboard/app/api/legacy.ts               |  3 +
 .../dashboard/app/components/AgentDetailView.tsx   | 20 +++++-
 .../app/components/AgentOnboardingModal.tsx        | 11 +++-
 packages/dashboard/app/components/ListView.tsx     | 54 +++++++++++++---
 .../__tests__/AgentDetailView.settings.test.tsx    | 45 +++++++++++++
 .../__tests__/AgentDetailView.test-helpers.ts      | 19 +++++-
 .../__tests__/AgentOnboardingModal.test.tsx        | 41 +++++++++++-
 .../app/components/__tests__/ListView.test.tsx     | 43 ++++++++++++-
 .../src/__tests__/routes-tasks-ops.test.ts         | 75 ++++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    | 22 +++++--
 12 files changed, 323 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-7899

Fusion-Task-Lineage: fd584ce4-42b3-4c20-8de5-4d3c8963f593

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 19:18:25 -07:00
gsxdsm
02fdb4c089 FN-7897: reserve footer space for pinned below-mode terminal
Fix the pinned (below-mode) terminal panel rendering underneath the fixed ExecutorStatusBar footer, so its bottom action-control row stays visible on desktop and mobile alike.

- Add a footerVisible prop to TerminalModal, wired from App.tsx's executorFooterVisible state
- Add .terminal-below-host--with-footer CSS modifier that redeclares --executor-footer-height and reserves padding-bottom (with the Android Chrome ICB offset), matching the .project-content--with-footer/.left-sidebar-nav--with-footer/.right-dock--with-footer precedent
- Update dashboard-guide.md terminal walkthrough to describe the new footer-avoidance behavior
- Add/extend TerminalModal tests covering the footerVisible prop and CSS modifier
- Add a patch changeset for @runfusion/fusion documenting the fix

Files changed:
 .../fn-7897-pinned-terminal-footer-overlap.md      |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 packages/dashboard/app/App.tsx                     |   1 +
 .../dashboard/app/components/TerminalModal.css     |  12 ++
 .../dashboard/app/components/TerminalModal.tsx     |  17 ++-
 .../components/__tests__/TerminalModal.test.tsx    | 135 ++++++++++++++++++++-
 6 files changed, 170 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7897

Fusion-Task-Lineage: e22db6a9-35a8-46a1-8c15-186eaf5267fd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 19:00:16 -07:00
gsxdsm
c745990aa2 FN-7879: deliver one-time Postgres-migration inbox notice on first 0.59 startup
Adds a best-effort, idempotent dashboard inbox notice announcing the upcoming embedded-Postgres storage migration, delivered once per project on the first engine start under the Fusion 0.59.x release line.

- New `deliverPostgresMigrationNoticeIfNeeded` in `@fusion/engine` (`postgres-migration-notice.ts`) builds and sends a `system` -> `user` inbox message via `MessageStore`, gated to version `0.59.x` by `isPostgresMigrationNoticeVersion`
- Idempotency via existing inbox message `metadata.kind = "postgres-migration-notice"` marker (no new settings key or table), so restarts never duplicate the notice
- Delivery is fully best-effort: any `MessageStore` failure is caught, logged as a warning, and never blocks or fails `ProjectEngine.start()`
- `ProjectEngine.start()` invokes the notice after runtime start, using an injected `cliPackageVersion` threaded from the CLI layer through `EngineManagerOptions` / `ProjectEngineOptions` so the engine never imports CLI/dashboard code directly
- `daemon.ts`, `dashboard.ts`, and `serve.ts` resolve the published `@runfusion/fusion` version via `getCliPackageVersion` / `isUnresolvedCliPackageVersion` and pass it into `ProjectEngineManager`
- Exported new symbols (`POSTGRES_MIGRATION_HELP_URL`, `POSTGRES_MIGRATION_NOTICE_KIND`, `deliverPostgresMigrationNoticeIfNeeded`, `isPostgresMigrationNoticeVersion`, related types) from `@fusion/engine`, and `isUnresolvedCliPackageVersion` from `@fusion/dashboard`
- New unit tests covering version matching and single-delivery/idempotency behavior
- Docs updated (`docs/agents.md`, `docs/dashboard-guide.md`) to describe the one-time notice and its dedup key
- Changeset added for `@runfusion/fusion` (minor, feature)

Files changed:
 .changeset/fn-7879-postgres-migration-inbox-notice.md              |   7 ++
 docs/agents.md                                                     |   1 +
 docs/dashboard-guide.md                                            |   1 +
 packages/cli/src/commands/daemon.ts                                |   6 +-
 packages/cli/src/commands/dashboard.ts                             |   5 +
 packages/cli/src/commands/serve.ts                                 |   6 +-
 packages/dashboard/src/index.ts                                    |   2 +-
 packages/engine/src/__tests__/postgres-migration-notice.test.ts    | 140 +++++++++++++++++++++
 packages/engine/src/index.ts                                       |   9 ++
 packages/engine/src/postgres-migration-notice.ts                   | 107 ++++++++++++++++
 packages/engine/src/project-engine-manager.ts                      |   6 +
 packages/engine/src/project-engine.ts                               |  12 ++
 12 files changed, 299 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7879

Fusion-Task-Lineage: 201877e5-6bdc-4168-a8ac-ae0e50ec8308

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 17:02:33 -07:00
gsxdsm
56c745240a FN-7880: shorten Reset Settings button to "Reset" on mobile
Shortens the Settings footer's Reset Settings button label to Reset at the mobile breakpoint to preserve footer space, while desktop/tablet keep the full label; confirmation dialog and reset behavior are unchanged.

- Add settings.reset.buttonShort i18n key (en, zh-CN) and typed resources.d.ts entry
- SettingsModal reset button now renders buttonShort ("Reset") when viewportMode === "mobile", otherwise the existing "Reset Settings" label
- Update settings-mobile.test.tsx to assert the compact mobile label and add coverage across modal/embedded x mobile/desktop viewport combinations
- Update docs/dashboard-guide.md to document the mobile-only compact label
- Add changeset (patch) for @runfusion/fusion

Files changed:
 .changeset/fn-7880-reset-mobile-label.md           |  7 ++++
 docs/dashboard-guide.md                            |  6 ++--
 packages/dashboard/app/components/SettingsModal.tsx |  7 +++-
 packages/dashboard/app/components/__tests__/settings-mobile.test.tsx | 37 +++++++++++++++++++++-
 packages/i18n/locales/en/app.json                  |  1 +
 packages/i18n/locales/zh-CN/app.json               |  1 +
 packages/i18n/src/resources.d.ts                   |  1 +
 7 files changed, 56 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7880

Fusion-Task-Lineage: e636e73d-172e-4a6e-bb51-078520fd05ab

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 16:48:04 -07:00
gsxdsm
ee1d978984 FN-7876: add custom terminal shortcut buttons to SessionTerminal mobile key bar
Extends the embedded Task Detail SessionTerminal to surface the shared, user-defined terminal shortcuts (from FN-7872's kb-terminal-preferences localStorage) as tappable buttons in its mobile accessory key bar.

- Read customShortcuts via the shared readTerminalPreferences() store on mount and refresh live on the storage event
- Render each custom shortcut as a mobile-only accessory-bar button that injects decodeTerminalShortcutSequence(value) through the focus-preserving keepFocus + sendInput path, clearing sticky Ctrl like the built-in ^C key
- Suppress the buttons for read-only/replay/idle/ended sessions via the existing canAcceptInput gate; desktop embedded terminals get no key bar
- Add .cli-terminal-key--custom styling for the new buttons
- Update docs/dashboard-guide.md to describe the mobile custom-shortcut key bar behavior
- Add a minor changeset for @runfusion/fusion documenting the feature
- Add SessionTerminal.mobile.test.tsx coverage for rendering, injection, live updates, and read-only suppression

Files changed:
 .changeset/fn-7876-session-terminal-custom-shortcuts.md                     |  7 ++
 docs/dashboard-guide.md                                                     |  2 +-
 packages/dashboard/app/components/SessionTerminal.css                      |  5 ++
 packages/dashboard/app/components/SessionTerminal.tsx                      | 31 +++++++
 packages/dashboard/app/components/__tests__/SessionTerminal.mobile.test.tsx | 94 ++++++++++++++++++++++
 5 files changed, 138 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7876
Fusion-Task-Lineage: 61d62ad2-7357-4eb4-b542-6e17deea1e5e
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 13:22:05 -07:00
gsxdsm
b77e12351e FN-7872: add custom terminal shortcut buttons to the Preferences panel
Lets users define, edit, and remove custom terminal shortcut buttons (label + injected key sequence) from the terminal Preferences panel, persisted client-side.

- Add a customShortcuts list to terminalPreferences (kb-terminal-preferences localStorage) with add/edit/remove management
- Add decodeTerminalShortcutSequence to decode \n, \t, \r, \e/\x1b, and \\ escapes for injected sequences
- Render custom shortcut buttons in TerminalModal's shortcut panel, injecting via the focus-preserving sendLiteralShortcut path
- Add management UI (add/edit/remove) for custom shortcuts in the terminal Preferences panel, styled in TerminalModal.css
- Extend TerminalModal and terminalPreferences test coverage for the new custom shortcut behavior
- Document custom terminal shortcuts in docs/dashboard-guide.md
- Add a minor changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7872-terminal-custom-shortcuts.md    |   7 +
 docs/dashboard-guide.md                            |   7 +-
 .../dashboard/app/components/TerminalModal.css     | 106 +++++++++++
 .../dashboard/app/components/TerminalModal.tsx     | 202 ++++++++++++++++++++-
 .../components/__tests__/TerminalModal.test.tsx    | 183 +++++++++++++++++++
 .../utils/__tests__/terminalPreferences.test.ts    |  68 +++++++
 .../dashboard/app/utils/terminalPreferences.ts     | 140 +++++++++++++-
 7 files changed, 708 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7872

Fusion-Task-Lineage: 9b2df0da-0eb7-4cec-a42b-767e23ff4c2c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 13:06:08 -07:00
gsxdsm
bb86844f8d FN-7869: add hide done toggle to Todo list view
Adds a per-project Hide done / Show done toggle to the Todo list items header so operators can declutter long selected lists while completion counts still reflect all items.
- Add hideDone state persisted per project via localStorage (kb-dashboard-todo-hide-done key registered in projectStorage)
- Filter rendered todo items to hide completed ones when the toggle is active, while keeping list stats/progress counts based on all items
- Adjust up/down item reordering to operate correctly against the visible (filtered) list while still reordering the underlying full item list
- Add an empty-state message when all items are hidden by the toggle, with Eye/EyeOff icon + i18n strings (todo.hideDone, todo.showDone, todo.allDoneHidden)
- Add regression tests covering the toggle, persistence, filtering, and empty state
- Document the Hide done / Show done control in the dashboard guide

Files changed:
 docs/dashboard-guide.md                            |  3 +
 packages/dashboard/app/components/TodoView.css     | 45 ++++++++++
 packages/dashboard/app/components/TodoView.tsx     | 66 +++++++++++++--
 .../app/components/__tests__/TodoView.test.tsx     | 99 ++++++++++++++++++++++
 packages/dashboard/app/utils/projectStorage.ts     |  1 +
 packages/i18n/locales/en/app.json                  |  3 +
 6 files changed, 210 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7869

Fusion-Task-Lineage: 9c334aba-e802-43b8-963c-0f2daf727583

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 12:52:30 -07:00
gsxdsm
06ec0e606e FN-7866: add auto-save toggle for the workspace file editor (default on)
Adds a shared, persisted auto-save preference for workspace text-file editing, defaulted to on, surfaced as a toolbar toggle in both the Files modal and right-dock Files view.

- Add useAutoSavePreference hook: persists the fn-file-editor-auto-save localStorage preference, broadcasts same-window changes via a custom event (storage events only reach other documents), and defaults to true.
- Extend useWorkspaceFileEditor with an autoSave flag that debounces (800ms) and triggers save() for a loaded, editable file with real pending changes, keyed by workspace+file+content to avoid re-firing on failed writes.
- Add an Auto-save toggle button to FileEditor's toolbar (autoSaveEnabled/onToggleAutoSave/canToggleAutoSave props), hidden for read-only/preview/binary files.
- Wire the shared preference into FileBrowserModal and DockFilesView, disabling auto-save for binary files in the modal.
- Add fileEditor.autoSave / fileEditor.toggleAutoSave i18n strings and document the new default behavior in docs/dashboard-guide.md.
- Add/extend tests covering the new hook, debounced auto-save behavior, and toolbar toggle wiring across FileEditor, FileBrowserModal, and DockFilesView.

Files changed:
 docs/dashboard-guide.md                            |   3 +
 .../dashboard/app/components/DockFilesView.tsx     |   6 +-
 .../dashboard/app/components/FileBrowserModal.tsx  |  20 ++--
 packages/dashboard/app/components/FileEditor.tsx   |  17 +++-
 .../components/__tests__/DockFilesView.test.tsx    |  37 ++++++-
 .../components/__tests__/FileBrowserModal.test.tsx |  86 +++++++++++++---
 .../app/components/__tests__/FileEditor.test.tsx   |  56 +++++++++++
 .../hooks/__tests__/useAutoSavePreference.test.ts  |  66 +++++++++++++
 .../hooks/__tests__/useWorkspaceFileEditor.test.ts | 108 +++++++++++++++++++++
 .../dashboard/app/hooks/useAutoSavePreference.ts   |  79 +++++++++++++++
 .../dashboard/app/hooks/useWorkspaceFileEditor.ts  |  47 ++++++++-
 packages/i18n/locales/en/app.json                  |   2 +
 12 files changed, 500 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-7866

Fusion-Task-Lineage: 0604de18-666d-4872-abce-2a3886c9ea55

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 12:49:37 -07:00
gsxdsm
b8c18becd3 FN-7865: make artifact viewer popups full-screen sheets on mobile
Fixes the artifact viewer FloatingWindow (image/video/PDF/document) so it opens as a full-screen sheet on mobile instead of a small draggable/resizable desktop-style window.

- Add a mobile-breakpoint override for .artifacts-gallery-window that clamps the FloatingWindow to inset:0/100vw/100dvh with no border/radius/shadow
- Hide the FloatingWindow resize handle and disable header drag cursor/touch-action on mobile so the sheet can't be dragged or resized like the desktop window
- Add a CSS-contract regression test (ArtifactsGallery.css.test.ts) asserting the mobile sheet rules exist while desktop keeps the header drag affordance
- Update dashboard-guide.md docs to describe desktop draggable/resizable behavior vs. mobile full-screen sheet behavior
- Add a patch changeset for @runfusion/fusion documenting the fix

Files changed:
 .changeset/fn-7865-artifact-viewer-mobile-sheet.md |  7 +++
 docs/dashboard-guide.md                            |  5 +-
 .../dashboard/app/components/ArtifactsGallery.css  | 28 +++++++++-
 .../__tests__/ArtifactsGallery.css.test.ts         | 63 ++++++++++++++++++++++
 4 files changed, 100 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7865

Fusion-Task-Lineage: 0b5dfaee-3f7b-4a2e-968c-324182ae7953

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 12:10:38 -07:00
gsxdsm
95a808af6e FN-7864: add inline artifact preview/link to artifact-registered mail messages
Artifact-registration mailbox notifications now render a shared inline preview and open-artifact link instead of plain text metadata.

- Add MailboxArtifactAttachment component rendering an inline image/document preview plus an "open artifact" link from message.metadata (artifactId/artifactType/mimeType) via artifactMediaUrl
- Wire MailboxModal and MailboxView to render the new attachment for artifact-registered messages, with supporting CSS
- Emit metadata.mimeType from notifyArtifactRegistered in agent-tools.ts so mailbox surfaces can pick the right preview affordance without an extra artifact fetch
- Add/extend tests for the new component and for MailboxView/agent-artifact-tools coverage
- Update dashboard guide docs and add a changeset for the feature

Files changed:
 .changeset/fn-7864-artifact-mail-link.md           |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 .../app/components/MailboxArtifactAttachment.tsx   | 103 +++++++++++++++++++++
 packages/dashboard/app/components/MailboxModal.css |  74 +++++++++++++++
 packages/dashboard/app/components/MailboxModal.tsx |  15 +++
 packages/dashboard/app/components/MailboxView.tsx  |  15 +++
 .../__tests__/MailboxArtifactAttachment.test.tsx   |  65 +++++++++++++
 .../app/components/__tests__/MailboxView.test.tsx  |  93 +++++++++++++++++++
 .../src/__tests__/agent-artifact-tools.test.ts     |  32 ++++++-
 packages/engine/src/agent-tools.ts                 |   5 +
 10 files changed, 409 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7864

Fusion-Task-Lineage: a6502e18-5f7f-4c67-80fb-a709e4a52c50

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 12:01:00 -07:00
gsxdsm
e559b2b538 FN-7853: preserve chat thread during active streaming turns
Fix useChat so already-rendered user/assistant messages no longer flicker away while an agent turn is actively streaming.

- useChat.ts: during an active streaming turn for the current session, treat stale/empty/cross-session loadMessages responses as append-only against the visible thread instead of replacing it, merging any genuinely new same-session messages in and skipping the session-cache write when the active thread is being preserved.
- ChatView.streaming-thread.test.tsx: add coverage asserting the rendered thread stays visible across mid-turn session-update/tool-call/stale-reload churn.
- useChat.test.ts: add hook-level regression tests for the append-only/merge/cache-skip behavior during active streaming.
- docs/architecture.md, docs/dashboard-guide.md: document the append-only mid-turn thread-stability behavior.
- Add changeset (patch) for @runfusion/fusion describing the user-facing fix.

Files changed:
 .../fn-7853-chat-mid-turn-message-stability.md     |   7 +
 docs/architecture.md                               |   1 +
 docs/dashboard-guide.md                            |   1 +
 .../__tests__/ChatView.streaming-thread.test.tsx   | 130 +++++++++++++
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 208 +++++++++++++++++++++
 packages/dashboard/app/hooks/useChat.ts            |  35 +++-
 6 files changed, 380 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7853

Fusion-Task-Lineage: d9909469-082c-4eeb-81fb-b36d1a9e4705

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:26:53 -07:00
gsxdsm
9bb74595c2 FN-7852: add one-time SQLite→embedded Postgres storage notice banner
Adds a dismissible, one-time dashboard banner announcing the upcoming SQLite→embedded-Postgres storage backend change.

- New self-contained StorageMigrationNoticeBanner component with title/body copy and a dismiss control that persists via localStorage key fusion:storage-migration-notice-dismissed
- Wire the banner into DashboardBanners alongside the CLI binary install banner for project-scoped views
- Add en locale strings (storageMigrationNotice.title/body/dismissLabel) in app.json
- Add component test coverage for render/dismiss/persistence behavior
- Document the notice in docs/dashboard-guide.md
- Add a minor changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7852-storage-migration-notice.md     |  7 ++
 docs/dashboard-guide.md                            |  2 +
 .../components/StorageMigrationNoticeBanner.css    | 73 +++++++++++++++++++
 .../components/StorageMigrationNoticeBanner.tsx    | 65 +++++++++++++++++
 .../StorageMigrationNoticeBanner.test.tsx          | 82 ++++++++++++++++++++++
 .../app/components/dashboard/DashboardBanners.tsx  | 11 ++-
 packages/i18n/locales/en/app.json                  |  5 ++
 7 files changed, 242 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7852

Fusion-Task-Lineage: e3235cce-9ca3-4830-8733-a2ec46c53246

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:19:52 -07:00
gsxdsm
dd95634262 FN-7845: show task-scoped artifacts alongside Task Documents
Extend the dashboard's Task Documents tab to union each task's registered documents with its task-scoped artifacts, with an inline right-pane viewer for the added artifact types.

- DocumentsView Task Documents tab now merges task documents and task-scoped artifacts per task group, sorted/grouped consistently
- Adds an inline right-pane artifact viewer (image/video/audio/pdf/inline-doc/other) reusing getArtifactCategory + artifactMediaUrl/fetchArtifact
- Selection state is a discriminated document|artifact union kept separate from Project Files selection; the standalone Artifacts gallery tab is unchanged
- Updates dashboard-guide.md to describe the merged Task Documents behavior (grouping, search, and preview now cover both documents and artifacts)
- Adds a minor changeset for @runfusion/fusion documenting the artifact-in-Task-Documents feature
- Expands DocumentsView test coverage for the new union/selection/preview behavior

Files changed:
 .changeset/fn-7845-task-documents-artifacts.md     |   7 +
 docs/dashboard-guide.md                            |   6 +-
 .../dashboard/app/components/DocumentsView.css     | 142 +++++++-
 .../dashboard/app/components/DocumentsView.tsx     | 389 ++++++++++++++++++---
 .../components/__tests__/DocumentsView.test.tsx    | 290 ++++++++++++++-
 5 files changed, 780 insertions(+), 54 deletions(-)

Fusion-Task-Id: FN-7845

Fusion-Task-Lineage: 32bbe6dc-4c02-449c-a13f-38abb8fd727d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:43:34 -07:00
gsxdsm
c7c6c5a8c4 FN-7842: color-code priority icons by urgency across quick add, task form, and task cards
Adds a shared urgency color source to priorityIndicator and wires it into every priority-glyph surface so low/normal/high/urgent read consistently by color, not just icon shape.

- priorityIndicator.tsx: add colorVar (low=info/blue, normal=muted, high=warning/amber, urgent=error/red) and new getPriorityColorVar() export as the single source of truth
- QuickEntryBox: tint the icon-only priority trigger and each option row in the priority picker with the matching urgency color
- TaskForm: tint the New Task inline priority glyph using the same color source
- TaskCard: render a colored priority glyph alongside the existing text label in the card-priority-badge (kept the non-normal visibility gate and badge geometry via a small CSS gap addition)
- Updated/added tests for QuickEntryBox, TaskCard (badge, badge-height, badge-wrap), and priorityIndicator to assert the new colors; added a patch changeset and a dashboard-guide.md doc update

Files changed:
 .changeset/fn-7842-priority-color-coding.md        |  7 +++++
 docs/dashboard-guide.md                            |  7 +++--
 .../dashboard/app/components/QuickEntryBox.tsx     |  7 +++--
 packages/dashboard/app/components/TaskCard.css     |  2 ++
 packages/dashboard/app/components/TaskCard.tsx     |  6 +++-
 packages/dashboard/app/components/TaskForm.tsx     |  7 +++--
 .../components/__tests__/QuickEntryBox.test.tsx    | 17 +++++++++--
 .../__tests__/TaskCard.badge-height.test.tsx       |  5 ++++
 .../__tests__/TaskCard.badge-wrap.test.tsx         |  5 ++++
 .../app/components/__tests__/TaskCard.test.tsx     | 33 +++++++++++++++++++++-
 .../app/utils/__tests__/priorityIndicator.test.tsx | 13 +++++----
 packages/dashboard/app/utils/priorityIndicator.tsx | 16 ++++++++---
 12 files changed, 103 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-7842

Fusion-Task-Lineage: 0b2d0d15-6e61-45fc-9378-bc09002bef55

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
06bf0b85b9 FN-7834: restyle Task Documents sidebar with clearer task-card grouping
Gives the Artifacts view's Task Documents sidebar a distinct card-per-task look with more breathing room between task groups, replacing the flat bordered-row list.

- Restyle .documents-task-sidebar-group into a bordered, rounded card with shadow and inter-group gap instead of a bottom-border-only divider
- Strengthen the group header (bolder task id/title, tinted background) so it reads as a container rather than a peer row
- Add hover/selected background treatment and left-indent to .documents-task-document-item entries, scoped under .documents-task-documents-sidebar so Project Files and Artifacts stay unaffected
- Add a regression test asserting group headers remain non-selectable containers distinct from selectable document rows
- Update dashboard-guide.md wording to describe the new distinct task-card grouping
- Add changeset (patch) documenting the sidebar restyle

Files changed:
 .changeset/fn-7834-task-documents-grouping.md      |  7 +++
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/DocumentsView.css     | 38 +++++++++++++---
 .../components/__tests__/DocumentsView.test.tsx    | 50 ++++++++++++++++++++++
 4 files changed, 90 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7834

Fusion-Task-Lineage: 9bac7666-19ba-410b-81dc-d9201a61d0b5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:48:20 -07:00
gsxdsm
49faf0afe2 FN-7832: reorder Task Detail tabs and default terminal picker to task worktree
Reworks the Task Detail terminal experience: the embedded Terminal tab now sits between Comments and Cost, its workspace picker defaults to the task's worktree, and the mobile terminal panel is shorter.

- Move the Terminal tab in Task Detail's tab strip to sit right after Comments and before Cost (previously Cost was earlier and Terminal was near the Session tab)
- TerminalModal now defaults its workspace picker to the useWorkspaces entry whose worktree matches the passed defaultCwd, but only until the operator manually changes the selection; the footer/global terminal still defaults to Project Root since it doesn't pass defaultCwd
- Reduce `.detail-section--worktree-terminal`'s mobile min-height from min(65dvh, 14 * --space-2xl) to min(50dvh, 11 * --space-2xl) so tab context and controls stay reachable above the fold
- Update docs/dashboard-guide.md to describe the new Comments → Terminal → Cost tab order and the worktree-matching picker default
- Add regression tests covering the new tab order and the default terminal workspace selection behavior
- Add a patch changeset describing the user-facing change

Files changed:
 .changeset/FN-7832-task-terminal-picker-and-tab-order.md          |  7 +++
 docs/dashboard-guide.md                                           |  9 +--
 packages/dashboard/app/components/TaskDetailModal.css             |  5 +-
 packages/dashboard/app/components/TaskDetailModal.tsx             | 30 +++++-----
 packages/dashboard/app/components/TerminalModal.tsx                | 19 +++++++
 packages/dashboard/app/components/__tests__/TaskDetailModal.attachments-and-tabs.test.tsx | 15 ++---
 packages/dashboard/app/components/__tests__/TaskDetailModal.worktree-terminal.test.tsx    | 12 ++++
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx                        | 64 ++++++++++++++++++++++
 8 files changed, 134 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-7832

Fusion-Task-Lineage: 4ee67a65-8564-49c9-b93c-8c3eab05c073

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:46:05 -07:00
gsxdsm
6b506f2c97 FN-7829: move terminal action controls into footer and add tab-strip overflow collapse
Relocates the shared terminal action-control cluster into the bottom status-bar footer at every breakpoint and replaces the fixed tablet-viewport tab collapse with a container-width overflow check.

- Move font-size, Clear, Shortcuts, Preferences, connection status, pin, and pop-out controls out of the desktop header into the `.terminal-status-bar` footer at all widths (desktop/tablet/mobile/floating/docked/pinned/embedded), replacing the prior viewport-tier-based split.
- Replace `isTerminalTabletViewport()` with `evaluateTabsOverflow()`, a container-size (ResizeObserver-driven) check with hysteresis that swaps the `.terminal-tabs` strip for the existing mobile-style `.terminal-mobile-tabs` dropdown whenever the tab strip doesn't fit, independent of viewport breakpoint.
- Update TerminalModal.css to match the new footer-first layout and drop now-unused tablet-tier header rules.
- Update dashboard-guide.md terminal usage steps to describe the new always-footer control location and the width-based (not tablet-only) tab dropdown fallback.
- Expand TerminalModal.test.tsx coverage for the overflow-driven tab collapse/expand behavior and footer control placement.
- Add changeset fn-7829-terminal-shortcuts-footer.md (patch, feature) documenting the footer/tab-dropdown change; resolve an add/add conflict on the pre-existing artifacts-doc-editing-and-comment-fix.md changeset by keeping fusion/fn-7829's summary wording.

Files changed:
 .../artifacts-doc-editing-and-comment-fix.md       |   2 +-
 .changeset/fn-7829-terminal-shortcuts-footer.md    |   7 +
 docs/dashboard-guide.md                            |   9 +-
 .../dashboard/app/components/TerminalModal.css     | 121 +++-----
 .../dashboard/app/components/TerminalModal.tsx     | 336 +++++++++++----------
 .../components/__tests__/TerminalModal.test.tsx    | 185 ++++++++----
 6 files changed, 351 insertions(+), 309 deletions(-)

Fusion-Task-Id: FN-7829

Fusion-Task-Lineage: 443c6e69-8946-4307-8a1a-f4f90681a054

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:06:53 -07:00
gsxdsm
79264d4990 FN-7824: auto-reconnect terminal on first launch instead of parking disconnected
Terminal WebSocket sessions now retry with capped backoff through cold-start failures instead of giving up and requiring a manual Reconnect click.

- useTerminal tracks whether a socket has ever successfully opened via hasEverConnectedRef
- a never-connected initial connect ignores MAX_RECONNECT_ATTEMPTS and keeps retrying at capped backoff, staying in the reconnecting affordance until it opens
- mid-session drops (sockets that opened at least once) keep the existing bounded give-up behavior, and permanent 4000/4004 closes remain terminal
- context-change invalidation now uses a ref flag (contextChangedSinceLastEffectRef) consumed inside the effect instead of a transient boolean dependency, avoiding cleanup re-runs that tore down the replacement socket during context-switch/reconnect races
- manual reconnect() and context/session changes reset hasEverConnectedRef so cold-start behavior reapplies per session
- added a patch changeset and expanded useTerminal test coverage for first-launch reconnect vs. mid-session disconnect behavior
- documented the first-launch reconnect behavior in docs/dashboard-guide.md

Files changed:
 .changeset/FN-7824-terminal-first-launch-autoreconnect.md         |   7 +
 docs/dashboard-guide.md                                           |   3 +
 packages/dashboard/app/hooks/__tests__/useTerminal.test.ts        | 208 ++++++++++++++++++++-
 packages/dashboard/app/hooks/useTerminal.ts                       |  34 +++-
 4 files changed, 234 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7824

Fusion-Task-Lineage: 7ed696d0-449e-4dc0-9be0-48b429b8c844

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 18:52:28 -07:00
gsxdsm
26f0c5ae8a FN-7825: add resizable Settings navigation rail with persisted width
Removes the hard divider between the Settings navigation rail and content, keeps section rows single-line with ellipsis overflow, and adds a draggable/keyboard-resizable handle that persists the rail's width in localStorage across the standalone modal and embedded Settings page.

- Add a resize handle (.settings-nav-resize-handle) between .settings-navigation and .settings-content, draggable via pointer events and resizable with ArrowLeft/ArrowRight when focused
- Persist chosen width to localStorage (fusion:settings-nav-width), clamped between 200px and 420px, defaulting to 248px; restore on mount
- Make .settings-navigation the sole owner of rail width via a --settings-nav-width CSS custom property instead of a fixed width, and drop the border-right divider
- Keep nav section labels on one line with white-space: nowrap + text-overflow: ellipsis in both the modal (SettingsModal.css) and embedded (styles.css) nav item styles
- Hide the resize handle on mobile; mobile keeps the stacked section picker unaffected
- Update docs/dashboard-guide.md to describe the new divider-less rail and resize behavior
- Add SettingsModal.navResize.test.tsx covering drag-resize, keyboard-resize, and width persistence
- Add changeset .changeset/fn-7825-settings-nav-resizable.md (minor)

Files changed:
 .changeset/fn-7825-settings-nav-resizable.md                                    |   7 +
 docs/dashboard-guide.md                                                         |   3 +
 packages/dashboard/app/components/SettingsModal.css                             |  56 ++++-
 packages/dashboard/app/components/SettingsModal.tsx                             | 124 +++++++++-
 packages/dashboard/app/components/__tests__/SettingsModal.navResize.test.tsx     | 268 +++++++++++++++++++++
 packages/dashboard/app/styles.css                                               |  27 ++-
 6 files changed, 467 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7825
Fusion-Task-Lineage: 34b940b4-2698-46a4-b47c-cda0b0cac564
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 18:48:59 -07:00
gsxdsm
17d7bd19ef FN-7826: make Task Detail interactive Terminal tab always available
Removes the single-worktree gate on the Task Detail Terminal tab so it renders for every task, defaulting its first shell to the task worktree when present and otherwise falling back to the project root.

- TaskDetailModal.tsx: showWorktreeTerminalTab is now always true (drops the isWorkspaceTask/single-worktree gate and its stale fallback effect); taskWorktreeCwd still feeds defaultCwd when a worktree is recorded, and the tab renders without requiring taskWorktreeCwd
- Adds a changeset documenting the behavior change (minor, feature) for @runfusion/fusion
- docs/dashboard-guide.md: updates the Terminal tab description to state it is always available, with worktree-or-project-root cwd fallback, including for multi-repo workspace tasks
- Expands TaskDetailModal.worktree-terminal.test.tsx coverage for the no-worktree and workspace-task cases now that the tab is always shown

Files changed:
 .changeset/FN-7826-worktree-terminal-always-available.md          |  7 +++
 docs/dashboard-guide.md                                           |  4 +-
 packages/dashboard/app/components/TaskDetailModal.tsx             | 12 ++---
 .../TaskDetailModal.worktree-terminal.test.tsx                    | 57 +++++++++++++++++++---
 4 files changed, 63 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-7826

Fusion-Task-Lineage: f87504fe-9330-4392-bdbe-33bba006d96c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 18:31:14 -07:00
gsxdsm
937650472a FN-7820: add Cost tab to task detail and optional card cost badge
Adds a shared cost-derivation utility and surfaces token/cost info in a new Cost tab on the task detail modal, plus an opt-in per-card cost badge on the board.

- Extract token-cost calculation into a shared taskTokenCost helper (read-time costFor derivation) reused by the Summary tab, new Cost tab, and card badge
- Add TaskDetailModal Cost tab (TaskCostTab.tsx/.css) showing cost breakdown for a task
- Simplify TaskSummaryTab by delegating cost math to the shared helper
- Add default-off project setting showCostBadgeOnCards (settings-schema.ts, types.ts) with a SettingsModal/AppearanceSection toggle
- Add CostBadgeContext to thread the setting into TaskCard without prop drilling
- Show an optional cost badge on TaskCard when the setting is enabled
- Update i18n strings across en/es/fr/ko/zh-CN/zh-TW locales
- Update docs (dashboard-guide.md, settings-reference.md) and add changeset fn-7820-cost-tab-and-card-badge.md

Files changed:
 .changeset/fn-7820-cost-tab-and-card-badge.md      |   7 ++
 docs/dashboard-guide.md                            |   4 +
 docs/settings-reference.md                         |   1 +
 .../core/src/__tests__/settings-defaults.test.ts   |  13 ++
 packages/core/src/settings-schema.ts               |   5 +
 packages/core/src/types.ts                         |   5 +
 packages/dashboard/app/App.tsx                     |   5 +
 .../dashboard/app/components/SettingsModal.tsx     |   6 +
 packages/dashboard/app/components/TaskCard.css     |   7 +-
 packages/dashboard/app/components/TaskCard.tsx     |  27 +++-
 packages/dashboard/app/components/TaskCostTab.css  |  51 ++++++++
 packages/dashboard/app/components/TaskCostTab.tsx  |  91 ++++++++++++++
 .../dashboard/app/components/TaskDetailModal.tsx   |  14 ++-
 .../dashboard/app/components/TaskSummaryTab.tsx    | 123 +-----------------
 .../app/components/__tests__/TaskCard.test.tsx     |  81 +++++++++++-
 .../app/components/__tests__/TaskCostTab.test.tsx  |  55 ++++++++
 .../TaskDetailModal.attachments-and-tabs.test.tsx  |  11 +-
 .../settings/sections/AppearanceSection.tsx        |   8 ++
 .../sections/__tests__/AppearanceSection.test.tsx  |  20 +++
 .../settings-default-descriptions.test.tsx         |   1 +
 .../dashboard/app/context/CostBadgeContext.tsx     |  19 +++
 packages/dashboard/app/hooks/useAppSettings.ts     |  15 +++
 .../app/utils/__tests__/taskTokenCost.test.ts      |  62 +++++++++
 packages/dashboard/app/utils/taskTokenCost.ts      | 139 +++++++++++++++++++++
 packages/i18n/locales/en/app.json                  |  29 ++++-
 packages/i18n/locales/es/app.json                  |  30 ++++-
 packages/i18n/locales/fr/app.json                  |  27 +++-
 packages/i18n/locales/ko/app.json                  |  30 ++++-
 packages/i18n/locales/zh-CN/app.json               |  30 ++++-
 packages/i18n/locales/zh-TW/app.json               |  30 ++++-
 30 files changed, 789 insertions(+), 157 deletions(-)

Fusion-Task-Id: FN-7820

Fusion-Task-Lineage: d33c5678-a68c-4b29-9db1-8ff0369dfd72

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 18:07:00 -07:00
gsxdsm
0a90dc4b55 FN-7821: refresh-then-recheck OAuth credentials before dispatching expiry notifications
Aligns OAuthExpiryMonitor's ntfy push notifications with the /api/auth/status refresh-then-recheck logic that drives the in-app OAuthReloginBanner, so providers that silently auto-refresh (e.g. GitHub Copilot's ephemeral token) no longer trigger false "OAuth token expired" pushes with no matching banner.

- OAuthExpiryMonitor.check() now performs a best-effort authStorage.getApiKey() refresh and reloads/re-resolves the credential before dispatching oauth-token-expired, instead of relying solely on the stored expiry timestamp
- resolveEffectiveOAuthCredential() now also guards against non-finite expires values in addition to non-numeric ones
- Updated docs/dashboard-guide.md and docs/settings-reference.md to describe the refresh-then-recheck behavior generically (not just Claude/Anthropic) and documented the FN-7821 fix in FNXC provenance comments
- Added regression tests covering the refresh-then-recheck flow in oauth-expiry-monitor.test.ts
- Added a patch changeset describing the fix for release notes

Files changed:
 .changeset/fn-7821-oauth-expiry-notification-banner-consistency.md               |   7 +
 docs/dashboard-guide.md                                                          |   6 +-
 docs/settings-reference.md                                                       |   6 +-
 packages/engine/src/notification/__tests__/oauth-expiry-monitor.test.ts          | 146 ++++++++++++++++++++-
 packages/engine/src/notification/oauth-expiry-monitor.ts                         |  48 ++++++-
 5 files changed, 199 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-7821

Fusion-Task-Lineage: 5954592c-adda-4fd4-b205-265860eddf3d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 18:07:00 -07:00
gsxdsm
6317fcddb5 FN-7813: add embedded worktree-rooted multi-tab Terminal to Task Detail
Add an interactive, worktree-rooted, multi-tab Terminal tab to the Task Detail
view, distinct from the pre-existing CLI-agent Session tab.

- TaskDetailModal gains a new embedded Terminal tab (single non-workspace
  task with one recorded worktree) that mounts TerminalModal in a new
  `embedded` render mode, rooted at the task's worktree
- Rename the existing agent-session tab label to "Session" to disambiguate
  it from the new Terminal tab
- useTerminalSessions gains task-scoped session storage and a `defaultCwd`
  option so embedded terminal tabs persist separately from footer/global
  project terminal tabs and start in the task worktree
- TerminalModal/CSS updated to support the embedded layout mode
- Update lazy-loaded-views docs test and AGENTS.md exclusion list to cover
  the new `LazyTerminalModal` task-detail-internal surface
- Document the new Session/Terminal tab split in docs/dashboard-guide.md
- Add i18n strings for the new Terminal tab across all locales
- Add a changeset (minor) for @runfusion/fusion

Files changed:
 .changeset/FN-7813-worktree-terminal-tab.md        |   7 +
 AGENTS.md                                          |   2 +-
 docs/dashboard-guide.md                            |   3 +
 .../app/__tests__/lazy-loaded-views-docs.test.ts   |   4 +-
 .../dashboard/app/components/TaskDetailModal.css   |  17 +++
 .../dashboard/app/components/TaskDetailModal.tsx   |  41 +++++-
 .../dashboard/app/components/TerminalModal.css     |  51 +++++++
 .../dashboard/app/components/TerminalModal.tsx     |  71 +++++++---
 .../__tests__/TaskDetailModal.test-helpers.ts      |   3 +
 .../TaskDetailModal.worktree-terminal.test.tsx     | 139 ++++++++++++++++++
 .../components/__tests__/TerminalModal.test.tsx    |  29 ++++
 .../hooks/__tests__/useTerminalSessions.test.ts    | 157 +++++++++++++++++++++
 .../dashboard/app/hooks/useTerminalSessions.ts     |  63 ++++++---
 packages/i18n/locales/en/app.json                  |   3 +-
 packages/i18n/locales/es/app.json                  |   3 +-
 packages/i18n/locales/fr/app.json                  |   3 +-
 packages/i18n/locales/ko/app.json                  |   3 +-
 packages/i18n/locales/zh-CN/app.json               |   3 +-
 packages/i18n/locales/zh-TW/app.json               |   3 +-
 19 files changed, 550 insertions(+), 55 deletions(-)

Fusion-Task-Id: FN-7813

Fusion-Task-Lineage: 4ef86a15-347a-4862-b01c-5063d8004cb8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00
gsxdsm
56b20a76af FN-7812: extend select-to-comment popover to Task Documents right pane
Adds select-to-comment parity to the Task Documents right pane in the Artifacts view, reusing the existing Project Files selection-comment pattern (useSelectionComment/SelectionCommentPopover) so operators can highlight task-document content and send it to a new task.

- Add markdown/plain preview refs and useSelectionComment hooks scoped to the selected Task Document, following the existing Plain/Markdown render toggle
- Gate the Task Documents selection popover on activeTab === "tasks" and the selected task document (separate from the Project Files popover, which stays gated on activeTab === "project") so tab switches never cross-render popovers
- Compose the New Task description source as `taskId/key` for task-document selections, mirroring the file-path convention used for Project Files
- Add regression tests covering plain/markdown task-document selection, empty-pane gating, tab isolation between Task Documents and Project Files popovers, and the mobile detail pane
- Update dashboard-guide.md to document select-to-comment support for Task Documents alongside Project Files
- Add a minor changeset for @runfusion/fusion documenting the feature (depends on FN-7811)

Files changed:
 .changeset/fn-7812-task-documents-select-to-comment.md            |  7 ++
 docs/dashboard-guide.md                                           |  4 +-
 packages/dashboard/app/components/DocumentsView.tsx                | 37 ++++++---
 packages/dashboard/app/components/__tests__/DocumentsView.test.tsx | 93 ++++++++++++++++++++++
 4 files changed, 130 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7812

Fusion-Task-Lineage: ace10d70-35fd-42fe-8a4a-e2c2c7c7c27b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00