Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b1a7fad
Polish agent sharing and snapshots
klopez4212 Jul 14, 2026
fd8ff5c
Address agent share review feedback
klopez4212 Jul 14, 2026
7ecbe11
Address agent sharing review feedback
klopez4212 Jul 14, 2026
dc4ba26
Render copied agent links as attachments
klopez4212 Jul 14, 2026
8abf893
Preview copied agents in the composer
klopez4212 Jul 14, 2026
e9daaa2
Remove composer close button stroke
klopez4212 Jul 14, 2026
0ee01a3
Polish share access heading
klopez4212 Jul 14, 2026
3f23037
Hide share close ring on open
klopez4212 Jul 14, 2026
234f040
Deemphasize the copy link action
klopez4212 Jul 14, 2026
ce7fef7
Reveal send after choosing recipients
klopez4212 Jul 14, 2026
5cf91a5
Match share recipient chips to new messages
klopez4212 Jul 14, 2026
f8a5636
Keep share recipient names static
klopez4212 Jul 14, 2026
3726794
Anchor chip poofs to the pointer
klopez4212 Jul 14, 2026
0999da5
Allow share recipient list scrolling
klopez4212 Jul 14, 2026
8cacb30
Tighten share card spacing
klopez4212 Jul 14, 2026
039f043
Remove copy link button shadow
klopez4212 Jul 14, 2026
bb0da09
Restore share memory warning
klopez4212 Jul 14, 2026
7ed108c
Soften share search placeholder
klopez4212 Jul 14, 2026
852e482
Smooth final share recipient removal
klopez4212 Jul 14, 2026
29f5212
Refine share access heading
klopez4212 Jul 14, 2026
306f43a
Align static share access values
klopez4212 Jul 14, 2026
9fbb094
Refine agent sharing workflow
klopez4212 Jul 14, 2026
be921b7
Harden agent sharing flows
klopez4212 Jul 14, 2026
a8ca035
Unify agent and team sharing flows
klopez4212 Jul 15, 2026
188892e
Guard snapshot sharing actions
klopez4212 Jul 15, 2026
fb56b5c
Respect team snapshot clipboard limits
klopez4212 Jul 15, 2026
9956389
Harden snapshot clipboard parsing
klopez4212 Jul 15, 2026
4a8e3e9
Fix chat-first agent creation after rebase
klopez4212 Jul 15, 2026
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
1 change: 0 additions & 1 deletion desktop/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export default defineConfig({
name: "integration",
testMatch: [
"**/agents.spec.ts",
"**/agent-snapshot-send.spec.ts",
"**/agent-snapshot-recipient.spec.ts",
"**/onboarding.spec.ts",
"**/stream.spec.ts",
Expand Down
34 changes: 34 additions & 0 deletions desktop/src-tauri/src/commands/media_download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,40 @@ pub async fn copy_image_to_clipboard(
.map_err(|_| "clipboard result channel closed unexpectedly".to_string())?
}

/// Write text to the system clipboard through the native shell.
///
/// WebKit can revoke browser clipboard permission after a user action awaits a
/// long-running operation such as snapshot encoding and upload. Keeping the
/// delayed write in the native layer makes that flow reliable on macOS.
#[tauri::command]
pub async fn copy_text_to_clipboard(
text: String,
html: Option<String>,
app: tauri::AppHandle,
) -> Result<(), String> {
let (tx, rx) = std::sync::mpsc::sync_channel::<Result<(), String>>(1);
app.run_on_main_thread(move || {
let result = arboard::Clipboard::new()
.map_err(|e| format!("clipboard error: {e}"))
.and_then(|mut clipboard| {
if let Some(html) = html {
clipboard
.set_html(html, Some(text))
.map_err(|e| format!("clipboard error: {e}"))
} else {
clipboard
.set_text(text)
.map_err(|e| format!("clipboard error: {e}"))
}
});
let _ = tx.send(result);
})
.map_err(|e| format!("main thread dispatch failed: {e}"))?;

rx.recv()
.map_err(|_| "clipboard result channel closed unexpectedly".to_string())?
}

/// Fetch blob bytes from a (pre-validated) relay media URL through the app's
/// HTTP client, enforcing the download size cap. The caller is responsible for
/// validating the URL origin and for any content-type checks on the result.
Expand Down
1 change: 1 addition & 0 deletions desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ pub fn run() {
download_file,
fetch_media_bytes,
copy_image_to_clipboard,
copy_text_to_clipboard,
fetch_snapshot_bytes,
list_relay_members,
get_my_relay_membership,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import assert from "node:assert/strict";
import test from "node:test";

import { clearLegacyPersonaCatalogVisibility } from "./legacyPersonaCatalogVisibility.ts";

test("clearLegacyPersonaCatalogVisibility removes the retired preference", () => {
const removedKeys = [];

clearLegacyPersonaCatalogVisibility({
removeItem(key) {
removedKeys.push(key);
},
});

assert.deepEqual(removedKeys, ["buzz-persona-catalog-visibility-v1"]);
});

test("clearLegacyPersonaCatalogVisibility ignores unavailable storage", () => {
assert.doesNotThrow(() => clearLegacyPersonaCatalogVisibility(null));
assert.doesNotThrow(() =>
clearLegacyPersonaCatalogVisibility({
removeItem() {
throw new Error("storage unavailable");
},
}),
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const LEGACY_PERSONA_CATALOG_VISIBILITY_STORAGE_KEY =
"buzz-persona-catalog-visibility-v1";

/**
* Removes the retired custom-persona catalog preference so it cannot resurface
* agents after the visibility control has been removed.
*/
export function clearLegacyPersonaCatalogVisibility(
storage?: Pick<Storage, "removeItem"> | null,
) {
let targetStorage = storage;
if (targetStorage === undefined) {
if (typeof window === "undefined") return;

try {
targetStorage = window.localStorage;
} catch {
return;
}
}
if (!targetStorage) return;

try {
targetStorage.removeItem(LEGACY_PERSONA_CATALOG_VISIBILITY_STORAGE_KEY);
} catch {
// Catalog cleanup is best-effort and should not block the agents view.
}
}
Loading