Commit Graph

116 Commits

Author SHA1 Message Date
gsxdsm
6a13ad175e FN-7732: remove dangling release-authorization UI/i18n/docs scaffolding
Narrative: The triage release-authorization gate itself was already removed in b5b0458; this cleans up the leftover scaffolding it left behind — an unemitted activity type, a dead TaskCard badge/label/CSS, orphaned i18n keys across all 6 locales, and a stale solutions doc — so the codebase no longer references a gate that no longer exists.

- Drop the unused `task:release-authorization-required` ActivityEventType and its label/rendering in ActivityFeed.tsx and ActivityLogModal.tsx
- Remove the dead `isReleaseAuthorizationHold` badge logic and `.awaiting-release-authorization` CSS class from TaskCard.tsx/TaskCard.css
- Simplify TaskDetailModal.tsx comments/logic now that legacy release-authorization holds render as ordinary manual plan-approval holds
- Delete orphaned i18n keys `tasks.awaitingReleaseAuthorization` and `taskDetail.plan.releaseAuthorizationHold` across en/es/fr/ko/zh-CN/zh-TW locales and resources.d.ts
- Delete the stale docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md doc
- Update docs/workflow-steps.md and docs/settings-reference.md to describe the gate as removed (superseded by FN-7732) instead of documenting still-active behavior
- Add changeset for @runfusion/fusion (patch/internal)

Files changed:
 .changeset/fn-7732-remove-release-authorization-block.md |  7 +++++
 docs/settings-reference.md                                |  2 +-
 docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md | 33 ----------------------
 docs/workflow-steps.md                                    |  6 ++--
 packages/core/src/types.ts                                 |  8 ++++--
 packages/dashboard/app/components/ActivityFeed.tsx         |  5 ----
 packages/dashboard/app/components/ActivityLogModal.tsx     |  6 ----
 packages/dashboard/app/components/TaskCard.css             | 11 --------
 packages/dashboard/app/components/TaskCard.tsx              | 13 +++------
 packages/dashboard/app/components/TaskDetailModal.tsx       | 14 +++------
 packages/i18n/locales/en/app.json                           |  3 --
 packages/i18n/locales/es/app.json                           |  5 +---
 packages/i18n/locales/fr/app.json                           |  5 +---
 packages/i18n/locales/ko/app.json                           |  5 +---
 packages/i18n/locales/zh-CN/app.json                        |  5 +---
 packages/i18n/locales/zh-TW/app.json                        |  5 +---
 packages/i18n/src/resources.d.ts                            |  3 --
 17 files changed, 30 insertions(+), 106 deletions(-)

Fusion-Task-Id: FN-7732

Fusion-Task-Lineage: d4137bd8-9056-4062-9f2a-c6f5d47295f4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
a24b0fac1a FN-7721: cap heartbeat worktree-acquisition retries and record exhaustion failures
Bounds durable-agent heartbeat worktree acquisition to a fixed retry count instead of requeuing to todo indefinitely across heartbeat cycles.

- Add MAX_HEARTBEAT_WORKTREE_ACQUISITION_RETRIES (3) in agent-heartbeat.ts, reusing Task.recoveryRetryCount as a cross-heartbeat counter (no schema migration)
- On cap exhaustion, terminally mark the task status:"failed" with an explanatory error, log the entry, and reopen to todo with preserveStatus so the failed status isn't wiped by reopen-to-todo semantics
- Add onTaskAcquisitionExhausted callback wired in in-process-runtime.ts to CentralCore.recordTaskCompletion(taskId, false) so exhausted acquisitions count toward totalTasksFailed
- Add regression tests in agent-heartbeat-worktree.test.ts and in-process-runtime.test.ts covering the retry cap and completion recording
- Add changeset (patch) and a docs/solutions/logic-errors writeup documenting the investigation and other worktree-collision sub-gaps found not to reproduce on HEAD

Files changed:
 .changeset/fn-7721-worktree-heartbeat-retry-cap.md |  7 ++
 docs/solutions/logic-errors/heartbeat-worktree-acquisition-unbounded-requeue.md | 84 ++++++++++++++++++++++
 packages/engine/src/__tests__/agent-heartbeat-worktree.test.ts | 58 +++++++++++++++
 packages/engine/src/__tests__/in-process-runtime.test.ts | 11 +++
 packages/engine/src/agent-heartbeat.ts | 72 ++++++++++++++++++-
 packages/engine/src/runtimes/in-process-runtime.ts | 12 ++++
 6 files changed, 242 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7721

Fusion-Task-Lineage: caad671c-f360-4c1c-8aaa-5b48fca5a55b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:04 -07:00
gsxdsm
0755fc5747 fix(FN-7693): mobile terminal blank — exempt xterm measurement from * { max-width: 100% }
Real root cause of the blank mobile terminal (the FN-7692 remeasure guard did not
fix it and is reverted here). styles.css has a mobile-only reset
`@media (max-width: 768px) { * { max-width: 100% } }` to prevent horizontal
overflow. That universal selector also matches xterm's hidden character-measurement
subtree (`.xterm-helpers` / `.xterm-char-measure-element`). That subtree's containing
block (`.xterm-helpers`) is a 0x0 absolutely-positioned box, so `max-width: 100%`
resolves to `max-width: 0` and hard-caps xterm's character-cell measurement at 0.
FitAddon.fit() then proposes 0 columns/rows and `.xterm-screen` (plus the WebGL
canvas) collapses to 0x0 — the prompt streams in and is written into xterm's row DOM
but paints into a zero-size box, so the terminal is blank. Mobile-only, which is why
desktop always rendered fine.

Reproduced live via mobile emulation: `.xterm-char-measure-element` measured 0 while
an identical monospace span in the same container measured ~295px; `max-width: none`
on the measure element restored ~295px, and reopening the terminal with the exemption
active rendered the prompt with `.xterm-screen` sized 369x760. No amount of
remeasure/refit can fix this — the CSS re-caps the measurement to 0 every time — so
the FN-7692 CharSizeService guard is removed.

- Exempt `.xterm-helpers` / `.xterm-char-measure-element` from the mobile max-width
  reset in styles.css (covers both TerminalModal and SessionTerminal)
- Revert the ineffective FN-7692 remeasure guard and its tests
- Update changeset (patch) and the docs/solutions write-up to the real root cause

Note: root cause + fix validated in the automation browser via mobile emulation
(393px, iPhone UA, forced touch), not a physical device.

Fusion-Task-Id: FN-7693

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:09:26 -07:00
gsxdsm
b7b1b71cae fix(FN-7692): recover blank mobile terminal when xterm screen collapses to 0x0
The mobile terminal rendered blank even though the WebSocket was Connected and
the shell prompt had already streamed in. Root cause (reproduced live): on the
mobile fullscreen layout xterm's CharSizeService can measure a 0-width character
cell, so FitAddon.fit() proposes 0 columns/rows and .xterm-screen (plus the WebGL
canvas) collapses to 0x0 — prompt bytes arrive and are written into xterm's row
DOM but paint into a zero-size box. Renderer-independent and mobile-layout-
specific; not fixed by resize/font-size re-fits because prior guards only validate
the container width and font load, never the resulting measured screen/cell width.

Add guardAgainstCollapsedTerminalScreen (app/utils/terminalPreferences.ts) and arm
it from both terminal surfaces (TerminalModal + SessionTerminal) right after their
initial fit. While the container has a width but .xterm-screen does not, it forces
a genuine DOM-strategy remeasure (forceTerminalFontRemeasure) + fit, re-driven by a
ResizeObserver until the screen has a real width. It waits (does not give up) while
the container is not yet measurable, is bounded so it never spins, and is disposed
on every re-init/close path. Recurrence of FN-7620/FN-7686.

- Add isTerminalScreenCollapsed + guardAgainstCollapsedTerminalScreen with tests
- Wire + dispose the guard across all xterm (re)init/close paths in both surfaces
- Add changeset (patch) and a docs/solutions write-up

Note: reproduced via mobile emulation (393px, iPhone UA, forced touch), not a
physical device; the guard is the structural fix — confirm on a real device.

Fusion-Task-Id: FN-7692

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:22:10 -07:00
gsxdsm
07507f5264 FN-7688: add slow login-shell profile latency hint and docs
Investigated whether --login in TerminalService first-prompt latency is a meaningful contributor and added a one-time diagnostic hint plus documentation of findings.

- Add SLOW_LOGIN_PROFILE_HINT_MS (2000ms) threshold and one-time, non-blocking console.info hint in createSession()'s PTY onData handler when a login shell is slow to produce first output
- Track spawnStartedAt and loginProfileHintLogged per session, and whether the succeeding spawn attempt used --login, without altering spawn args, timeouts, or the retry-without-login fallback
- Add regression tests covering the slow-login-profile hint behavior in terminal-service.test.ts
- Document the investigation and findings in docs/solutions/developer-experience/login-shell-profile-latency.md and link it from docs/dashboard-guide.md
- Add a patch changeset for @runfusion/fusion describing the new server-log hint

Files changed:
 .changeset/fn-7688-login-shell-profile-latency.md  |   7 ++
 docs/dashboard-guide.md                            |  17 +++
 .../login-shell-profile-latency.md                 |  79 ++++++++++++++
 .../src/__tests__/terminal-service.test.ts         | 121 +++++++++++++++++++++
 packages/dashboard/src/terminal-service.ts         |  57 ++++++++++
 5 files changed, 281 insertions(+)

Fusion-Task-Id: FN-7688

Fusion-Task-Lineage: 08d5dd47-ea9f-4973-9f0e-a8d5fdeae111

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 10:06:42 -07:00
gsxdsm
a832b7979f FN-7686: skip redundant session-list round trip on fresh terminal load
Speed up initial terminal load by short-circuiting the no-op server session list call when there are no persisted local tabs to validate.

- useTerminalSessions: when readTabsFromStorage returns zero tabs, skip the listTerminalSessions HTTP call entirely and mark bootstrap ready immediately, unblocking auto-create/WebSocket connect instead of serializing behind a provably-discarded round trip
- Reload-with-persisted-tabs path is unchanged and still awaits the list call since its result is decision-relevant there
- Add regression tests covering the fresh-load fast path and the persisted-tabs path
- Add changeset (patch) and a docs/solutions write-up of the bootstrap-list-serialized-before-auto-create issue

Files changed:
 .changeset/fn-7686-slow-terminal-initial-load.md   |  7 ++
 ...bootstrap-list-serialized-before-auto-create.md | 87 ++++++++++++++++++++++
 .../hooks/__tests__/useTerminalSessions.test.ts    | 73 ++++++++++++++++++
 .../dashboard/app/hooks/useTerminalSessions.ts     | 23 +++++-
 4 files changed, 189 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7686

Fusion-Task-Lineage: 9c708329-6362-4c2e-967f-aea12849c47c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 09:53:39 -07:00
gsxdsm
ca7c987ab5 FN-7621: fix mobile terminal shortcut bar horizontal scroll defeated by ancestor touch-action lock
Root-caused and fixed the third recurrence of the mobile terminal shortcut bar not scrolling horizontally: styles.css's mobile lockdown resets touch-action to pan-y across ancestors, and touch-action's used value is the intersection of the touched element's and every ancestor's value, so the leaf .terminal-shortcut-panel's pan-x was silently defeated even though it was already correct.

- Opt the terminal overlay and modal ancestors (.modal-overlay.terminal-modal-overlay, .modal.terminal-modal--mobile, plain-media-query mobile modal, and the shortcut/status footer) into touch-action: pan-x pan-y so descendant leaf touch-action values can take effect
- Add FNXC:Terminal comments documenting the ancestor-intersection root cause and recurrence history (FN-7550/FN-7560)
- Add a documented solution note under docs/solutions/ui-bugs/ for the ancestor-intersection touch-action pattern
- Add regression tests asserting the modal/overlay/footer ancestors carry the pan-x pan-y opt-in
- Add a changeset for the fix

Files changed:
 .../fn-7621-mobile-terminal-shortcut-scroll.md     |   7 ++
 ...on-ancestor-intersection-defeats-leaf-scroll.md |  57 +++++++++++
 .../dashboard/app/components/TerminalModal.css     |  38 ++++++++
 .../components/__tests__/TerminalModal.test.tsx    | 106 +++++++++++++++++++++
 4 files changed, 208 insertions(+)

Fusion-Task-Id: FN-7621

Fusion-Task-Lineage: 771fd79e-e193-43b0-908b-0e8fe2fc2c70

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:49 -07:00
gsxdsm
8d73b18c35 FN-7620: fix mobile terminal rendering blank via ResizeObserver recovery
Fixes the mobile dashboard terminal sometimes rendering completely blank on open by having TerminalModal recover from a zero/collapsed container box.

- TerminalModal now attaches a persistent ResizeObserver directly on the xterm container, mirroring SessionTerminal's existing pattern
- When the container reports a zero/collapsed box on the first post-open fit, it now re-fits once the real box settles instead of staying stuck at FitAddon's degenerate 2x1-cell floor
- Added regression tests covering TerminalModal and SessionTerminal zero-geometry recovery
- Documented the root cause and fix in docs/solutions/ui-bugs/mobile-terminal-blank-render-zero-geometry-container.md
- Added a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7620-mobile-terminal-blank-render.md |   7 +
 docs/solutions/ui-bugs/mobile-terminal-blank-render-zero-geometry-container.md | 112 +++++++
 packages/dashboard/app/components/TerminalModal.tsx |  49 +++
 packages/dashboard/app/components/__tests__/SessionTerminal.test.tsx |  66 ++++
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx |  358 +++++++++++++++++++++
 5 files changed, 592 insertions(+)

Fusion-Task-Id: FN-7620

Fusion-Task-Lineage: 103f5b17-9a6e-4e9a-ab61-65ccb2203a8d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:48 -07:00
gsxdsm
e347062e1f FN-7603: force xterm DOM-based char measurement to fix mobile terminal spacing
Fixes recurrence #5 of mobile terminal inter-character spacing by unifying xterm's cell-width measurement pipeline with WidthCache's DOM-based glyph measurement, validated against real xterm instead of the jsdom mock.

- Add withDomBasedTerminalCharacterMeasurement() in terminalPreferences.ts: transiently hides window.OffscreenCanvas during terminal.open() so CharSizeService's constructor throws and self-selects its own DOM-based fallback strategy, unifying dimensions.css.cell.width with WidthCache.get('W') measurement
- Wire withDomBasedTerminalCharacterMeasurement() around terminal.open() calls in SessionTerminal.tsx and TerminalModal.tsx
- Add FNXC:Terminal comments documenting the Canvas-vs-DOM measurement divergence root cause, grounded in the installed @xterm/xterm@5.5.0 source
- Add docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md recurrence #5 section
- Expand TerminalModal.test.tsx coverage for the new measurement-forcing behavior
- Add changeset fn-7603-mobile-terminal-spacing.md (patch, fix)

Files changed:
 .changeset/fn-7603-mobile-terminal-spacing.md      |   7 +
 docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md | 101 ++++++
 packages/dashboard/app/components/SessionTerminal.tsx   |  16 +-
 packages/dashboard/app/components/TerminalModal.tsx     |  16 +-
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx    | 363 ++++++++++++++++++++-
 packages/dashboard/app/utils/terminalPreferences.ts     |  63 ++++
 6 files changed, 554 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7603
Fusion-Task-Lineage: 6c7d980f-953e-4fa9-908e-b24125904cbe
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 19:42:16 -07:00
gsxdsm
7c0be5311a FN-7567: re-bake xterm letter-spacing after fit() to fix mobile terminal spacing recurrence
Fixes recurrence #4 of the mobile terminal excess character-spacing bug: SessionTerminal and TerminalModal now force a second genuine xterm font remeasure AFTER fitAddon.fit() settles the post-fit column count, since handleResize() never re-bakes DomRenderer's letter-spacing compensation itself.

- SessionTerminal.tsx: call forceTerminalFontRemeasure() again after fit()/sendResizeMessage() in the resize handler, re-baking spacing against the settled (post-fit) column count instead of the stale pre-fit one.
- TerminalModal.tsx: same second forceTerminalFontRemeasure() call after fitAddon.fit()/sendResize() in its resize handling path.
- Expanded SessionTerminal.test.tsx and TerminalModal.test.tsx coverage to assert the post-fit remeasure occurs.
- Added docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md documenting recurrence #4 root cause (DomRenderer._setDefaultSpacing() never recomputes from handleResize()).
- Added changeset fn-7567-mobile-terminal-spacing.md (patch, category fix).

Files changed:
 .changeset/fn-7567-mobile-terminal-spacing.md      |   7 +
 docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md |  89 ++++++
 packages/dashboard/app/components/SessionTerminal.tsx   |  23 ++
 packages/dashboard/app/components/TerminalModal.tsx     |  43 ++-
 packages/dashboard/app/components/__tests__/SessionTerminal.test.tsx  | 127 +++++++-
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx    | 334 ++++++++++++++++++++-
 6 files changed, 619 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7567
Fusion-Task-Lineage: 5da20522-82d3-4c4d-9008-db71bc5b4d75
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:46 -07:00
gsxdsm
9d4a45b0f9 FN-7561: fix mobile terminal excess inter-character spacing after font settle
Root-cause fix for xterm text rendering with wide inter-character gaps on mobile after fonts settle post-load.
- Added forceTerminalFontRemeasure() in terminalPreferences.ts to work around xterm's OptionsService setter being a no-op when reassigning an already-current fontFamily/fontSize
- Applied the remeasure helper at every post-waitForTerminalFontMetrics() settle site in TerminalModal.tsx and SessionTerminal.tsx
- Added regression tests covering the remeasure invariant across SessionTerminal, TerminalModal, and terminalPreferences
- Documented root cause and fix in docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md
- Added changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7561-mobile-terminal-spacing.md      |   7 +
 docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md | 120 ++++++++++
 packages/dashboard/app/components/SessionTerminal.tsx   |  11 +-
 packages/dashboard/app/components/TerminalModal.tsx     |  11 +-
 packages/dashboard/app/components/__tests__/SessionTerminal.test.tsx  | 108 ++++++++-
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx    | 257 ++++++++++++++++++++-
 packages/dashboard/app/utils/__tests__/terminalPreferences.test.ts    |  55 +++++
 packages/dashboard/app/utils/terminalPreferences.ts     |  38 +++
 8 files changed, 601 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7561

Fusion-Task-Lineage: ad9da396-abf4-46ea-8c60-f2ed40fa4b01

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:44 -07:00
gsxdsm
7300bf54ce FN-7460: disable WebKit text scaling in terminals
Disable WebKit terminal text scaling so iPhone Safari preserves exact xterm cell metrics.

- Set terminal xterm host subtrees to disable text-size adjustment instead of pinning it at 100%.
- Update terminal CSS contract coverage for modal and session terminal surfaces.
- Document the real-iPhone recurrence and add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7460-ios-terminal-spacing.md                 |  7 +++++++
 .../ui-bugs/xterm-async-font-remeasure-paste-dedupe.md     |  7 ++++---
 packages/dashboard/app/__tests__/terminal-input.test.ts    | 14 +++++++-------
 packages/dashboard/app/components/SessionTerminal.css      |  7 +++++--
 packages/dashboard/app/components/TerminalModal.css        |  9 ++++++---
 .../app/components/__tests__/TerminalModal.test.tsx        |  7 +++++++
 6 files changed, 36 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-7460

Fusion-Task-Lineage: 00542017-457b-40b8-9139-084218bc3533

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 07:47:03 -07:00
gsxdsm
8d7abb8c33 FN-7447: fix Android terminal mobile viewport sizing
Fix Android keyboard-open terminal layout by sizing mobile shells from the visual viewport.

- Track visualViewport width in the terminal modal and mobile keyboard detection.
- Apply keyboard-constrained mobile terminal sizing even when CSS media queries see a wider layout viewport.
- Cover Android visualViewport width behavior with modal, session terminal, and hook regressions.
- Document the fix pattern and add a patch changeset for the published Fusion package.

Files changed:
 .../fn-7447-android-mobile-terminal-spacing.md     |  7 ++
 ...ndroid-mobile-terminal-visual-viewport-width.md | 26 ++++++++
 .../dashboard/app/components/TerminalModal.css     | 21 +++++-
 .../dashboard/app/components/TerminalModal.tsx     |  8 +++
 .../__tests__/SessionTerminal.mobile.test.tsx      | 40 +++++++++++-
 .../components/__tests__/TerminalModal.test.tsx    | 76 ++++++++++++++++++++++
 .../app/hooks/__tests__/useMobileKeyboard.test.ts  | 38 +++++++++++
 packages/dashboard/app/hooks/useMobileKeyboard.ts  | 10 ++-
 8 files changed, 222 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7447

Fusion-Task-Lineage: c01faf0f-842e-4632-bf8f-ae54070c3bf8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 13:51:25 -07:00
gsxdsm
18b07b5b7d FN-7388: Fix folded Android terminal mobile sizing
Fix Android foldable terminal surfaces so initial folded panes use mobile viewport geometry.\n\n- Use touch visualViewport dimensions when classifying terminal mobile mode.\n- Apply mobile TerminalModal shell styles outside media queries for folded Android panes.\n- Cover folded Android viewport behavior in terminal and viewport-mode tests.\n- Document the folded viewport baseline invariant and add a patch changeset.\n\nFiles changed:\n .changeset/fn-7388-android-folded-terminal-spacing.md     |  7 +++\n docs/solutions/ui-bugs/mobile-terminal-folded-viewport-baseline.md    |  8 ++-\n packages/dashboard/app/components/SessionTerminal.tsx   | 18 +++++-\n packages/dashboard/app/components/TerminalModal.css     | 37 +++++++++++\n packages/dashboard/app/components/TerminalModal.tsx     | 31 ++++++++-\n packages/dashboard/app/components/__tests__/SessionTerminal.mobile.test.tsx      | 31 +++++++++\n packages/dashboard/app/components/__tests__/TerminalModal.test.tsx    | 73 ++++++++++++++++++++++\n packages/dashboard/app/hooks/__tests__/useViewportMode.test.ts    | 29 ++++++++-\n packages/dashboard/app/hooks/useViewportMode.ts    | 26 +++++++-\n 9 files changed, 251 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7388

Fusion-Task-Lineage: cdf2ef0d-be1f-4414-9113-17ffebdecde5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:33 -07:00
gsxdsm
8f65186bdc FN-7289: fix folded-phone terminal keyboard spacing
Preserve mobile terminal geometry when folded phones open with the keyboard already visible.

- Use layout viewport height when computing keyboard overlap so focused keyboard-open folded postures keep a valid baseline.
- Allow keyboard-closed width/posture changes at short folded heights to refresh the terminal viewport baseline.
- Add regression coverage for TerminalModal and SessionTerminal folded-phone keyboard spacing and document the recurrence.

Files changed:
 .../fn-7289-mobile-terminal-folded-keyboard.md     |   7 ++
 .../mobile-terminal-folded-viewport-baseline.md    |  11 +-
 .../dashboard/app/components/TerminalModal.tsx     |  20 ++--
 .../__tests__/SessionTerminal.mobile.test.tsx      |  30 +++++
 .../components/__tests__/TerminalModal.test.tsx    | 127 +++++++++++++++++++++
 5 files changed, 183 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7289

Fusion-Task-Lineage: 82134835-ca72-4796-89da-c8d071efc481

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 10:53:47 -07:00
gsxdsm
ac87b1e8e4 FN-7281: fix folded terminal viewport baselines
Keep mobile terminals sized against the settled folded viewport before keyboard overlap is applied.

- Re-baseline terminal keyboard metrics when folded devices settle to a new closed-posture width.
- Avoid replacing the baseline from focused keyboard-open samples that would erase real keyboard overlap.
- Cover TerminalModal and SessionTerminal mobile keyboard spacing behavior with regression tests.
- Document the folded-phone terminal spacing fix and add a patch changeset.

Files changed:
 .changeset/fn-7281-mobile-terminal-spacing.md      |  7 ++
 .../mobile-terminal-folded-viewport-baseline.md    | 56 +++++++++++++++
 .../dashboard/app/components/TerminalModal.tsx     | 57 ++++++++++++++--
 .../__tests__/SessionTerminal.mobile.test.tsx      | 39 +++++++++++
 .../components/__tests__/TerminalModal.test.tsx    | 79 ++++++++++++++++++++++
 .../app/hooks/__tests__/useMobileKeyboard.test.ts  | 53 ++++++++++++++-
 packages/dashboard/app/hooks/useMobileKeyboard.ts  | 31 +++++++--
 7 files changed, 309 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7281
Fusion-Task-Lineage: 90ab7398-c583-4312-8cf6-0ef7d6328c8d
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 09:09:29 -07:00
gsxdsm
c17d745665 FN-7109: notify operators when CLI agents await input
Notify external providers when terminal-backed CLI agents pause for tool permission or user input.

- Add a dedicated cli-agent-awaiting-input notification event to settings, schema defaults, dashboard options, and provider tests.
- Dispatch CLI-agent waiting-on-input notifications from the in-process runtime with task context and prompt-scoped dedupe keys.
- Document the operator behavior and add a published package changeset for the new notification surface.

Files changed:
 .changeset/fn-7109-cli-agent-notification.md       |   7 ++
 docs/agents.md                                     |   4 +
 docs/settings-reference.md                         |   4 +-
 .../cli-agent-permission-notifications.md          |  13 +++
 .../core/src/__tests__/global-settings.test.ts     |   1 +
 packages/core/src/settings-schema.ts               |   1 +
 packages/core/src/types.ts                         |   6 ++
 .../SettingsModal.remote-notifications.test.tsx    |   1 +
 .../components/__tests__/settings-mobile.test.tsx  |   2 +-
 .../settings/sections/NotificationsSection.tsx     |   3 +
 .../src/__tests__/in-process-runtime.test.ts       |  56 ++++++++++-
 packages/engine/src/__tests__/notifier.test.ts     |   6 +-
 .../engine/src/__tests__/ntfy-provider.test.ts     |   4 +
 .../engine/src/__tests__/webhook-provider.test.ts  |   2 +
 .../engine/src/cli-agent/__tests__/runtime.test.ts |  39 +++++++-
 .../__tests__/notification-service.test.ts         |  56 ++++++++++-
 .../src/notification/notification-service.ts       |   9 +-
 packages/engine/src/notification/ntfy-provider.ts  |   7 ++
 .../engine/src/notification/webhook-provider.ts    |   2 +
 packages/engine/src/notifier.ts                    |   1 +
 packages/engine/src/runtimes/in-process-runtime.ts | 111 +++++++++++++++++++++
 21 files changed, 326 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7109

Fusion-Task-Lineage: 636c1875-92a2-46a7-847e-1f4955c0822f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 09:28:31 -07:00
gsxdsm
04f8fe5d59 FN-7107: load CE stage skills for interactive sessions
Ensure Compound Engineering stages request and expose their registered skills when launching interactive sessions.

- Add plugin-local skill resolution checks that warn when a stage skill install is missing.
- Pass a stable additional skill path and requested stage skill into every CE interactive session.
- Add coverage for stage skill loading options and update skill reachability expectations.

Files changed:
 ...d-skills-not-loading-in-interactive-sessions.md |  1 +
 .../src/__tests__/skill-reachability.test.ts       | 71 +++++++++++++---------
 .../src/__tests__/stage-skill-loading.test.ts      | 69 +++++++++++++++++++++
 .../src/session/orchestrator.ts                    | 48 ++++++++++++++-
 4 files changed, 157 insertions(+), 32 deletions(-)

Fusion-Task-Id: FN-7107

Fusion-Task-Lineage: 0504e9ba-c2e7-4317-9c90-55693baf8170

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 09:28:30 -07:00
gsxdsm
d9efea9e27 docs(workspace): capture Task-field persistence gotcha learning
Adds a docs/solutions learning: a Task field is silently dropped on persist
unless it has a SQLite column + defineTaskColumn + rowToTask mapping (applyTaskPatch
writes the DB-round-tripped task back over task.json). Plus a CONCEPTS.md entry for
the active-session lease (the path-keyed exclusivity/liveness registry whose key
choice caused the concurrent-workspace collision).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:35:49 -07:00
gsxdsm
4faadd4f75 Merge remote-tracking branch 'origin/main' into conflict-resolution-1712
# Conflicts:
#	packages/dashboard/app/components/WorkflowNodeEditor.tsx
#	packages/engine/src/__tests__/executor-fast-mode-workflows.test.ts
2026-06-23 15:44:52 -07:00
gsxdsm
ec1d29e818 FN-6922: guard worktree acquisition returns from repo root
Prevent task worktree acquisition from handing the project root back to executors.

- Add a repo-root return guard across resume, pool, and fresh acquisition paths.
- Clear invalid repo-root task assignments and create a fresh worktree fallback when safe.
- Share repo-root canonicalization and expand regression coverage for acquisition liveness.
- Document the acquisition guard and add a patch changeset.

Files changed:
 .changeset/fn-6922-repo-root-acquisition-guard.md  |   5 +
 .../repo-root-task-worktree-requeue-loop.md        |   9 +-
 .../__tests__/executor-worktree-liveness.test.ts   |  35 +++
 .../worktree-acquisition-secrets-env.test.ts       |   9 +-
 .../src/__tests__/worktree-acquisition.test.ts     |  91 ++++++-
 packages/engine/src/worktree-acquisition.ts        | 272 +++++++++++++--------
 packages/engine/src/worktree-pool.ts               |   8 +-
 7 files changed, 304 insertions(+), 125 deletions(-)

Fusion-Task-Id: FN-6922

Fusion-Task-Lineage: c16cee1b-de16-4d5f-90e0-132f94fa8377
2026-06-22 19:11:08 -07:00
gsxdsm
68d3c5820e docs(FN-6880): capture optional-group toggle-id collision learning
Document the code-review P1 as a logic-errors learning: a per-task graph
toggle (enabledWorkflowSteps, keyed by optional-group node id) collided with
the legacy step-template namespace and was silently remapped by the store
resolver, bypassing an enabled group. Cross-references the per-task-override
blast-radius cousins as the id-namespace-collision variant of that class.
Seeds an "Optional step group" entry in CONCEPTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 20:33:32 -07:00
gsxdsm
7ee1fec22c FN-6861: reject repo-root task worktrees
Prevent stale task metadata from treating the project repository root as a reusable task worktree.

- Classify root-equal task worktree paths as repo-root before registered-worktree checks.
- Clear stale resumed repo-root assignments so acquisition creates a fresh configured task worktree.
- Add structured executor audit metadata and regression coverage for repo-root liveness collisions.
- Document the repo-root requeue-loop invariant and recovery behavior.

Files changed:
 docs/architecture.md                               |  2 +-
 .../repo-root-task-worktree-requeue-loop.md        | 49 ++++++++++++++++
 .../__tests__/executor-worktree-liveness.test.ts   | 23 +++++++-
 .../src/__tests__/worktree-acquisition.test.ts     | 67 +++++++++++++++++++++-
 .../src/__tests__/worktree-pool-liveness.test.ts   | 25 ++++++++
 packages/engine/src/executor.ts                    | 22 ++++++-
 packages/engine/src/worktree-acquisition.ts        |  4 ++
 packages/engine/src/worktree-pool.ts               | 13 ++++-
 8 files changed, 198 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6861

Fusion-Task-Lineage: d6a4922e-5a21-4037-b2c2-86ff53d8e9e3
2026-06-21 14:28:58 -07:00
gsxdsm
7e478fb473 Merge pull request #1703 from Runfusion/gsxdsm/workflow-optional-steps
feat(dashboard): workflow optional steps — authoring, full-modal parity, stepwise seam
2026-06-21 09:04:39 -07:00
gsxdsm
cb64e874de docs: enrich engine singleton-lock learning after PR #1704 review
- Fix frontmatter enums (root_cause: logic_error, component: tooling); add #1699
  to related_prs and last_updated
- Reflect post-review behavior: external marker cleared at lock-acquire time;
  reconcile/startAll/onProjectAccessed swallow EngineAlreadyRunningError
- Add rejected approach (don't merge has()/hasRunningEngine) and the
  keep-them-distinct invariant
- Tighten socket-name detail (sha1[:16]); cross-link the browser-testing doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 03:35:16 -07:00
gsxdsm
7d312b416d docs: capture engine singleton-lock learning (EngineAlreadyRunningError != no engine)
Document the false "engine not running" banner root cause and fix as a
docs/solutions learning, and add an "Engine Singleton Lock" entry to
CONCEPTS.md: a failed per-machine lock acquisition is proof an engine is
running elsewhere, not "no engine."

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 03:15:22 -07:00
gsxdsm
9479f0b313 docs(solutions): capture eslint exhaustive-deps CI-lint gotcha 2026-06-21 03:10:21 -07:00
gsxdsm
c766bc9c95 FN-6811: keep terminal symbols out of xterm metrics
Keep terminal symbol fonts scoped away from xterm's measured text stacks across modal and session surfaces.

- add a scoped symbols @font-face to the session terminal CSS chunk
- defensively strip the symbols font from resolved xterm font-family presets
- expand modal, session, and CSS regression tests for symbols-free measurement and scoped glyph fallback
- document recurrence #6 and the remaining real-device iOS Safari verification gap

Files changed:
 .../xterm-symbols-nerd-font-unicode-range.md       | 13 ++++--
 .../dashboard/app/__tests__/terminal-input.test.ts | 51 ++++++++++++++++++----
 .../dashboard/app/components/SessionTerminal.css   | 11 +++++
 .../dashboard/app/components/TerminalModal.css     |  3 ++
 .../components/__tests__/SessionTerminal.test.tsx  |  3 ++
 .../components/__tests__/TerminalModal.test.tsx    | 47 ++++++++++++++++++--
 .../dashboard/app/utils/terminalPreferences.ts     | 17 ++++++--
 7 files changed, 127 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-6811

Fusion-Task-Lineage: 15a6fc1f-34c6-44d4-b9ea-8b5b3baae267
2026-06-20 21:02:51 -07:00
gsxdsm
2e3b965909 FN-6757: smooth mobile Quick Chat keyboard resizing
Smooth Quick Chat mobile panel height changes while keeping viewport sampling synchronous.\n\n- Add Android resize-content detection that toggles height easing only for coarse keyboard viewport samples.\n- Clear smoothing and viewport CSS variables on blur, unmount, and suppressed shrink paths.\n- Cover Android smoothing, iOS offsetTop refocus, Latest gate, and streaming state with Quick Chat regression tests.\n- Document the mobile keyboard smoothing behavior and add a published package changeset.\n\nFiles changed:\n .changeset/smooth-mobile-quick-chat-keyboard.md    |   5 +\n docs/dashboard-guide.md                            |   1 +\n .../quick-chat-mobile-keyboard-board-shift.md      |   2 +\n packages/dashboard/app/components/QuickChatFAB.css |   8 ++\n packages/dashboard/app/components/QuickChatFAB.tsx |  17 +++\n .../app/components/__tests__/QuickChatFAB.test.tsx | 141 +++++++++++++++++++++\n 6 files changed, 174 insertions(+)

Fusion-Task-Id: FN-6757

Fusion-Task-Lineage: d301aee8-ef76-4d70-a4cd-91641bb05259
2026-06-20 00:41:36 -07:00
gsxdsm
b9c5b4a2a6 docs: capture gate-mode-drops-coverage learning
Document the test-changed shared-infra catch-all trap (gate mode replaces
affected-package coverage instead of augmenting it) under docs/solutions/,
and add an "Affected-package test selection" concept to CONCEPTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 19:10:27 -07:00
gsxdsm
11c4120705 FN-6659: keep xterm font metrics symbols-free
Keep terminal wide-glyph fallback out of xterm's measured font path while preserving Nerd Font symbols in DOM rendering.

- Split terminal font resolution into symbols-free xterm font families and scoped glyph fallback families.
- Apply the glyph fallback CSS variable to both TerminalModal and SessionTerminal surfaces.
- Update regression coverage and the documented mobile xterm wide-glyph recurrence analysis.

Files changed:
 .changeset/fn-6659-terminal-render.md              |  5 +++
 .../xterm-symbols-nerd-font-unicode-range.md       | 22 +++++++-----
 .../dashboard/app/__tests__/terminal-input.test.ts | 42 +++++++++++++---------
 .../dashboard/app/components/SessionTerminal.css   |  8 +++++
 .../dashboard/app/components/SessionTerminal.tsx   | 21 +++++++++--
 .../dashboard/app/components/TerminalModal.css     |  8 +++++
 .../dashboard/app/components/TerminalModal.tsx     | 13 ++++++-
 .../__tests__/SessionTerminal.mobile.test.tsx      |  6 ++--
 .../components/__tests__/SessionTerminal.test.tsx  | 14 ++++----
 .../components/__tests__/TerminalModal.test.tsx    |  9 +++--
 .../utils/__tests__/terminalPreferences.test.ts    |  2 +-
 .../dashboard/app/utils/terminalPreferences.ts     | 16 +++++----
 12 files changed, 117 insertions(+), 49 deletions(-)

Fusion-Task-Id: FN-6659

Fusion-Task-Lineage: e29a709d-9d9d-4a90-9616-8f08c41b126d
2026-06-18 15:59:34 -07:00
gsxdsm
16b6e5decb FN-6638: stabilize mobile terminal font metrics
Stabilize terminal font metric remeasurement across mobile and attach surfaces.

- Add a shared terminal font metric wait helper that falls back from full font stacks to concrete individual font families before remeasurement.
- Reapply font options, refit, resize, and refresh SessionTerminal after font metrics settle to cover attached CLI terminals.
- Pin text-size adjustment on xterm measurement subtrees so mobile WebKit cannot inflate ASCII cell metrics.
- Extend terminal preference and rendering tests, documentation, and changeset coverage for the recurrence.

Files changed:
 .changeset/fn-6638-terminal-render.md              |   5 +
 .../xterm-async-font-remeasure-paste-dedupe.md     |  20 +++-
 .../dashboard/app/__tests__/terminal-input.test.ts |  26 +++++
 .../dashboard/app/components/SessionTerminal.css   |  10 ++
 .../dashboard/app/components/SessionTerminal.tsx   |  29 ++++++
 .../dashboard/app/components/TerminalModal.css     |  10 ++
 .../dashboard/app/components/TerminalModal.tsx     |  24 ++---
 .../components/__tests__/SessionTerminal.test.tsx  |  41 +++++++-
 .../components/__tests__/TerminalModal.test.tsx    |  38 ++++++++
 .../utils/__tests__/terminalPreferences.test.ts    |  29 +++++-
 .../dashboard/app/utils/terminalPreferences.ts     | 107 +++++++++++++++++++++
 11 files changed, 319 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-6638

Fusion-Task-Lineage: edbf071d-a0c1-4955-95ff-83e6996f4674
2026-06-18 13:19:43 -07:00
gsxdsm
1bd8f6de6f FN-6603: fix mobile terminal font measurement
Stabilize terminal glyph measurement by keeping monospace text fonts ahead of symbols fallbacks.

- Move the Fusion Terminal Nerd Font Symbols face behind real monospace fonts in the shared xterm font stack and terminal presets.
- Document the mobile WebKit cell-measurement hazard and keep SessionTerminal aligned with the shared preference path.
- Add regression coverage for mobile wide-glyph spacing, preference presets, and terminal input rendering.
- Add a patch changeset for the published CLI bundle.

Files changed:
 .changeset/fn-6603-terminal-render.md              |  5 +++
 .../xterm-symbols-nerd-font-unicode-range.md       | 17 ++++++---
 .../dashboard/app/__tests__/terminal-input.test.ts | 42 ++++++++++++++++++++--
 .../dashboard/app/components/SessionTerminal.tsx   |  3 ++
 .../dashboard/app/components/TerminalModal.css     |  5 ++-
 .../__tests__/SessionTerminal.mobile.test.tsx      | 22 +++++++++++-
 .../components/__tests__/SessionTerminal.test.tsx  | 23 ++++++++++--
 .../dashboard/app/utils/terminalPreferences.ts     | 14 +++++---
 8 files changed, 115 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-6603

Fusion-Task-Lineage: b5d90064-1bfd-4da9-8d89-c95cf6fcec0c
2026-06-17 18:48:53 -07:00
gsxdsm
4e47c87c43 FN-6510: preserve last opened quick chat session
Quick Chat now restores the persisted session id without same-target auto-init replacing it.

- Wait for persisted session lookup before auto-initializing the selected quick chat target.
- Skip the first same-target switch after restoring an existing session so the restored id remains authoritative.
- Prefer message activity over metadata-only updates when falling back from stale persisted sessions.
- Cover model, agent, and mobile restoration paths plus hook-level same-target replay behavior.
- Document the quick chat last-session restoration regression and invariant.

Files changed:
 docs/solutions/ui-bugs/quick-chat-last-opened-session-restore.md      |  60 ++++++++++
 packages/dashboard/app/components/QuickChatFAB.tsx                   |  23 +++-
 packages/dashboard/app/components/__tests__/QuickChatFAB.test.tsx    | 130 ++++++++++++++++++++-
 packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts          |  38 ++++++
 4 files changed, 246 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-6510
Fusion-Task-Lineage: 135807dd-30f3-4032-9de8-f34927e5c44d
2026-06-17 01:22:21 -07:00
gsxdsm
f14f9b2e45 FN-6516: preserve tablet chat sidebar width during typing
Keep tablet chat sidebars visible at the persisted width while the software keyboard is open.

- Preserve the non-mobile sidebar inline width instead of forcing tablet keyboard sessions to the minimum width.\n- Extend ChatView tablet viewport tests for default, persisted custom, and collapsed-sidebar keyboard states.\n- Document the FN-6516 refinement in the tablet keyboard viewport solution note.\n\nFiles changed:\n .../ui-bugs/tablet-keyboard-viewport-mode-flip.md  |  2 +\n packages/dashboard/app/components/ChatView.tsx     |  9 ++--\n .../__tests__/ChatView.mobile-render.test.tsx      | 55 ++++++++++++++++++----\n 3 files changed, 53 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6516

Fusion-Task-Lineage: 51927ebb-3a9e-4dc5-827a-33c76a142335
2026-06-16 23:21:14 -07:00
gsxdsm
602fefff19 FN-6498: smooth mobile quick chat viewport tracking
Keep the mobile Quick Chat sheet aligned with visualViewport changes without redundant layout writes.

- Dedupe repeated mobile visualViewport samples before updating sheet CSS variables.
- Reset viewport tracking state and CSS variables on close/unmount to prevent stale reopen sizing.
- Add regression coverage for mobile tracking, reopen behavior, desktop bypass, and missing visualViewport fallback.
- Document the viewport-smoothing pitfall alongside the keyboard board-shift solution.

Files changed:
 .../quick-chat-mobile-keyboard-board-shift.md      |   4 +
 packages/dashboard/app/components/QuickChatFAB.tsx |  25 +++-
 .../app/components/__tests__/QuickChatFAB.test.tsx | 141 +++++++++++++++++++++
 3 files changed, 167 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6498

Fusion-Task-Lineage: 23c17843-778a-4337-aeed-c80793615738
2026-06-16 21:25:39 -07:00
gsxdsm
b85d02add0 Merge pull request #1682 from Runfusion/feature/acp-route-a-followups
feat(acp): Route A follow-ups — token usage, opt-in headless auth, status tests + bridge-auth learning
2026-06-17 06:12:06 +08:00
gsxdsm
0093678ee6 FN-6481: require release triage authorization
Block release-class tasks from automatic triage dispatch unless they come from a user-authored source with explicit authorization.

- Add release intent classification and authorization-marker enforcement before final triage transitions.
- Record activity/log details when release tasks are parked awaiting manual approval.
- Surface the new release-authorization activity in dashboard activity views.
- Cover release gating behavior with engine tests and document the architecture pattern.
- Add a changeset for the published CLI package.

Files changed:
 .changeset/fn-6481-release-triage-authorization.md |   5 +
 .../release-triage-requires-user-authorization.md  |  33 +++++
 packages/core/src/types.ts                         |   2 +
 packages/core/vitest.config.ts                     |   4 +
 packages/dashboard/app/components/ActivityFeed.tsx |   5 +
 .../dashboard/app/components/ActivityLogModal.tsx  |   6 +
 .../__tests__/triage-release-authorization.test.ts | 158 +++++++++++++++++++++
 .../engine/src/triage-release-authorization.ts     | 100 +++++++++++++
 packages/engine/src/triage.ts                      |  51 +++++++
 scripts/lib/test-quarantine.json                   |   8 +-
 10 files changed, 371 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6481
Fusion-Task-Lineage: 0bddb77a-87e5-4fa5-b31a-e773bdae7a29
2026-06-16 15:08:24 -07:00
gsxdsm
65c49585d1 fix(review): address PR #1682 re-review (reuse concurrency + auth hardening)
- P1 (Greptile): a tool-use break-early turn released the warm connection
  (inUse=false) while conn.prompt() was still pending, letting the next turn
  launch a concurrent prompt on the same ACP session (protocol corruption).
  keepWarm now requires !sawToolCall, so a tool-use turn tears the connection
  down like the non-reuse path; only a clean stop turn (prompt fully resolved
  before finish) keeps it warm. + test.
- buildBridgeEnv: treat a whitespace-only auth var as absent (v.trim()), so a
  blank higher-preference token can't shadow a real lower-preference one and we
  never forward a useless blank token. + test.
- Auth-forwarding tests: clear ambient auth vars in beforeEach so a runner-env
  token can't shadow the case under test (CodeRabbit).
- Doc: clarify the allow-list never carries API keys by default; the single
  FUSION_CLAUDE_ACP_FORWARD_AUTH opt-in (default OFF) is the only exception.

348/348 pass, tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:52:58 -07:00
gsxdsm
ffef0aad6a docs(solutions): ACP bridge 'Not logged in' — thin spawn env + keychain session isolation
Compound learning: the claude-code-cli-acp bridge returned 'Not logged in'
despite a working claude -p, due to (1) a too-thin spawn env (needs XDG_*/USER/
SHELL beyond HOME/PATH) and (2) macOS login-Keychain session isolation for
detached/headless processes. Six headless tasks misdiagnosed it as an upstream
gap. Cross-linked from the ACP runtime integration pattern doc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:15:38 -07:00
gsxdsm
6bb120525d FN-6424: scope terminal symbols font glyph ranges
Prevent the terminal symbols font from corrupting ASCII cell measurement on mobile.\n\n- Add unicode-range scoping to the Fusion terminal Nerd Font symbols face.\n- Cover the CSS contract so symbols ranges include Nerd Font blocks and exclude printable ASCII.\n- Document the xterm font-loading regression and required verification path.\n\nFiles changed:\n .../xterm-symbols-nerd-font-unicode-range.md       | 63 ++++++++++++++++++++++\n .../dashboard/app/__tests__/terminal-input.test.ts | 49 +++++++++++++++++\n .../dashboard/app/components/TerminalModal.css     |  5 ++\n 3 files changed, 117 insertions(+)

Fusion-Task-Id: FN-6424

Fusion-Task-Lineage: 7350c926-1d51-474b-bfc3-a17f922b9322
2026-06-13 20:46:54 -07:00
gsxdsm
7040cd3511 docs: capture mobile .visually-hidden scrollWidth bug in solutions
Document the root cause (offset-less position:absolute sr-only utility
escaping the kanban board's overflow clip and inflating
documentElement.scrollWidth → iOS shrink-to-fit zoom), the top/left:0 fix,
and the CSS-fixture regression guard. Cross-links the sibling mobile
viewport-containment learnings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 17:26:12 -07:00
gsxdsm
1db4835d1d FN-6390: fix terminal font remeasure and paste handling
Fix terminal rendering and input delivery at the xterm font and paste seams.

- Remeasure TerminalModal xterm instances after the terminal web font finishes loading.
- Let xterm native paste handle Cmd/Ctrl+V so clipboard input is delivered once.
- Add regression coverage for modal and session terminal paste/font behavior.
- Document the xterm async font and native paste solution.

Files changed:
 .../xterm-async-font-remeasure-paste-dedupe.md     |  59 +++++++++
 .../dashboard/app/components/TerminalModal.tsx     |  60 +++++++--
 .../components/__tests__/SessionTerminal.test.tsx  |  31 +++++
 .../components/__tests__/TerminalModal.test.tsx    | 140 ++++++++++++++++++---
 4 files changed, 264 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-6390

Fusion-Task-Lineage: f041a058-73c5-40fc-b390-c20bdb3bad69
2026-06-13 16:30:28 -07:00
gsxdsm
7fa8c4e5f4 FN-6397: fix mobile workflow board fill chain
Ensure workflow-mode boards fill the mobile viewport while preserving internal column scrolling.

- Reassert the mobile flex fill chain for project content, workflow board wrappers, and workflow columns.
- Extend mobile board regression coverage across empty/populated workflow states with and without the toolbar.
- Document the workflow board collapse root cause and add a transient temp-dir isolation guard test.

Files changed:
 docs/dashboard-guide.md                            |   1 +
 .../ui-bugs/mobile-workflow-board-fill-chain.md    |  61 +++++++++++++
 .../__tests__/board-mobile-initial-render.test.tsx | 101 +++++++++++++++++++++
 packages/dashboard/app/styles.css                  |  52 +++++++++++
 scripts/__tests__/check-test-isolation.test.mjs    |  23 +++++
 scripts/check-test-isolation.mjs                   |  12 ++-
 6 files changed, 249 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6397
Fusion-Task-Lineage: ddee773d-6d3a-46d1-b1c7-f601a961365e
2026-06-13 16:30:28 -07:00
gsxdsm
eea33639ee FN-6378: contain mobile board overscroll
Contain horizontal overscroll on mobile kanban board scrollers so iOS edge drags do not rubber-band columns off screen.

- Add horizontal overscroll containment to board, workflow column, and lane column scrollers while preserving proximity snap scrolling.
- Add CSS fixture regression coverage for mobile/base board and lane overscroll containment.
- Document the iOS horizontal overscroll containment root cause and fix.

Files changed:
 ...-board-ios-horizontal-overscroll-containment.md | 64 +++++++++++++++++++++
 .../board-mobile-overscroll-containment.test.ts    | 65 ++++++++++++++++++++++
 packages/dashboard/app/components/Lane.css         |  2 +
 packages/dashboard/app/styles.css                  |  1 +
 4 files changed, 132 insertions(+)

Fusion-Task-Id: FN-6378

Fusion-Task-Lineage: 70b4852b-feb0-42b5-81ba-13bfd143e0bc
2026-06-13 11:53:44 -07:00
gsxdsm
88e25dc9f4 FN-6365: prevent mobile document horizontal panning
Contain the mobile dashboard document viewport while preserving intended inner horizontal scrollers.

- Lock mobile html/body/#root and fullscreen overlay chrome to the viewport inline axis.
- Default mobile touch handling to vertical-only panning and opt board/code/table scrollers back into horizontal gestures.
- Add CSS fixture regression coverage plus a solution note for mobile horizontal pan containment.

Files changed:
 docs/solutions/ui-bugs/mobile-horizontal-pan-document-viewport-containment.md |  62 +++++++++++
 packages/dashboard/app/__tests__/mobile-horizontal-pan-containment.test.ts    | 116 +++++++++++++++++++++
 packages/dashboard/app/styles.css                                            |  47 +++++++--
 3 files changed, 219 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-6365

Fusion-Task-Lineage: 4673da28-1438-4ea5-b32c-25bc52285273
2026-06-13 11:22:07 -07:00
gsxdsm
38007db549 FN-6364: reset iOS mobile viewport on restore
Recover stale iOS document scroll after returning to the Fusion dashboard.

- Add an iOS-only restore hook that clears orphaned body offsets and scrolls the document back to the origin when unlocked.
- Wire the restore reset from the dashboard app shell for mobile layouts.
- Cover visible/page-show restores, platform no-ops, active-lock guards, and orphaned style cleanup.
- Document the mobile restore drift solution for future regressions.

Files changed:
 .../mobile-ios-restore-document-scroll-drift.md    |  59 ++++++++++
 packages/dashboard/app/App.tsx                     |   4 +-
 .../hooks/__tests__/useMobileScrollLock.test.ts    | 121 ++++++++++++++++++++-
 .../dashboard/app/hooks/useMobileScrollLock.ts     |  61 +++++++++++
 4 files changed, 243 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-6364

Fusion-Task-Lineage: 9243cab8-5fbb-4332-ac4d-aabefde4161c
2026-06-13 10:29:24 -07:00
gsxdsm
fb102a86d5 FN-6362: reset mobile keyboard restore metrics
Reset mobile keyboard restore sampling so collapsed viewports clear stale keyboard-open metrics.

- Add a restore-specific sampling path for visibilitychange/pageshow that can reset the viewport baseline and bypass the impossible-sample hold once.
- Preserve the existing in-session impossible-sample guard and tail polling behavior for normal focus/resize updates.
- Cover iOS restore, stale offset drift, genuinely open restored keyboards, and Android-style shrink reset cases.
- Document the mobile keyboard restore stale viewport fix for future UI debugging.

Files changed:
 .../mobile-keyboard-restore-stale-viewport.md      |  59 ++++++++
 .../app/hooks/__tests__/useMobileKeyboard.test.ts  | 160 +++++++++++++++++++++
 packages/dashboard/app/hooks/useMobileKeyboard.ts  |  75 +++++++---
 3 files changed, 275 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-6362

Fusion-Task-Lineage: 3919d892-b2d5-419a-abeb-84ac298ca2d5
2026-06-13 10:14:11 -07:00
gsxdsm
869a4f77da FN-6329: prevent Quick Chat keyboard board shift
Keep the mobile board layout stable while Quick Chat owns the keyboard viewport.

- Treat fullscreen mobile overlays as suppressors for App-level footer hiding.
- Pass Quick Chat mobile open state into the shared keyboard flag helper.
- Cover iOS, Android, modal, and non-mobile keyboard flag behavior.
- Document the Quick Chat mobile keyboard board-shift root cause and fix.

Files changed:
 .../quick-chat-mobile-keyboard-board-shift.md      | 58 ++++++++++++++++++++++
 packages/dashboard/app/App.tsx                     |  4 +-
 .../utils/__tests__/mobileBarKeyboardFlags.test.ts | 57 ++++++++++++++++++++-
 .../dashboard/app/utils/mobileBarKeyboardFlags.ts  | 10 +++-
 4 files changed, 126 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6329

Fusion-Task-Lineage: f7c37252-c0ea-44f0-b4e3-5aa2022cf7bc
2026-06-12 19:22:11 -07:00
gsxdsm
c0ff360737 FN-6243: keep mobile auto-merge toggles visible
Keep the mobile dashboard pinned while offscreen auto-merge controls are toggled.

- Reset document horizontal scroll during mobile board stabilization and immediately after auto-merge toggles.
- Cover portrait and landscape mobile scroll realignment in the auto-merge integration test.
- Document the real-browser blank-dashboard root cause and add a patch changeset.

Files changed:
 .changeset/FN-6243-mobile-auto-merge-blank.md      |  5 ++
 ...bile-auto-merge-toggle-document-scroll-blank.md | 55 ++++++++++++++++++++++
 packages/dashboard/app/components/Board.tsx        | 47 ++++++++++++++++--
 ...-merge-toggle-blank.mobile-integration.test.tsx | 49 +++++++++++++++++++
 4 files changed, 152 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6243

Fusion-Task-Lineage: 91f74de2-667f-4732-a840-47b792288bec
2026-06-11 21:26:59 -07:00