Commit Graph

4288 Commits

Author SHA1 Message Date
gsxdsm
b8c8642cae FN-5645: fix mission autopilot progression to wait for assertion runs
Fusion-Task-Id: FN-5645

Fusion-Task-Lineage: ed9d2045-2bfe-4070-a7e3-caca010e6cc6
2026-05-28 23:58:47 -07:00
gsxdsm
230efa1cdc FN-5644: default AI merge commit body to summarize changes
Fusion-Task-Id: FN-5644

Fusion-Task-Lineage: 5cf0133b-2a14-4bb4-a1c4-2d5bef5793bc
2026-05-28 23:45:40 -07:00
gsxdsm
6c44ed16e7 chore(release): v0.36.0
Version bump via changesets.
2026-05-28 23:40:25 -07:00
gsxdsm
41ee331429 FN-5648: show in-progress feedback while merging PRs
Fusion-Task-Id: FN-5648

Fusion-Task-Lineage: f056a665-4d52-4472-8495-487a1865aea4
2026-05-28 23:31:03 -07:00
gsxdsm
f5bf7b9b60 FN-5647: remove errant right border on mobile regular chat composer
Fusion-Task-Id: FN-5647

Fusion-Task-Lineage: 278367a7-a3bb-4591-b117-06d17ee71241
2026-05-28 23:27:05 -07:00
gsxdsm
1df1b479dd FN-5640: refresh PR status from Check PR Status footer action
Fusion-Task-Id: FN-5640

Fusion-Task-Lineage: 80074933-2486-4aa6-b23d-1d0e049808cb
2026-05-28 21:40:01 -07:00
gsxdsm
f5cf974504 FN-5639: fix PR panel merge button disabled state
Fusion-Task-Id: FN-5639

Fusion-Task-Lineage: 12a37f9b-895e-4116-b8e1-33315785a42a
2026-05-28 21:32:54 -07:00
gsxdsm
cec191eac3 FN-5638: migrate pi-ai and pi-coding-agent packages to @earendil-works scope
Fusion-Task-Id: FN-5638

Fusion-Task-Lineage: 6e99c156-5f6c-42e6-bd26-618e08ffd05f
2026-05-28 21:23:48 -07:00
gsxdsm
f258a75162 FN-5634: fix ntfy JSON publish priority mapping
Fusion-Task-Id: FN-5634

Fusion-Task-Lineage: 20868ce3-fe31-4638-87f6-83577f46caab
2026-05-28 21:17:02 -07:00
gsxdsm
c1d558c765 feat(FN-5633): AI merge commit summary + task trailers, verify-and-fix, editable prompt
- Commit message: the merge agent writes a concise change-summary subject (not
  just the task title), and every landed squash carries board-association
  trailers — `Fusion-Task-Id: <taskId>` plus the canonical lineage trailer when
  the task has a lineageId — guaranteed via an idempotent amend
  (ensureTaskTrailersOnHead) even if the agent omits them.
- Verify-and-fix: the merge prompt instructs the agent to run the project's
  tests / type-check / lint after resolving the merge and fix any NEW failure
  the merge introduced (not pre-existing breakage) before committing.
- Editable prompt: the AI merge agent's base persona is the editable "merger"
  role prompt (Settings -> Prompts); the clean-room / verification / trailer
  rules are always appended so a custom prompt can't drop them.
- Reviewer model: reviewer uses the project reviewer/validator model lane
  (resolveValidatorSettingsModel); the bespoke merger.reviewerModel setting is
  removed.

Changeset updated to cover all AI merger changes.

Tests: trailer present on landed commit (+ lineage when set), editable-prompt
incorporation, new-breakage verification wording.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 20:14:13 -07:00
gsxdsm
0e5ca34c61 refactor(FN-5633): AI merge reviewer uses the project reviewer/validator model
Drop the bespoke `merger.reviewerModel` setting. The AI merge reviewer now
resolves its model via `resolveValidatorSettingsModel` — the same
reviewer/validator lane used elsewhere (project validator → global validator →
project default) — falling back to the merger model only if that lane is empty.
Removes the setting from the type, schema default, and the Settings UI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 19:53:11 -07:00
gsxdsm
730cee8d61 Remove errant vertical gray line on regular chat input box 2026-05-28 19:52:16 -07:00
gsxdsm
fb27ead6b3 Recovery: re-land PR tab spacing tokens onto main 2026-05-28 19:50:53 -07:00
gsxdsm
b2dce7d852 Recovery: Re-land (Close source-imported GitHub issues on ta 2026-05-28 19:49:31 -07:00
gsxdsm
2c4683a298 Recovery: re-land tablet TaskDetailModal width onto main 2026-05-28 19:45:27 -07:00
gsxdsm
29ac58f8d0 feat(FN-5633): standalone AI merge path (clean-room merge + AI reviewer)
New default merge path (merger.mode="ai"), self-contained in merger-ai.ts and
dispatched from ProjectEngine.onMerge instead of the legacy aiMergeTask pipeline
(kept for merger.mode="deterministic").

Flow: clean-room detached worktree at the target branch tip → AI agent merges
the task branch + squashes (resolving conflicts) → fresh read-only AI reviewer
audits with corrective retries (blocking vs advisory; advisory lands, unfixable
correctness hard-fails via AiMergeBlockedError; fail-safe verdict parsing) →
land via `git merge --ff-only` when the checkout is on the target (else
update-ref CAS) → sync the local checkout (stash → ff → restore; AI reconciles
a conflicting restore and keeps the original edits in a backup stash;
un-stashable dirt advances the ref + warns) → finalize (delete task branch —
never the integration branch — task→done, remove temp worktree).

- Per-task target branch honored (falls back to the default integration
  branch); local checkout synced only when on that target.
- Structurally immune to the dirty-clobber and stale-base/non-FF bug classes of
  the legacy path (clean room + FF-by-construction).
- Progress surfaced on the task status pill + task log stream.
- Clear error when the target branch has no local ref.

Settings: merger.mode / merger.reviewerModel / merger.maxReviewPasses, surfaced
in Settings → Merge; legacy merge-mechanics settings hidden when AI mode is on.

Tests: merger-ai.test.ts (verdict parser, clean merge, blocking hard-fail,
advisory land, empty no-op, target-branch isolation, missing-target error,
landSquash clean/other-branch/dirty-restore/AI-resolved). Legacy
merge-orchestration tests pinned to deterministic mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 18:50:23 -07:00
gsxdsm
200dda95dc feat(FN-5624): suppress transient task.json ENOENT with guard, logging, and
Implements graceful suppression of transient `task.json` ENOENT errors in the executor, logging a suppression signal and surfacing a banner in the UI, with test coverage for both the executor behavior and notification service. Documentation in `docs/architecture.md` and a changeset for `@runfusion/f

Fusion-Task-Id: FN-5624

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5624
2026-05-28 12:10:03 -07:00
gsxdsm
2a3535893b feat(FN-5622): add goals REST API with store accessor and route handlers
Introduces a Goals REST API (`GET/POST/PUT /api/goals` and `GET/PUT /api/goals/:id`) backed by a new `@fusion/core` goal store and typed goal types, including comprehensive route and store test coverage. Documentation on architecture and storage is updated to reflect the new domain, and a changeset

Fusion-Task-Id: FN-5622

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5622
2026-05-28 10:32:16 -07:00
gsxdsm
f13e197371 fix(dashboard): import JSX type from react for OAuthReloginBanner
React 19 removed the global JSX namespace; matches the pattern already used in agentHealth.tsx.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 09:14:33 -07:00
gsxdsm
e84673c632 feat(FN-5618): handle deleted source issues in TaskCard
Implements source issue delete handling in the task dashboard, including prompt-based user interaction for source-linked issues, new GitHub tracking state logic in `packages/dashboard/src/github-tracking-state.ts`, and corresponding test coverage, with documentation added to `docs/task-management.md

Fusion-Task-Id: FN-5618

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5618
2026-05-28 08:57:59 -07:00
gsxdsm
9969b0779b feat(FN-5619): expand PR notice block padding
Adds padding expansion to the PR notice block in PrPanel.css with corresponding test assertions to verify the token values, completing the FN-5619 styling pass.

Fusion-Task-Id: FN-5619

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5619
2026-05-28 08:45:09 -07:00
gsxdsm
0a04837e7a chore(release): v0.35.0
Version bump via changesets.
2026-05-28 08:20:50 -07:00
gsxdsm
d767e2ecbd feat(FN-5601): add OpenAI Responses API type support to custom providers
Added OpenAI Responses API as a new custom provider type, wiring `apiType: "responses"` through the core registry, engine routes, and dashboard UI with a dropdown selector; includes test coverage across the registry, routes, and component layers.

Fusion-Task-Id: FN-5601

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5601
2026-05-27 21:31:12 -07:00
gsxdsm
da34bd06e3 feat(FN-5595): add oauth relogin banner with validity logger
This merge implements an OAuth relogin banner feature (FN-5595) that displays in the dashboard when OAuth tokens expire. The feature includes a new `OAuthReloginBanner` component with styling and tests, an OAuth validity logger in the engine for tracking token state, and corresponding API route inte

Fusion-Task-Id: FN-5595

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5595
2026-05-27 21:31:12 -07:00
Josemi Liebana
6ad18663b8 fix(dashboard): address review comments on PR #1099
- fix(perf): use messagesRef.current in loadMoreMessages to avoid
  recreating callback on every streamed token; messagesRef is already
  kept in sync on every render so no useEffect needed — removes
  `messages` from useCallback deps
- fix(api): reject invalid order query param with 400 instead of
  silently ignoring; valid values are 'asc' and 'desc'

Tests:
- useChat: loadMoreMessages identity is stable when messages array changes
- chat-routes: GET /messages?order=invalid returns 400
2026-05-27 17:38:04 +02:00
Josemi Liebana
d7e4cf7f94 fix(test): update useChat tests for order=desc and before-cursor pagination 2026-05-27 15:24:31 +02:00
Josemi Liebana
599b1ec337 fix(dashboard): scroll-to-bottom button now overrides pending scroll restoration
When the user clicks 'Latest' while loadMoreMessages was in-flight,
the scroll restoration (which maintains position when older messages
are prepended) was undoing the explicit jump-to-bottom.

Fix: clear scrollRestoreSnapshotRef and set isUserScrollingRef=false
before anchorToBottom so the layout effect's restoration is skipped.
2026-05-27 14:43:51 +02:00
Josemi Liebana
6e9ab0e989 feat(dashboard): load latest messages first with order=desc pagination
- Add order?: 'asc' | 'desc' to ChatMessagesFilter (core)
- Route handler passes order param from query string
- Initial load requests order=desc and reverses for display
- loadMoreMessages uses before cursor instead of offset
- hasMoreMessages starts false (prevents IntersectionObserver race)
- ChatView IntersectionObserver guards against messagesLoading
2026-05-27 11:57:21 +02:00
gsxdsm
2f80c6ea7b chore(release): v0.34.0
Version bump via changesets.
2026-05-26 23:45:59 -07:00
gsxdsm
cac08d733b chore(dashboard): fix lint and typecheck
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 22:20:22 -07:00
gsxdsm
6a6c6fdbfd perf(dashboard): speed up startup and eliminate API request storms
Multiple coordinated fixes for the perceived "dashboard takes forever to
load" complaint. Per-page-load HTTP requests drop from ~177 to ~101 and
duplicate per-project InProcessRuntime creation is eliminated.

- engine: shouldUseHybridExecutor no longer auto-enables for local-only
  multi-project setups (set FUSION_HYBRID_EXECUTOR=1 to force). The
  duplicate-runtime path was running self-healing twice per project and
  contending on the same SQLite file. ProjectEngineManager already
  handles N local projects with one InProcessRuntime each.
- dashboard cli: parallelized independent store inits, started
  CentralCore.init early in background, ran plugin loading concurrently
  with extension resolution. Sequenced SQLite store inits to avoid a
  TOCTOU race in addColumnIfMissing migrations across TaskStore /
  AutomationStore / PluginStore / AgentStore (all open the same
  .fusion/fusion.db). Restored try/catch around HybridExecutor.initialize
  and engineManager.ensureEngine so a paused or broken cwd project no
  longer aborts dashboard startup.
- dashboard client: added in-flight request dedupe wrapped around the
  top API offenders. /api/plugins/ui-slots drops from 17x to 1x per load.
  dedupe.forceFresh redirects ALL in-flight waiters to receive the fresh
  post-mutation response, not just the forcing caller. Generation
  counters in useAgents and AgentListModal protect against slow polls
  overwriting fresh state.
- dashboard SSE: agent event handler now debounces 250ms with a
  trailing-edge guard so multi-agent activity bursts coalesce to at
  most 2 refetches per burst.
- dashboard route: PATCH /api/projects/:id with isolationMode change
  returns 503 with actionable guidance when HybridExecutor is
  unavailable, instead of silently persisting a config the live runtime
  won't honor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:57:31 -07:00
gsxdsm
9bea9510c0 Merge pull request #1073 from titosemi/fix/chat-manager-multi-project-routing
fix(chat): use per-project ChatManager for multi-project message routing
2026-05-26 21:57:24 -07:00
gsxdsm
0cabe582aa fix(chat): resolve ChatManager before flushing SSE headers
Move resolveScopedChatManager() before res.flushHeaders() in the
POST /messages route so that failures (e.g. project DB cannot be
opened) produce a proper HTTP error instead of silently closing the
SSE connection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:44:12 -07:00
gsxdsm
e721d8481a Merge origin/main into fix/chat-manager-multi-project-routing
Resolve conflict in register-chat-routes.ts: keep per-project
ChatManager routing via resolveScopedChatManager while preserving
main's resolveProjectChatContext-based store resolution for read
routes. The auto-merged chat-project-services.ts correctly combines
main's fallback-safe resolveProjectChatContext with the PR's new
getOrCreateScopedChatManager cache.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:38:25 -07:00
gsxdsm
903806f6fb Merge pull request #978 from titosemi/fix/chat-view-message-truncation
fix(dashboard): wire scroll-to-top pagination for chat history instead of loading all messages
2026-05-26 21:20:23 -07:00
gsxdsm
aa64643cf1 feat(FN-5589): merge fusion/fn-5589 2026-05-26 17:19:34 -07:00
gsxdsm
4b5a2e5c68 feat(FN-5588): add secrets section navigation to Settings modal
Adds a dedicated Secrets section to the SettingsModal navigation, removes the now-unused secrets footer callback wiring from App and AppModals, updates the related tests, and documents the secrets location in the dashboard guide.

Fusion-Task-Id: FN-5588

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5588
2026-05-26 17:19:34 -07:00
Josemi Liebana
e018701fed fix(dashboard): wire scroll-to-top pagination instead of loading all messages
- Remove fetchAllMessagesInChat/fetchAllMessages helpers
- Keep limit:50 for initial load in useChat and useQuickChat
- Add IntersectionObserver sentinel at top of ChatView message list to
  trigger loadMoreMessages() when user scrolls to the top
- Keep stale-session guards (activeSessionRef checks) from original PR
- Tests: revert assertions back to { limit: 50 }
2026-05-26 21:48:35 +02:00
Josemi Liebana
30e14650cd fix(chat): scope chatStore in stream+messages session guards
The session existence checks in GET /stream and POST /messages were using
options?.chatStore (global DB), so secondary-project sessions would throw
notFound before the scoped ChatManager ran. Replaces with resolveScopedChatStore.
2026-05-26 18:11:44 +02:00
gsxdsm
91b5d77934 Merge pull request #974 from titosemi/fix/chat-sessions-multi-project-scope-clean
fix(dashboard): use per-project chatStore in chat session API routes
2026-05-26 08:27:02 -07:00
Josemi Liebana
d6d5bf098d fix(lint): prefer-const in context.ts; fix GET /sessions/:id isGenerating routing
- context.ts: let engine → const engine (prefer-const lint rule)
- register-chat-routes.ts GET /sessions/🆔 use per-project chatManager
  for isGenerating enrichment (addresses Greptile P2 comment)
2026-05-26 16:58:26 +02:00
Josemi Liebana
0ce1b62809 fix(chat): use per-project ChatManager for multi-project message routing
In multi-project mode the global chatManager was backed by ~/.fusion/fusion.db.
Secondary project chat sessions live in per-project DBs, so
chatManager.sendMessage() failed with 'Chat session not found' for any
project that is not the daemon's CWD.

Fix: add getOrCreateScopedChatManager to chat-project-services.ts (cached by
fusionDir, same pattern as the existing chatStore cache). POST /messages,
GET /stream, POST /cancel, and GET /sessions isGenerating enrichment all
resolve the per-project ChatManager when projectId is provided.

Fallback to global chatManager when no projectId (preserves single-project mode).

Tests: added multi-project chat routing describe block in chat-routes.test.ts.
2026-05-26 16:16:38 +02:00
Josemi Liebana
dae167a127 fix(test): fix 7 test failures in chat-routes and routes-agents suites
Group A (2 failures): resolveProjectChatContext was calling
getOrCreateProjectStore even when no engine existed for the
project. This triggered real FS lookups in tests, causing the
catch to return the default store instead of the engine store.
Fix: only take the engine path when an engine is actually found.

Group B (1 failure): createSSERequest() returned a bare
EventEmitter with no .query property. The refactored handler
reads req.query.projectId at the top, throwing TypeError.
Fix: initialise .query = {} in createSSERequest().

Group C (4 failures): createMockStore() in routes-agents.test.ts
was missing getFusionDir(), which getOrCreateScopedChatStore()
calls to compute the cache key. The resulting TypeError caused
every lookup=resume handler invocation to 500.
Fix: add getFusionDir() to the mock.
2026-05-26 15:58:57 +02:00
gsxdsm
1fb905afb7 feat(FN-5585): add planning branch controls to planning mode modal
Adds planning branch controls to the PlanningModeModal, extending the planning API and routes with supporting tests and documentation. The changeset bumps `@runfusion/fusion` as a minor release.

Fusion-Task-Id: FN-5585

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5585
2026-05-25 16:32:57 -07:00
gsxdsm
5eacd79b43 feat(FN-5584): merge fusion/fn-5584 2026-05-25 15:27:06 -07:00
gsxdsm
e4099f2ff5 Merge pull request #1063 from agustinsacco/feat/editable-agent-name
feat: make agent name editable in review step of creation modal
2026-05-25 14:21:45 -07:00
gsxdsm
629aa29b65 fix(dashboard): use fs.mkdir for cloudflared local-bin fallback on Windows
Replace execFileAsync("mkdir", ["-p", ...]) with fs.mkdir({ recursive: true })
in the cloudflared install fallback path. The -p flag is Unix-only and breaks
on Windows cmd.exe ("A subdirectory or file -p already exists"). Test mocks
updated to verify the fs.mkdir call instead of the shelled-out mkdir.

The original report covered both this site and packages/engine/src/worktree-hooks.ts;
the latter was already converted to fs.mkdir independently, so only the
dashboard route change is needed.

Co-Authored-By: kenlin8827 <kenlin8827@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 13:57:04 -07:00
gsxdsm
8650480622 Merge branch 'main' into fix/chat-sessions-multi-project-scope-clean 2026-05-25 13:28:29 -07:00
gsxdsm
6085e91295 Merge branch 'main' into fix/chat-view-message-truncation 2026-05-25 13:28:27 -07:00
gsxdsm
56e3ee0454 Merge branch 'main' into feat/editable-agent-name 2026-05-25 13:27:40 -07:00