- core/store: include workspaceWorktrees in the slim and activity-log-limited
SELECT lists (rowToTask reads it, but the explicit column lists omitted it, so
slim/limited reads dropped the field and could misclassify workspace tasks);
add regression tests for both read surfaces
- dashboard/register-git-github: validate caller-supplied repoPath in resolveGitDir
via isPathWithin containment check (path-traversal hardening for all git
endpoints); make loadWorkspaceConfig a static @fusion/core import per AGENTS.md
- dashboard/legacy: preserve repoPath in the string-form pullBranch overload
- dashboard/GitManagerModal: revalidate selectedRepo against the fetched repo list
so a stale selection can't persist across project switches
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add GET /api/git/workspace-repos endpoint returning sub-repo list
- Add resolveGitDir() helper: resolves repoPath query param to sub-repo dir
- Update all 34 git endpoints to use resolveGitDir for workspace targeting
- Add repoPath param to 30+ frontend git API functions
- GitManagerModal: auto-detect workspace repos on mount, show repo selector
dropdown at top of sidebar, pass selected repo to all git API calls
- Auto-select first repo when workspace mode is detected
- Repo change triggers data refetch via gitRepoPath dependency
- Add POST /api/projects/detect-workspace endpoint for sub-repo scanning
- Modify POST /api/projects to accept workspaceMode + taskPrefix params
- SetupWizardModal: auto-detect sub-repos when path is entered, show
workspace mode checkbox with detected repo count, add task prefix field
auto-derived from project name
- Wire workspaceMode and taskPrefix through registration API call
Show the dashboard footer when the global AI engine stop control is active.
- Add a stopped executor state derived from globalPause and expose it through the legacy API types.
- Render Stopped with error-red styling and a stop-rectangle icon in the executor status bar.
- Cover stopped state derivation, footer rendering, API responses, and localized labels.
Files changed:
.../dashboard/app/__tests__/api-projects.test.ts | 3 ++-
packages/dashboard/app/api/legacy.ts | 14 +++++++----
.../dashboard/app/components/ExecutorStatusBar.tsx | 11 ++++++---
.../__tests__/ExecutorStatusBar.test.tsx | 27 ++++++++++++++++++++++
.../app/hooks/__tests__/useExecutorStats.test.ts | 22 ++++++++++++++++--
packages/dashboard/app/hooks/useExecutorStats.ts | 10 +++++---
packages/i18n/locales/en/app.json | 1 +
packages/i18n/locales/es/app.json | 2 ++
packages/i18n/locales/fr/app.json | 2 ++
packages/i18n/locales/ko/app.json | 2 ++
packages/i18n/locales/zh-CN/app.json | 2 ++
packages/i18n/locales/zh-TW/app.json | 2 ++
12 files changed, 85 insertions(+), 13 deletions(-)
Fusion-Task-Id: FN-6933
Fusion-Task-Lineage: 1f128b36-105a-4133-87ce-75bb8df8a42f
SKILL.md now renders via MailboxMessageContent (markdown + sanitized HTML + mermaid) instead of raw <pre>. Files strip is compact and lists all files; clicking a file loads its content in the detail pane (markdown via MailboxMessageContent, other text via <pre>, binary/oversized notice) with a Back-to-SKILL.md affordance. New GET /api/skills/:id/file endpoint (readSkillFileContent: path-traversal-guarded, 2MB ceiling, binary detection) + fetchSkillFileContent client fn.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment shape gains authorAvatarUrl + authorIsBot (gh GraphQL Bot/__typename or REST user.type==Bot or [bot] login; avatar from API or github.com/{login}.png, suppressed for bots). New shared CommentsThread (PR + issue) shows author avatar (lucide Bot/User fallback), readable localized timestamp (ISO title), a Human/Bot badge + data-comment-author-type, prev/next chevron nav that scrolls+highlights, and an All/Human/Bot filter defaulting to All.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirrors the PR detail pattern for issues: GitHubClient.getIssueDetail (gh issue view --json comments, REST fallback) + closeIssue (gh issue close, REST PATCH fallback); new POST /api/github/issues/detail + /issues/close routes. The Issues preview fetches comments on selection (cached, non-blocking) and renders them below the body; a Close-issue button in the preview header (open issues only) closes via the API, toasts, and reflects the closed state without dismissing the view.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New POST /api/github/pulls/detail endpoint + GitHubClient.getPullRequestDetail (gh pr view --json comments,statusCheckRollup, REST fallback). On PR select, the preview fetches detail (cached per PR, body never blocked) and renders below the body: a Checks section (each check name + status pill success/failure/pending/neutral, linked to detailsUrl) and a Comments section (chronological, markdown via MailboxMessageContent). Issues tab unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- GitHub import preview shows the full issue/PR body (markdown) + metadata (list already returned full bodies; removed client truncation).
- Task-detail main view: constrain width (no right cutoff); move 'Back to board' into the gray header far right.
- Dock pop-out: smoother touch drag (touch-action:none + captured-element listeners); popping out closes the dock but keeps the floating modal; modal survives dock dismiss.
- Remove duplicate inner headers in Git Manager / Activity Log / Dev Server / Secrets (dock + pop-out chrome already titles them); keep the title on mobile narrow; relocate gm Refresh into the section tab strip.
- Git Manager tabs: one scrollable row of compact icon-only tabs (max visible, scroll if needed).
- List quick entry is single-line (not tall) via singleLine prop; Board unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the bridged `claude` can't authenticate (detached daemon / no keychain),
the turn returns "Not logged in" instead of a real answer. Rather than silently
relay that, detect it and let the user choose.
- Driver: detect a "Not logged in"-only turn and write a cross-process signal
(fusion-acp-bridge-auth.json); a real response clears it (acp-driver test).
- Dashboard status: GET /providers/claude-cli/status reports
acp.authFailed + authReason from the signal.
- UI: the Claude CLI provider card shows an auth-failure banner with
"Use claude -p" (sets experimentalFeatures.claudeCliAcp=false) and
"I fixed auth — re-test", plus a fix hint (run `claude` to log in).
- Enable resolution now recomputes each call with an operator force-override
(FUSION_CLAUDE_ACP_FORCE), so the "Use -p" fallback takes effect on the next
turn — no restart. claude-acp-enable tests updated.
pi-claude-cli + engine tests green; dashboard typecheck clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Title summarization now accepts oversized task descriptions while bounding the model prompt.
- Remove the 2000-character validation ceiling for summarize-title requests.
- Truncate long descriptions only at model-input time with a dedicated exported cap.
- Update route/API docs and tests for long-description behavior.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6305-title-summarize-any-length.md | 5 +++
packages/core/src/__tests__/ai-summarize.test.ts | 43 ++++++++++++++++++----
packages/core/src/ai-summarize.ts | 34 +++++++++++------
packages/core/src/index.ts | 1 +
packages/dashboard/app/api/legacy.ts | 2 +-
.../src/__tests__/routes-planning.test.ts | 25 +++++++++++++
packages/dashboard/src/routes.ts | 2 +-
7 files changed, 92 insertions(+), 20 deletions(-)
Fusion-Task-Id: FN-6305
Fusion-Task-Lineage: 69a83173-ac85-489f-b4cc-d1a70b6d25eb
Fix bug where navigating into an empty folder in the DirectoryPicker
would automatically revert to the previous folder. The useEffect that
auto-fetches on open was using the stale 'value' prop instead of
'browser.currentPath' after navigation.
Also adds a 'New folder' button to the DirectoryPicker toolbar so users
can create folders directly when setting up a project.
- DirectoryPicker.tsx: fix useEffect to use browser.currentPath || value
- DirectoryPicker.tsx: add create folder UI state and handlers
- DirectoryPicker.css: styles for create folder input and actions
- routes.ts: add POST /api/create-directory endpoint
- legacy.ts: add createDirectory API client
- DirectoryPicker.test.tsx: add tests for empty folder nav and create folder
- restore customFields on unarchive; reconcile all occupants on field-schema edits (store.ts)
- serialize per-field saves + controlled inputs in TaskFieldsSection (race fixes)
- fn_workflow_get includes layout; Array.isArray guards in validateCodeNodeSources
- per-instance graphStepActiveContext keying; rebase in instance worktree; clear run-once memo on RETHINK
- GET /api/step-parsers + registry-backed parser select (plugin parsers reachable from editor)
- translate new workflowNodes/workflowFields strings across all 5 non-en locales
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add in-app preflight remediation so Create PR can push task branches without leaving Fusion.
- add a dashboard API route and client helper to push the task branch to origin and recompute PR preflight state
- update the Create Pull Request modal, styles, and tests to surface push-branch remediation alongside AI conflict resolution
- document the flow and add a published CLI changeset plus server coverage for the new push-branch endpoint
Files changed:
.changeset/fn-5950-pr-push-branch.md | 5 +
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/api/legacy.ts | 19 +++
packages/dashboard/app/components/PrCreateModal.css | 4 +-
packages/dashboard/app/components/PrCreateModal.tsx | 48 +++++-
packages/dashboard/app/components/__tests__/PrCreateModal.test.tsx | 44 ++++++
packages/dashboard/src/__tests__/register-git-github.pr-push-branch.test.ts | 176 +++++++++++++++++++++
packages/dashboard/src/routes/register-git-github.ts | 68 ++++++++
8 files changed, 362 insertions(+), 4 deletions(-)
Fusion-Task-Id: FN-5950
Fusion-Task-Lineage: 5a6c5c6a-8f99-44c0-8f54-f0a6ff537ed0
Main independently landed the same pausedReason persistence fix (column in
the task INSERT/upsert, TaskRow type, rowToTask mapping) with the column
ordered between paused and userPaused; adopt main's ordering and drop this
branch's duplicate entries so the values array stays aligned. Union the
dashboard package.json deps (main's compound-engineering plugin alongside
this branch's sorted pi-coding-agent/cli-printing-press/cursor-runtime).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both sides bootstrapped CONCEPTS.md — kept main's broader structure (Missions,
Merge lifecycle, CE sessions) and folded the branch-group vocabulary into its
Merge-lifecycle cluster (enriched Shared branch group + Self-healing sweep;
added Branch assignment mode, Landed, Group promotion). Union-merged core
index/store imports; took main's AGENTS.md discoverability wording. Also adds
execFile to the two child_process test mocks that only stubbed exec (the
coordinator's argv-based git calls now require it).
Add dashboard support for resolving task-branch PR conflicts with AI before PR creation.
- add a dashboard PR conflict resolver that merges the selected base into the task branch, invokes an AI merge session on conflicted files, verifies markers are removed, then commits and pushes the updated branch
- expose a POST /tasks/:id/pr/resolve-conflicts route plus client API/export wiring, docs updates, and a changeset for the published CLI package
- update the Create PR modal UI, styling, and tests to surface preflight conflicts, trigger AI resolution, and refresh preflight state after success
- add API coverage for successful and unresolved conflict-resolution paths and include the new route test in the dashboard API quality shard
Files changed:
.changeset/fn-5949-pr-conflict-resolution.md | 5 +
docs/dashboard-guide.md | 1 +
docs/task-management.md | 1 +
packages/dashboard/README.md | 1 +
packages/dashboard/app/api/legacy.ts | 20 ++
.../dashboard/app/components/PrCreateModal.css | 32 ++-
.../dashboard/app/components/PrCreateModal.tsx | 46 ++++
.../components/__tests__/PrCreateModal.test.tsx | 33 +++
...egister-git-github.pr-resolve-conflicts.test.ts | 186 +++++++++++++++
packages/dashboard/src/index.ts | 5 +
packages/dashboard/src/pr-conflict-resolver.ts | 258 +++++++++++++++++++++
.../dashboard/src/routes/register-git-github.ts | 225 ++++++++++++------
packages/dashboard/vitest.config.ts | 2 +-
13 files changed, 739 insertions(+), 76 deletions(-)
Fusion-Task-Id: FN-5949
Fusion-Task-Lineage: fea35fbf-6254-415c-83cc-0bc24abc911e
CLI prompt nodes now accept a raw cliCommand (any command + args), not just
named scripts. A raw command must be explicitly approved by the user before it
runs: an unapproved command pauses the task (status awaiting-cli-approval) with
the command shown; the user approves via POST /tasks/:id/workflow/approve-cli,
which records the exact command string in settings.approvedWorkflowCliCommands
and resumes. Named scripts (settings.scripts) still never require approval.
Adds POST /tasks/:id/workflow/input to answer await-input nodes (records a
steering comment + resumes).