Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/interactive-capabilities/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ OpenBitFun Playbook currently contains **22 features**, **21 settings pages**, a
- Generated per-item interaction audit: `docs/interactive-capabilities/technical/product-control-open-audit.json`
- Generated low-level audit map: `docs/interactive-capabilities/technical/tauri-command-map.json`

说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **656** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **657** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。

Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **656** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **657** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.

## 控制边界 / Control boundary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@
"evidence": [
"command:get_clipboard_files",
"command:resolve_browser_dropped_file_paths",
"command:set_file_drop_preview_target",
"command:upload_image_contexts",
"source:src/web-ui/src/flow_chat/utils/externalFileIntake.ts#buildExternalFileContexts",
"source:src/web-ui/src/flow_chat/utils/externalFileIntake.test.ts#buildExternalFileContexts",
Expand Down
22 changes: 19 additions & 3 deletions docs/interactive-capabilities/technical/tauri-command-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"schemaVersion": 2,
"generatedFrom": "src/shared/interactive-capabilities/catalog.json",
"catalogDigest": "5473331e06ecd4bfafbf9b547d48b4fe1561ccf69d86fdfde51ea10dc919531c",
"commandCount": 656,
"commandCount": 657,
"coverage": {
"commandCount": 656,
"documentedCommandCount": 612,
"commandCount": 657,
"documentedCommandCount": 613,
"implementationCommandCount": 44,
"implementationDigest": "012cebbd8d7c908d8e4c0787f73a2fa5f43184c240e7fde68cb941667574ba8f"
},
Expand Down Expand Up @@ -8601,6 +8601,22 @@
"signature": "fn set_external_tool_targets_enabled_command( request: SetExternalToolTargetsEnabledRequest, ) -> ExternalSourceOperationResult<ExternalSourceSnapshotResponse>",
"remoteWorkspacePolicy": "RemoteUnsupported"
},
{
"id": "set_file_drop_preview_target",
"moduleId": "file_drop_preview",
"capabilityId": "feature.files-editor",
"capabilityIds": [
"feature.files-editor"
],
"documentedItemIds": [
"feature.files-editor:attachments"
],
"visibility": "documented",
"rustPath": "api::file_drop_preview_api::set_file_drop_preview_target",
"sourceFile": "src/apps/desktop/src/api/file_drop_preview_api.rs",
"signature": "fn set_file_drop_preview_target( window: tauri::WebviewWindow, request: SetFileDropPreviewTargetRequest, ) -> Result<(), String>",
"remoteWorkspacePolicy": "LocalOnly"
},
{
"id": "set_global_skill_disabled",
"moduleId": "skill",
Expand Down
4 changes: 3 additions & 1 deletion scripts/core-boundaries/cargo-dependency-boundaries.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,9 @@ const THIRD_PARTY_CAPABILITY_PROFILES = new Map([
optional: true,
useDefaultFeatures: false,
})],
['openbitfun-desktop', dependencyProfile(['jpeg', 'png'], {
// Desktop owns bounded controller-local drag thumbnail decoding.
// Keep only its raster input formats and PNG/JPEG output codecs.
['openbitfun-desktop', dependencyProfile(['bmp', 'gif', 'jpeg', 'png', 'webp'], {
useDefaultFeatures: false,
})],
['openbitfun-miniapp-market-service', dependencyProfile(['jpeg', 'png', 'webp'], {
Expand Down
10 changes: 10 additions & 0 deletions scripts/desktop-tauri-build.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ const FAILED_BUILD = { status: 1 };
const DMG_ARGS = ['--target', 'x86_64-apple-darwin', '--bundles', 'app,dmg'];
const ROOT = join(import.meta.dirname, '..');

test('Windows desktop manifest opts into layered child windows and preserves common controls', () => {
const desktop = join(ROOT, 'src', 'apps', 'desktop');
const manifest = readFileSync(join(desktop, 'windows-app.manifest'), 'utf8');
const build = readFileSync(join(desktop, 'build.rs'), 'utf8');
assert.match(build, /app_manifest\(include_str!\("windows-app\.manifest"\)\)/);
assert.match(build, /rerun-if-changed=windows-app\.manifest/);
assert.match(manifest, /name="Microsoft\.Windows\.Common-Controls"[\s\S]*?version="6\.0\.0\.0"/);
assert.match(manifest, /<compatibility xmlns="urn:schemas-microsoft-com:compatibility\.v1">[\s\S]*?<application>[\s\S]*?<supportedOS Id="\{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a\}"/);
});

test('Desktop packaging selects the Web font profile from its target triple', () => {
const appleEnv = { [WEB_FONT_PROFILE_ENV]: HARMONY_BUNDLED_FONT_PROFILE };
assert.equal(
Expand Down
25 changes: 25 additions & 0 deletions src/apps/desktop/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,31 @@ run `cargo test -p openbitfun-desktop --lib api::local_file_download::tests`.
After changing its registration, also run
`cargo test -p openbitfun-desktop --lib remote_workspace_policy`.

For Windows external-file drag previews, run
`cargo test --locked -p openbitfun-desktop --lib file_drop_preview_api` and
`pnpm --dir src/web-ui run test:run src/infrastructure/files/useWindowsFileDropPreview.test.tsx src/app/scenes/session/FileDropPreviewCards.test.tsx`.
After rebuilding Desktop, manually check Explorer drags with one image, more than
four images, mixed file formats, Escape, leaving the pane, and a scene switch.
Verify HTML text/tab/file-tree drags still work. The temporary OLE child only
covers the active chat target during an external file drag; do not enable Wry's
window-wide Windows handler as a replacement. After command registration changes,
also run `cargo test -p openbitfun-desktop --lib remote_workspace_policy`.

The layered receiver requires the compatibility declaration in
`windows-app.manifest`; keep it wired through `build.rs` for dev and release.
After changes to that contract, run
`node --test scripts/desktop-tauri-build.test.mjs` and `cargo build -p openbitfun-desktop`.
The focused native test creates and destroys 50 real, hidden receiver windows.
The Shell regression also uses a real `IDataObject` and drag-image helpers to
verify 20 takeovers leave no `SysDragImage`, and that the next target can restore
the source image and clean it up on drop/cancel. `IDropTargetHelper::Show(false)`
alone does not dismiss the modern layered image; end the Shell renderer session
before displaying the custom preview, while keeping the OLE receiver active.
If the Windows Tauri library test loader fails before running tests, embed the
same desktop manifest into a temporary copy of the generated test executable
using the Windows SDK `mt.exe`, then run the `file_drop_preview_api` filter on
that copy. A Common Controls-only manifest cannot exercise layered children.

For staged application-update cache and signature behavior, use
`cargo test -p openbitfun-desktop --lib api::update_api::tests`.
For peer system-info response compatibility, run
Expand Down
11 changes: 10 additions & 1 deletion src/apps/desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ sha2 = { workspace = true }
minisign-verify = { workspace = true }
screenshots = { workspace = true }
enigo = { workspace = true }
image = { workspace = true, features = ["jpeg", "png"] }
# Controller-local drag thumbnails decode these formats; other files use UI icons.
image = { workspace = true, features = ["bmp", "gif", "jpeg", "png", "webp"] }
resvg = { workspace = true }
tempfile = { workspace = true }

Expand Down Expand Up @@ -123,6 +124,8 @@ windows = { workspace = true, features = [
"Win32_Graphics_Dxgi_Common",
"Win32_Graphics_Gdi",
"Win32_Storage_FileSystem",
"Win32_System_LibraryLoader",
"Win32_System_SystemServices",
"Win32_Storage_Xps",
"Win32_System_Com",
"Win32_System_Ole",
Expand All @@ -132,11 +135,17 @@ windows = { workspace = true, features = [
"Win32_System_WinRT_Graphics",
"Win32_System_WinRT_Graphics_Capture",
"Win32_UI_Accessibility",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
] }
windows-core = { workspace = true }
webview2-com = { workspace = true }

[target.'cfg(windows)'.dev-dependencies]
# Real Shell IDataObject fixtures for native drag-image lifecycle regressions.
windows = { workspace = true, features = ["Win32_UI_Shell_Common"] }

[features]
default = []
# Enable webview devtools and element inspector for development builds.
Expand Down
6 changes: 5 additions & 1 deletion src/apps/desktop/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ fn main() {
// large debug invoke dispatcher cannot exhaust the default 1 MiB stack.
#[cfg(target_os = "windows")]
println!("cargo:rustc-link-arg-bins=/STACK:8388608");
tauri_build::build();
println!("cargo:rerun-if-changed=windows-app.manifest");
let windows =
tauri_build::WindowsAttributes::new().app_manifest(include_str!("windows-app.manifest"));
tauri_build::try_build(tauri_build::Attributes::new().windows_attributes(windows))
.expect("failed to build desktop platform resources");
}
Loading
Loading