Skip to content

fix(workspace): drag safety net, onDrag/Tooltip, ResizeObserver menu, input border - #2205

Closed
hanlinyu1030 wants to merge 3106 commits into
GCWing:mainfrom
SWangHash:hly/win-bugfix
Closed

hanlinyu1030 wants to merge 3106 commits into
GCWing:mainfrom
SWangHash:hly/win-bugfix

Conversation

@hanlinyu1030

@hanlinyu1030 hanlinyu1030 commented Aug 11, 2026 •

Copy link
Copy Markdown

概述 / Overview
本 PR 包含三个提交,修复工作区会话相关问题:会话标题 i18n 持久化与大小写重复文件夹校验、拖拽 safety net,以及补齐测试 mock。
改动 / Changes

  1. 会话名冲突与大小写重复文件夹 / Session name collision & case-duplicate folder
  • FlowChatManager:hasHistoricalSessions 仅计本工作区会话,避免另一个工作区共享 slug-collided 目录时误报"有历史"从而抑制默认会话创建。
  • NewProjectDialog:新增项目名长度(>255)校验、创建前路径存在/大小写冲突预检(systemAPI.checkPathExists),错误按权限/路径不存在分类显示。
  • session 标题走 i18n key 解析(ChatInput/BtwSessionPanel/ReviewPlatformPanel/ExportImageButton),空会话创建时持久化 title metadata,reload 后可随 locale 重新本地化。
  • TauriCommandError:isPermissionError 扩展 permitted/eperm。
  • locales(en/zh-CN/zh-TW):新增错误 key。
  1. 拖拽 safety net 与 onDrag/Tooltip / Drag safety net & onDrag/Tooltip
  • WorkspaceListSection:加 drag-state safety net(native ghost + window dragend/mousedown + document mousemove + 1.5s timeout + dragover 刷新),防止 dragend 未触发时 is-drag-active 卡住。
  • WorkspaceItem:onDrag prop、拖拽时 Tooltip disabled、ResizeObserver menu popover 重新定位(修复 menu 边缘裁剪)。
  • scss:拖拽时隐藏 inline-actions/branch/menu、:focus outline 抑制;NewProjectDialog 输入 border/overlay 移到 container(.bitfun-input-container)。
  1. 测试 mock 补全 / Test mock fix
  • SessionModule.test:persistenceMocks 与 vi.mock('./PersistenceModule') 补 updateSessionMetadata,修复 4 个 createChatSession 用例(No "updateSessionMetadata" export is defined)。

wsp1911 and others added 30 commits August 3, 2026 18:12
- Add bounded retries and structured refresh outcomes for models.dev downloads.
- Replace the in-memory catalog projection immediately after a successful refresh.
- Emit catalog update events and forward them through peer UI transport.
- Reload catalog data in ModelSelector and AI model settings.
- Add service, runtime, transport, and frontend regression tests.
Discover bounded Claude Code user and project rules with paths front matter, then activate matching instructions after successful workspace reads. Preserve source identity through session history and drop conditional reminders during compaction so later reads can reload current content.
Allow state-based shell-turn tests to tolerate loaded Windows runners while preserving immediate completion and bounded deadlock detection.
- extend remote model selection with present-nullable reasoning presets
- validate presets against the resolved model catalog before atomic updates
- synchronize canonical model and preset selections through catalog polling
- add mobile reasoning controls with backward-compatible capability gating
- cover protocol compatibility, selection forwarding, and catalog invalidation
Register the coordinator local-command persistence port in the narrow session
runtime so usage reports can be saved through the desktop session API.
Add a regression test for the runtime assembly.
- keep usage report turns provisional until persistence succeeds
- return authoritative turn IDs and storage indexes from the runtime port
- reconcile the session catalog and loaded history ranges after persistence
- exclude provisional reports from turn rails and history tail boundaries
- remove failed provisional reports and prevent frontend-only metadata persistence
- document the in-memory and partial-history semantics of dialogTurns
- add regression coverage for partial-history pagination and report persistence
- add recursive validation for preset IDs, budgets, sequences, and request patches
- validate default presets against the projected models.dev catalog
- enforce validation across config loading, updates, resets, and imports
- align duplicate preset resolution between projection and runtime lookup
- add regression coverage for invalid schemas and configuration rollback
Remove the temporary Tao Git patch now that 0.36.0 includes the
Windows keyboard and IME deadlock fix.

Advance the patched Tauri runtime revision to its Tao 0.36 and Wry 0.56
integration while retaining the Windows child-webview focus fix.
- Make the leading-slash command picker follow the current composer text exclusively.
- Limit inline skill-picker synchronization to `$` and non-leading `/` triggers.
- Prevent stale inline-trigger state from reopening the command picker after `/` is deleted or the picker is dismissed.
- Add regression coverage for leading-slash trigger classification.
- preserve the upstream MIT license and add third-party attribution
- record source revision, retrieval metadata, transformation rules, and hashes
- add reproducible snapshot update and offline validation commands
- bundle models.dev notices with Desktop and CLI releases
- enforce provenance validation through repository hygiene checks
- Restore protected nested runtime fields after every JSON Merge Patch.
- Prevent null, scalar, and array replacements from removing generationConfig.maxOutputTokens.
- Add regression coverage for selected presets, model defaults, and preset sequences.
- Verify with adapter tests and workspace cargo check.
Keep TUI lineage reads nonblocking, move settlement validation to the Runtime owner, and make shared IPC reads supersedable and full duplex. Preserve exact cancellation outcomes and fix the confirmed Windows Dispatch test and worktree path portability issues.
- validate reasoning presets against the resolved model catalog
- persist unavailable presets as Auto during create, update, restore, and catalog reconciliation
- keep turn-time fallback as a final safety net
- synchronize automatic preset clearing across Web UI, CLI, and remote projections
- add focused persistence, event, and frontend state tests
Implements the Skin marketplace across desktop, web, backend, agent interactions, deployment assets, shared GitHub authentication, submissions, and review workflows.
- store reasoning presets in controller outbound dispatch records
- project pending and applied presets through target job listings
- restore presets in Web observers while preserving legacy compatibility
- cover explicit auto, follow-up adoption, and restart recovery
- merge tested adapter fallbacks between models.dev and model configuration
- restrict inferred presets to trusted endpoints and known model families
- keep unknown models and custom gateways fail closed
- preserve models.dev authority and model-config override behavior
- verify fallback presets resolve through runtime catalog and client application
- replace the Windows cache atomically without removing the active snapshot
- support BITFUN_MODELS_DEV_PATH as a local runtime catalog source
- preserve the last valid cache when local catalog validation fails
- add focused tests and register Windows dependency ownership
Restore MiniApp/Skin shared GitHub marketplace sessions, accept the canonical OAuth returnTo parameter while retaining legacy compatibility, and document the coordinated deployment contract.
* feat(relay): deploy from published multi-arch image

* fix(relay): prefer verified China image route

* test(relay): smoke published image platforms

* fix(ci): isolate Relay platform smoke pulls
* fix(skin-market): add desktop and website links

* fix(appearance): register manual submission surface
bobleer and others added 20 commits August 10, 2026 19:05
feat(input): show paths in file mentions
…rrors

fix(ai): retry every provider error
Reattaching on every start turned out to be too eager. The browser only
keeps its approval grant while it stays running, so whenever the browser
had restarted since the last connection, BitFun's startup reattach put
an approval dialog in front of the user before they had asked for the
browser at all.

Gate it behind ai.browser_control_auto_connect_on_startup, off by
default, alongside the default CDP row it applies to. The setting's
description says what turning it on does, including the dialog after a
browser restart, and what stays true when it is off: BitFun attaches the
first time an agent needs the browser.
…ect-opt-in

fix(browser): make startup reattach opt-in
The root agent guide only warned about remote SSH workspaces, so changes
routinely shipped complete for the local desktop and incomplete for the
other remote paths: relay-driven remote control (mobile web and IM bots),
Peer Device Mode, and detached Dispatch jobs.

Replace the "Remote compatibility" section with "Remote scenarios":

- A table naming all four scenarios with their design entry points.
- Cross-cutting rules: design the remote path with the feature, degrade
  loudly instead of falling back to the local host, keep blocking prompts
  answerable from a distance, survive disconnect, and treat remote
  workspace paths as POSIX on every client OS.
- Per-scenario obligations pointing at the real enforcement points: the
  remote-workspace policy registry, the RemoteCommand wire protocol and
  bot command router, the three peer deny lists that must stay in sync,
  and the dispatch observer/capability contract.

AGENTS-CN.md is updated to match.
docs(agents): expand remote scenario guardrails
- refresh reasoning projections while editing explicit models.dev bindings
- warn when the active API format cannot reliably apply catalog presets
- add combined provider and model search with ranked multi-keyword matching
- streamline custom preset naming and hide internal preset IDs
fix(settings): streamline copy and align controls
Remote scenarios routinely put two different BitFun versions on one
connection, and users upgrade in place, but the agent guide had no rule
covering either. Add an "Upgrade compatibility" global rule next to the
remote scenarios section, matching what the existing remote-workspace and
transport designs already practice:

- persisted shapes stay tolerant, defaulted, and never repurposed;
- unparseable data degrades instead of being deleted or reset;
- cross-version boundaries advertise and check a capability rather than
  assuming behavior from a package version;
- a rename is a migration, including the data it references;
- upgrade coverage means legacy deserialization and old-payload round
  trips, not only the current shape.

AGENTS-CN.md is updated to match.
The Web UI transport adapter denies 10 controller-owned commands that
neither peer host refuses: the nine `speech_*` capture/model commands and
`dispatch_continue`. The controller-side list is only an optimization —
an older controller build, or any non-Web-UI controller, still reaches a
peer host over HostInvoke, and the host would then run them.

That means microphone capture sessions and speech model file management
executing on the peer instead of the machine the user speaks at, and a
dispatch control-plane verb running against the peer's outbound observer
records and SSH credentials rather than the controller's. Every sibling
dispatch verb is already denied on all three lists; `dispatch_continue`
was simply missed.

Deny both families on the desktop and CLI peer hosts, and add contract
tests covering them.

The README already required these three lists to stay aligned, but
nothing enforced it. Add a peer command policy check to the core boundary
checker that fails when a controller-denied command is missing from either
host list, so the boundary cannot drift again. The check is one-way: a
host denying more than the controller stays allowed. The CLI's four
pre-handled control-plane commands are declared exceptions, and a stale
exception is itself reported.

Verified: cargo test -p bitfun-cli --bins peer_host, cargo test -p
bitfun-desktop --lib peer_host_invoke / remote_workspace_policy, and the
new check both passing on the fix and reporting all 10 commands without it.
Reconnecting to a peer device left the chat blank until the user clicked a
session in the sidebar. Three gaps in `initializeWorkspace`, all reachable
only in Peer Device Mode because `clearAllSessionsForPeerSwitch` is the one
place that bumps the store surface generation:

1. A metadata page loaded across a surface-generation bump is discarded by
   `processPersistedSessionMetadataList`, but the page is still returned
   with its sessions. The caller then sees "history exists" over an empty
   store. Reload once against the settled generation.

2. History was only restored on the auto-select path, so a session that was
   already active but still metadata-only was never hydrated. The breadcrumb
   and turn rail render from the catalog while the message area stays empty
   — the reported symptom. Restore history for an active historical session
   too.

3. When metadata claimed sessions but none were selectable, initialize
   returned true while selecting nothing. The caller reads true as "do not
   create a session", so the surface ended up with neither. Report no
   history so the caller creates against the live workspace instead.

No persisted shape, command, or protocol changes; an older peer host is
unaffected.

Verified: all three tests fail without the fix and pass with it; the 8
existing FlowChatManager cases are unchanged; 252 tests across
src/flow_chat/services pass; pnpm run type-check:web clean.
…r-retries

fix(agent): unify live model retry budget
`browser.wait` read only `duration_ms`, so the very plausible
`{ "ms": 1800000 }` was dropped and the call fell through to a branch that
returned `{ success: true }` instantly. An agent asked to pause 30 minutes
got "Wait completed" back in milliseconds and moved straight on. The
action documented no parameters at all, so the model had to guess the key,
and even a correct guess was silently capped at 30 seconds.

- Accept the spellings models emit: `duration_ms` / `ms` / `wait_ms` /
  `sleep_ms`, plus `seconds` / `secs` variants, numeric strings included.
- Reject a `wait` carrying neither duration nor condition with
  INVALID_PARAMS instead of reporting a success that never waited.
- Raise the cap to 60 minutes, in step with AgentWait's MAX_TIMEOUT_MS, and
  report `ms` / `requested_ms` / `clamped` so a shortened wait says so.
- Race the sleep against the turn's cancellation token, and stop
  `call_impl` from folding Cancelled into an `ok: false` envelope — a stop
  during a long pause must not wait out the pause, nor look like a tool
  error the model tries to recover from.
- Serve duration waits before session resolution: a pure pause touches no
  page, and agents pace themselves long before they open a browser.
- Resolve `{ condition, timeout_ms }`: the condition always wins and any
  duration bounds it, rather than sleeping and never looking at the page.
  Condition waits keep their previous 15s default, now configurable.
- Document all of it in the tool description, and point repeating schedules
  at the Cron tool, which ends the turn instead of pinning it open.
@GCWing

GCWing commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Supplementary PR description

Asked to sweep a set of channels every 30 minutes, a Cowork-mode agent
replied that it had no cron tool and fell back to chaining long `wait`
calls. It was telling the truth: `Cron` was in Claw's tool list and
nowhere else, so in Cowork, Team, DeepResearch, and the four shared
coding modes the agent could not see it at all. Deferred exposure is not
the cause — deferred tools are advertised by name — the tool simply was
not in those modes' `default_tools`.

ControlHub's `wait` documentation now tells the agent to schedule
repeating work with Cron instead of holding the turn open, and ControlHub
ships in all of those modes, so the guidance pointed at a tool the agent
did not have.

- Add `Cron` to Cowork, Team, DeepResearch, and `shared_coding_mode_tools`
  (agentic / debug / multitask / plan), so it is available everywhere
  ControlHub is.
- Cover the pairing with an invariant test over the built-in modes; it
  caught the shared coding baseline, which the first pass had missed.
- Say in ControlHub's description what to do if Cron is genuinely absent,
  rather than leaving a chain of long waits as the silent fallback.

Scheduling stays behind the normal permission gate — Cron is not
read-only and emits a `custom_tool` intent — so this widens what the
agent can propose, not what it can do unattended.
@GCWing

GCWing commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Thank you for your contribution.

The main branch has been replaced with the 1.0.0 codebase from 1.0.0-explore. As part of this migration and Git history cleanup, the affected pull requests have been temporarily closed.

If your changes are still needed, please reapply them on a fresh branch based on the new main, then open a new PR against main or update and reopen this PR. Please link any replacement PR to this one so we can retain the discussion and review context.

We apologize for the disruption and appreciate your understanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.