1.0.0 explore - #2517
Merged
Merged
Conversation
…op dead AgentService - Add eslint no-restricted-imports fence: business code must reach the platform only via api.invoke (ApiClient); direct invoke from '@tauri-apps/api/core' is reserved for adapters/** and the intentional PeerHostInvokeBridge exception. - Reroute 8 A-class modules (insights, i18n, companion pet, announcement, file/image context, ide-control event bus) from direct invoke to api.invoke. - Delete the dead legacy agent-service.ts wrapper (no consumers) and its FlowChatManager field/import/initialization, the orphaned getAvailableAgents() method, and its test mock. Co-Authored-By: Claude <noreply@anthropic.com>
Remove 11 files and prune the api barrel of entries with no real consumers anywhere in src (verified by full-tree grep + dynamic import + bitfunAPI.<prop> access). Follow-up to 433f601 which dropped the legacy agent-service.ts. Deleted (11 files): - infrastructure/services/ dead chain (5): business/agentService.ts, infra/contextManager.ts, infra/index.ts, api/index.ts (broken barrel exporting non-existent contextService), index.ts (barrel with no importer) - infrastructure/api/service-api/ProjectAPI.ts + GitRepoHistoryAPI.ts (only referenced inside the dead bitfunAPI collection) - shared/crypto/ (e2e-encryption.ts + index.ts, no @/shared/crypto import) - infrastructure/agents/constants.ts (BUILTIN_SUB_AGENT_IDS/isBuiltinSubAgent) - shared/context-menu-system/examples/FileTreeIntegrationExample.tsx Barrel edit (infrastructure/api/index.ts): drop the dead bitfunAPI collection object, its default export, the GitRepoHistory type re-export, and the projectAPI/gitRepoHistoryAPI imports; keep the 23 re-exports that have real consumers. Sync the eslint examples/** ignore to the deleted example dir. Conservatively retained: - ContextAPI.ts: contextAPI loses its only consumer (ContextManager) but wraps backend session commands (compress_context/save_session_data/...) — cross-layer decision, pruned from bitfunAPI but file kept. - Method-level dead code (~60 methods across RemoteConnectAPI/MiniAppAPI/ SubagentAPI/AgentAPI/etc): TS wrapper dead != Rust handler dead; deferred to a follow-up batch that checks the backend command table per method. Verified: tsc --noEmit introduces no new errors (only a pre-existing, unrelated websocket-adapter GitTrustReport import error remains); eslint src clean; vitest failures pre-exist on baseline (jsdom localStorage env issue). Co-Authored-By: Claude <noreply@anthropic.com>
…gaps Address PR GCWing#2428 review (CHANGES_REQUESTED): - Declare LOCAL_ONLY owners for i18n/announcement/companion-pet/insights/ IDE-control/browser/webview/devtools/desktop-pet commands routed to peer without an owner; cross-device routing regressed controller app-shell state. - Add SIDE_EFFECTING_GET_COMMANDS so get_pending/get_announcement_tips (scheduler-mutating reads) are never auto-retried by the peer read path. - Add no-restricted-syntax ImportExpression selector to the ESLint fence so dynamic import('@tauri-apps/api/core') bypasses fail the build too. - Migrate all ~30 pre-existing dynamic-import sites to api.invoke (15 files); each command's peer-vs-local owner is declared to preserve behavior. - FileContextImpl: fs_exists -> check_path_exists (peer-routed, CLI-peer supported) so file-tree path checks resolve on the rendered surface. - PanelController: route report_ide_control_result success branch through api.invoke so both branches use the same LOCAL_ONLY transport. Verified: eslint src -> 0 errors; peer-device-adapter.test.ts 39/39 passed. Co-Authored-By: Claude <noreply@anthropic.com>
The core-boundaries check enforces a one-way ownership boundary: every command the FE adapter marks LOCAL_ONLY must also be refused by each peer host, because an older or non-Web-UI controller can still HostInvoke them. The previous commit added i18n/announcement/companion-pet/insights/IDE- control/browser/webview/devtools/desktop-pet/diagnostics commands to the FE deny list but not to the desktop and CLI peer-host deny lists, so CI's "Check core boundaries" step failed. Add the 37 controller-owned commands to both src/apps/desktop/src/api/peer_host_invoke.rs and src/apps/cli/src/peer_host/deny.rs, grouped with owner comments mirroring the FE adapter. Being unimplemented on the CLI peer is not the boundary — they are refused explicitly. Verified: check-core-boundaries -> passed; check-core-boundaries.test -> 126/126; cargo test -p bitfun-desktop peer_host -> 6/6; cargo test --bin bitfun peer_host -> 79/79. Co-Authored-By: Claude <noreply@anthropic.com>
The dynamic-import migration moved useDebugInspector and
agentCompanionPetCommands off `@tauri-apps/api/core` and onto
`api.invoke`, but their tests still mocked `@tauri-apps/api/core`, so the
mock never intercepted the call. CI "Run web UI tests" failed:
- useDebugInspector.test.tsx: expected mocks.invoke to be called with
'debug_devtools_available' but it was called 0 times.
- agentCompanionPetCommands.test.ts: api.invoke('show_main_window') hit the
real ApiClient (WebSocket connection failed).
Repoint both tests at `@/infrastructure/api/service-api/ApiClient` (the
established pattern) and flush the post-invoke microtask in
useDebugInspector before dispatching keys, since the keydown listener now
registers right after the (synchronous) api.invoke resolves rather than
after the old dynamic-import microtask.
Verified: useDebugInspector 4/4, agentCompanionPetCommands 7/7.
Co-Authored-By: Claude <noreply@anthropic.com>
…arden adapter fence Address PR GCWing#2428 review round 3 (issues #1-GCWing#3): 1. CLI peer host lacked a `cancel_tool` route. Expose `cancel_tool` on `CoreAgentRuntimeCompatibility` (delegates to the coordinator), add the CLI dialog handler + dispatch branch, and advertise the `cancel_tool` capability in both desktop and CLI `peer_mode_ping`. 2. CLI peer host lacked a `get_all_tools_info` route and the tool-info DTO was duplicated between desktop and core. Add a shared `ToolInfoDto` + `build_tool_info`/`build_all_tools_info` in core (backed by the global tool registry), a thin CLI `tools` handler + dispatch branch, and the `tool_catalog` capability in both `peer_mode_ping` surfaces. Desktop's `tool_api` now aliases the core DTO instead of redefining it. 3. The ESLint adapter fence leaked: a global `ignores` entry for `src/shared/context-system/core/types/**` let direct/dynamic `invoke` imports pass lint there. Drop the blanket ignore and add a targeted override that exempts only `react-hooks/rules-of-hooks`; the fence rules now apply. Add a config-level regression test pinning that both the ordinary business dir and the context-system types dir block invoke, while the adapter exception still permits it. Frontend: propagate `cancelTool`/`toolCatalog` capabilities through the peer-device snapshot/context, gate the Terminal interrupt button and the tool-catalog fetches (useAgentsList, AssistantDefaultsPage) on host support; default to allowed when capabilities are unknown to avoid flicker. Co-Authored-By: Claude <noreply@anthropic.com>
…adapter surface PR GCWing#2428 review GCWing#4 (limityan, 2026-08-25). All but the truncated PR-title P3. P1: - Browser Control / Computer Use now run on the host that runs the Tool: removed browser_control_*/computer_use_get_status/request_permissions/ open_system_settings from FE + Desktop LOCAL_ONLY; CLI deny.rs already refuses them. Desktop Peer B bridges to its own webview (reads B's browser/OS); SessionConfig surfaces an explicit unsupported notice on a CLI Peer instead of silent invoke failures. browser_webview_* stays controller-local (embedded UI). - cancel_tool joins HIGH_PRIORITY_COMMANDS so Terminal Interrupt takes the reserved high slot instead of queueing behind saturated normal work. - Tool catalog request bound to Device Surface: renderedPeerDeviceId added to useAgentsList loadAgents deps + AssistantDefaultsPage effect, so A->B (same workspace + capability) reloads; requestId guard drops stale results. P2: - Capability versioning: cancelTool/toolCatalog become boolean|null (null = unknown/older host); consumers stay optimistic so an older Desktop keeps its working button/list instead of being gated off. - Tool catalog status tri-state (available/unsupported/failed/empty) in useAgentsList + AssistantDefaultsPage; AssistantDefaultsPage distinguishes failure from a truly empty list. - keepalive publishes a React snapshot when a ready peer's capabilities change (not only on recovery), via capabilitiesEqual(). P3: - Remove two unreachable-pub identity fns + unused import from catalog.rs. - eslint fence regression test runs the eslint JS bin via process.execPath with shell:false (was pnpm + shell:true -> Node DEP0190 on Windows). Verified: eslint src clean; focus tests 72/72 (adapter 42, manager 19, surface + fence); core-boundaries + 126 self-tests pass; cargo build core/desktop clean; desktop peer_host_invoke 6/6; CLI cli_command_contracts 41/41. Pre-existing @generated/api type error and 2 flaky terminal_process contract tests are unrelated. Co-Authored-By: Claude <noreply@anthropic.com>
Round-5 review fixes for PR GCWing#2428 (reviewer limityan, 2026-08-25). P1 mixed-version cancel_tool: - Add declarative `host_type: "desktop"|"cli"` to peer_mode_ping on both Rust sides (desktop peer_host_invoke.rs, cli control.rs). - Parse into PeerHostCapabilities.hostKind (PeerConnectionManager.ts); null when an older host omits the field. - New resolveCanCancelTool() (terminalToolCardState.ts): null capability resolves by hostKind — old CLI hides the button, old Desktop shows it, unknown stays optimistic. Replaces the inline IIFE in TerminalToolCard. - Add a failure toast (toolCards.terminal.interruptFailed) in the catch path. P2 mixed-version tool_catalog: - New peerCapabilityResolution.ts with canQueryToolCatalogOnSurface() mirroring the cancel_tool resolution (null + cli -> unsupported). Replaces inline IIFEs in useAgentsList + AssistantDefaultsPage. - Surface tool-catalog status: AgentsScene renders an unsupported/failed message (agentsOverview.toolsUnsupported/toolsFailed) and gates writes; AssistantDefaultsPage MCP zone distinguishes unsupported/failed/empty and disables all tool writes (Switch/reset/group-toggle) when not writable. P2 browser/computer-use read reclassification: - Add browser_control_get_status, browser_control_list_browsers, computer_use_get_status to RETRYABLE_READ_COMMANDS (prefix matching had misclassified them as mutations). Tests on all sides: desktop peer_host_invoke host_type assertion, cli peer_mode_ping_advertises_cli_host_type, PeerConnectionManager hostKind parsing, terminalToolCardState resolveCanCancelTool cases, new peerCapabilityResolution suite, adapter read reclassification, AgentsScene unsupported-catalog rendering. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
将
main分支上 PR #2428 的全部 9 个提交同步到1.0.0-explore分支,引入「适配层围栏(adapter fence)」重构与 Peer-Device 能力增强。核心改动是把所有业务@tauri-apps/api/coreinvoke()调用收敛到api.invoke()(ApiClient),由 eslintno-restricted-imports强制围栏;同时为 Peer-Device 模式补齐cancel_tool/tool_catalog能力、声明式host_type字段,以及混合版本主机的兼容分类。Type and Areas
Type: refactor / bug fix
Areas: web UI、desktop/Tauri、Rust core(peer-host)
Motivation / Impact
invoke,统一经适配层路由,使本地/peer 路由、错误处理、capability 门控有单一收口点,并为后续替换传输层留出空间。cancel_tool、tool_catalog能力,UI 据此区分「主机不支持目录 / 读取失败 / 真的没有工具」三种状态,不再把不支持错误掩盖为空列表。host_type声明字段或get_all_tools_info回落探测进行分类,避免误判。Verification
npx tsc --noEmit— 干净(仅@bitfun/ui历史基线报错,非本次引入)eslint— 0 error / 0 warning(含no-restricted-imports围栏规则)vitest— 6 个文件 94/94 通过(peer-device、adapters、agents scene、terminal tool-cards、peerCapabilityResolution、peerDeviceSurfaceController)cargo check— 0 错误pnpm run check:core-boundaries— 通过(+ 129/129 边界测试,确认LOCAL_ONLY_COMMANDS在 CLIdeny.rs+ desktoppeer_host_invoke.rs间的镜像不变式成立)Reviewer Notes
useI18n(非useTranslation)、renderCapabilityRow/renderMcpGroups扁平行表格(非 main 的GalleryZone)、loadDefaultsuseCallback 模式;整合 main 的三态能力解析、toolCatalogStatus/toolCatalogWritable写入门控、host_type字段、遗留主机分类、陈旧加载竞态保护(loadRequestIdRef)。PeerHostCapabilities= explore 独有productControlV1/productControlNativeV1/productControlPresentationV1+ main 的cancelTool/toolCatalog(三态boolean|null)+hostKind。Rustpeer_mode_ping广播全部并集。browser_webview_set_agent_target_state+mark_bitfun_control_*(main commit 7 已删但 explore 仍需);删除 main 移除的computer_use_*/browser_control_*。AgentsScene.test.tsx「unsupported tool catalog」用例需在选中 agent 后点击[data-detail-section="tools"]tab(explore 仅在该 section 激活时渲染工具区),已修正。null三态对未探测主机保持乐观(向后兼容旧版 peer)。包含的 9 个提交
6b01d378b业务 invoke 走适配层,删除死代码 AgentService90e059803删除已确认零消费者的死代码dcbefd1c2声明 Peer-Device-Mode 所有者,补齐适配层围栏1aa33545b将控制器拥有的命令镜像到 peer deny 列表a477eedd2迁移后的测试指向 ApiClient mock 表面38b610304CLI peer 新增 cancel_tool + 工具目录路由,加固适配层5cb8699ccbrowser/computer-use 路由到工具主机,加固 peer 适配层0585146d8通过 host_type 字段解决混合版本 peer 能力bdf7b7f6c关闭 PR 2428 review 缺口Checklist
Fixes #2428