chore(desktop): merge origin/main into workspace-scoped-agent-store

Adopt spawn_hash → spawn_snapshot rename from main; migrate spawn_config_hash: 0
test fixtures to prospective_spawn_config_snapshot() calls in global_agent_config
tests, epoch tests, and runtime_commands tests.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7
2026-08-04 19:13:15 -04:00
co-authored by Will Pfleger
428 changed files with 29919 additions and 7327 deletions
+215 -64
View File
@@ -44,6 +44,7 @@ import {
KIND_MEMBER_ADDED_NOTIFICATION,
KIND_MEMBER_REMOVED_NOTIFICATION,
KIND_PERSONA,
KIND_PROJECT_ANNOUNCEMENT,
KIND_REPO_ANNOUNCEMENT,
KIND_REPO_STATE,
KIND_STREAM_MESSAGE_EDIT,
@@ -88,6 +89,7 @@ export type MockManagedAgentSeed = {
lastError?: string | null;
lastErrorCode?: number | null;
needsRestart?: boolean;
restartDiff?: Array<{ field: string; change: unknown }>;
autoRestartOnConfigChange?: boolean;
respondTo?: RawManagedAgent["respond_to"];
respondToAllowlist?: string[];
@@ -265,6 +267,8 @@ type E2eConfig = {
parent_added: boolean;
parent_error: string | null;
};
/** When set, the mocked `add_agent_to_huddle` command throws. */
addAgentToHuddleError?: string;
/** Delay an invocation-time huddle snapshot to exercise hydration ordering. */
huddleStateReadDelayMs?: number;
/** Delay companion creation to expose the newly-started huddle handoff state. */
@@ -369,6 +373,8 @@ type E2eConfig = {
// (e.g. a generic PDF) without a real upload pipeline. See
// tests/helpers/bridge.ts:MockBridgeOptions.uploadDescriptors.
uploadDelayMs?: number;
/** Exercise the production composer path that queues files until send. */
deferredComposerUploads?: boolean;
/** Delay (ms) applied to `encode_agent_snapshot_for_send` so E2E tests can
* observe the "preparing" phase before the upload begins. 0/undefined = instant. */
encodeDelayMs?: number;
@@ -398,21 +404,6 @@ type E2eConfig = {
// Seed rows returned by `list_save_subscriptions`. Each entry uses the same
// snake_case wire shape the Rust backend returns so tests can drive the
// LocalArchiveSettingsCard without a real SQLite database.
observerArchiveDefaultEnabled?: boolean;
/**
* Delay (ms) applied to `observer_archive_default_enabled` so E2E tests
* can exercise short-lived loading UI. 0/undefined = instant. Prefer the
* explicit defer/release seam for pending-state ordering assertions.
*/
observerArchiveDefaultEnabledDelayMs?: number;
/** Hold the observer policy command until the E2E release seam is called. */
deferObserverArchiveDefaultEnabled?: boolean;
/**
* When set, `observer_archive_default_enabled` throws with this message
* instead of resolving — drives the fail-closed `.catch()` path in
* `useObserverArchiveReconciliation` / `LocalArchiveSettingsCard`.
*/
observerArchiveDefaultEnabledError?: string;
agentMetricArchiveDefaultEnabled?: boolean;
saveSubscriptions?: Array<{
scope_type: string;
@@ -824,6 +815,7 @@ type RawManagedAgent = {
last_error: string | null;
last_error_code: number | null;
needs_restart?: boolean;
restart_diff?: Array<{ field: string; change: unknown }>;
log_path: string;
start_on_app_launch: boolean;
auto_restart_on_config_change?: boolean;
@@ -1066,6 +1058,15 @@ declare global {
command: string;
payload: unknown;
}>;
__BUZZ_E2E_EMIT_MEDIA_UPLOAD_PHASE__?: (input: {
id: string;
phase: string;
}) => Promise<void>;
__BUZZ_E2E_EMIT_MEDIA_UPLOAD_PROGRESS__?: (input: {
id: string;
sent: number;
total: number;
}) => Promise<void>;
__BUZZ_E2E_EMIT_MOCK_HUDDLE_TTS_SPEAKER__?: (payload: {
pubkey: string | null;
level: number;
@@ -1134,8 +1135,33 @@ declare global {
kind: number;
tags: string[][];
}>;
/** Project-scoped events accepted by the mock relay. */
__BUZZ_E2E_ACCEPTED_PROJECT_EVENTS__?: Array<{
content: string;
kind: number;
tags: string[][];
}>;
/** Project event kinds rejected once, in order, to exercise retry flows. */
__BUZZ_E2E_REJECT_PROJECT_EVENT_KINDS__?: number[];
/** Makes the mock relay reject project announcements as an unknown kind. */
__BUZZ_E2E_UNSUPPORTED_PROJECT_ANNOUNCEMENTS__?: boolean;
/** Project event kinds accepted once but reported as failed to test lost acknowledgements. */
__BUZZ_E2E_FAIL_PROJECT_EVENT_ACK_KINDS__?: number[];
/**
* Extra project events appended to the mock store on first access.
* Use to seed standalone repositories (kind 30617) or other project-scoped
* events before a test interaction, without mutating the fixed seed data.
* Events must be complete RelayEvent shapes; id is a required field so that
* id-keyed queries (e.g. lost-ACK recovery) can match them.
*/
__BUZZ_E2E_EXTRA_PROJECT_EVENTS__?: Array<{
id: string;
kind: number;
pubkey: string;
created_at: number;
content: string;
tags: string[][];
}>;
/** Structured merge error returned by the mock native merge command. */
__BUZZ_E2E_PROJECT_MERGE_ERROR__?: {
code: string;
@@ -1173,6 +1199,12 @@ declare global {
};
__BUZZ_E2E_SET_RELAY_CONNECTION_STATE__?: (state: ConnectionState) => void;
__BUZZ_E2E_GET_RELAY_CONNECTION_STATE__?: () => ConnectionState;
/** Queue deterministic mock AUTH outcomes, consumed in order. */
__BUZZ_E2E_QUEUE_AUTH_RESPONSES__?: (
responses: Array<{ success: boolean; message: string }>,
) => void;
/** Inject CLOSED into every active mock live subscription. */
__BUZZ_E2E_CLOSE_LIVE_SUBSCRIPTIONS__?: (reason: string) => number;
__BUZZ_E2E_SET_STALL_WEBSOCKET_SENDS__?: (stall: boolean) => void;
__BUZZ_E2E_DISCONNECT_MOCK_WEBSOCKETS__?: () => number;
__BUZZ_E2E_RESTART_MOCK_WEBSOCKETS__?: () => number;
@@ -1279,10 +1311,6 @@ declare global {
/** Count of `get_event` invocations for the current defer-target ID since
* the last time `__BUZZ_E2E_DEFER_GET_EVENT__` was set. */
__BUZZ_E2E_GET_EVENT_CALL_COUNT__?: number;
/** Release every deferred observer archive policy command. */
__BUZZ_E2E_RELEASE_OBSERVER_ARCHIVE_POLICY__?: () => number;
/** Number of observer archive policy commands currently held by the seam. */
__BUZZ_E2E_OBSERVER_ARCHIVE_POLICY_PENDING__?: number;
/** Hold the next channel read until released. */
__BUZZ_E2E_DEFER_NEXT_CHANNELS_READ__?: () => void;
/** Disarm the latch and release the held channel read, if any. */
@@ -1392,7 +1420,6 @@ type DeferredGetEvent = {
run: () => Promise<string>;
};
let deferredGetEventQueue: DeferredGetEvent[] = [];
let deferredObserverArchivePolicyQueue: Array<() => void> = [];
let deferNextChannelsRead = false;
let deferredChannelsReadResolve: (() => void) | null = null;
@@ -1616,6 +1643,7 @@ function cloneManagedAgent(agent: MockManagedAgent): RawManagedAgent {
last_error: agent.last_error,
last_error_code: agent.last_error_code,
needs_restart: agent.needs_restart ?? false,
restart_diff: agent.restart_diff ? [...agent.restart_diff] : [],
log_path: agent.log_path,
start_on_app_launch: agent.start_on_app_launch,
auto_restart_on_config_change: agent.auto_restart_on_config_change ?? true,
@@ -2169,6 +2197,7 @@ function buildSeededManagedAgent(seed: MockManagedAgentSeed): MockManagedAgent {
last_error: seed.lastError ?? null,
last_error_code: seed.lastErrorCode ?? null,
needs_restart: seed.needsRestart ?? false,
restart_diff: seed.restartDiff ?? [],
log_path: `/tmp/mock-agent-${seed.pubkey}.log`,
start_on_app_launch: true,
auto_restart_on_config_change: seed.autoRestartOnConfigChange ?? true,
@@ -2927,6 +2956,7 @@ const mockReminderEvents: RelayEvent[] = [];
const mockPersonaEvents: RelayEvent[] = [];
let mockRelayMembers: RawRelayMember[] = [];
const mockSockets = new Map<number, MockSocket>();
const mockAuthResponses: Array<{ success: boolean; message: string }> = [];
let mockWebsocketUnavailable = false;
const relayWebsocketConnectAttemptStarts: number[] = [];
let mockWebsocketSendMutexWedged = false;
@@ -2941,8 +2971,8 @@ let mockManagedAgentRuntimes: MockManagedAgentRuntimeRow[] = [];
// mutated by `create_save_subscription` / `delete_save_subscription` /
// `merge_save_subscription_kinds` / `remove_save_subscription_kind` exactly
// as the real SQLite-backed Rust commands would (see `archive/store.rs`).
// This lets E2E specs drive the fresh-internal-repair path (start from `[]`,
// reconcile, observe a kind-24200 row appear) and OSS toggle ON/OFF, neither
// This lets E2E specs drive the default-on seeding path (start from `[]`,
// reconcile, observe a kind-24200 row appear) and toggle ON/OFF, neither
// of which an immutable seed can represent.
type MockSaveSubscriptionRow = {
scope_type: string;
@@ -3041,7 +3071,7 @@ type MockHuddleState = {
tts_enabled: boolean;
transcription_enabled: boolean;
is_creator: boolean;
voice_input_mode: "voice_activity";
voice_input_mode: "push_to_talk" | "voice_activity";
};
type PersistedMockHuddle = {
@@ -3156,7 +3186,7 @@ function initializeMockHuddle(
tts_enabled: seed.ttsEnabled ?? false,
transcription_enabled: seed.transcriptionEnabled ?? false,
is_creator: seed.isCreator ?? true,
voice_input_mode: "voice_activity",
voice_input_mode: "push_to_talk",
},
};
}
@@ -5190,6 +5220,7 @@ const MOCK_PROJECT_SEEDS = [
name: "buzz",
description:
"Relay, desktop, and mobile clients for the Buzz community platform.",
cloneUrl: `${DEFAULT_RELAY_HTTP_URL}/git/${MOCK_IDENTITY_PUBKEY}/buzz`,
owner: MOCK_IDENTITY_PUBKEY,
contributors: [ALICE_PUBKEY, BOB_PUBKEY, CHARLIE_PUBKEY],
activityLevel: 4,
@@ -5198,6 +5229,7 @@ const MOCK_PROJECT_SEEDS = [
dtag: "relay-tools",
name: "relay-tools",
description: "Operator tooling and admin CLI for relay deployments.",
cloneUrl: "https://github.com/block/relay-tools.git",
owner: ALICE_PUBKEY,
contributors: [MOCK_IDENTITY_PUBKEY, BOB_PUBKEY],
activityLevel: 2,
@@ -5206,6 +5238,7 @@ const MOCK_PROJECT_SEEDS = [
dtag: "design-system",
name: "design-system",
description: "Shared UI tokens, typography ramps, and component library.",
cloneUrl: `${DEFAULT_RELAY_HTTP_URL}/git/${BOB_PUBKEY}/design-system`,
owner: BOB_PUBKEY,
contributors: [ALICE_PUBKEY],
activityLevel: 1,
@@ -5224,6 +5257,7 @@ const MOCK_PROJECT_SUBJECTS = [
];
const MOCK_PROJECT_KINDS = new Set<number>([
KIND_PROJECT_ANNOUNCEMENT,
KIND_REPO_ANNOUNCEMENT,
KIND_REPO_STATE,
KIND_GIT_PATCH,
@@ -5302,7 +5336,8 @@ function buildMockProjectEvents(): RelayEvent[] {
["d", seed.dtag],
["name", seed.name],
["description", seed.description],
["clone", `https://relay.example.com/git/${owner}/${seed.dtag}`],
["buzz-channel", "9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50"],
["clone", seed.cloneUrl],
...seed.contributors.map((pubkey) => ["p", pubkey]),
],
owner,
@@ -5367,10 +5402,7 @@ function buildMockProjectEvents(): RelayEvent[] {
? [
["h", "9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50"],
["branch-name", `feature/mock-${dayOffset}-${index}`],
[
"clone",
`https://relay.example.com/git/${owner}/${seed.dtag}`,
],
["clone", seed.cloneUrl],
]
: []),
];
@@ -5380,11 +5412,39 @@ function buildMockProjectEvents(): RelayEvent[] {
}
}
const projectOwner =
window.__BUZZ_E2E_PROJECT_OWNER_OVERRIDE__ ?? MOCK_PROJECT_SEEDS[0].owner;
events.push(
createMockEvent(
KIND_PROJECT_ANNOUNCEMENT,
"",
[
["d", "buzz"],
["name", "buzz"],
["description", "The complete Buzz community platform."],
["a", `${KIND_REPO_ANNOUNCEMENT}:${projectOwner}:buzz`],
["a", `${KIND_REPO_ANNOUNCEMENT}:${ALICE_PUBKEY}:relay-tools`],
],
projectOwner,
now,
"project-buzz".padEnd(64, "0"),
),
);
return events;
}
function getMockProjectEventStore(): RelayEvent[] {
mockProjectEventStore ??= buildMockProjectEvents();
if (!mockProjectEventStore) {
mockProjectEventStore = buildMockProjectEvents();
// Append any extra events injected by the test via addInitScript before
// the app boots. This lets a test seed standalone repositories or other
// project-scoped events without modifying the fixed seed data.
const extras = window.__BUZZ_E2E_EXTRA_PROJECT_EVENTS__;
if (extras && extras.length > 0) {
mockProjectEventStore.push(...(extras as RelayEvent[]));
}
}
return mockProjectEventStore;
}
@@ -5396,19 +5456,23 @@ function isMockProjectScopedEvent(event: RelayEvent): boolean {
(tag) => tag[0] === "a" && (tag[1] ?? "").startsWith("30617:"),
);
return (
hasRepoAddressTag &&
(event.kind === KIND_REPO_ANNOUNCEMENT || hasRepoAddressTag) &&
(event.kind === 1 || MOCK_PROJECT_KINDS.has(event.kind))
);
}
function filterMockProjectEvents(filter: MockFilter): RelayEvent[] {
const authors = filter.authors?.map((author) => author.toLowerCase());
const idsSet =
filter.ids && filter.ids.length > 0 ? new Set(filter.ids) : null;
return getMockProjectEventStore()
.filter((event) => {
if (filter.kinds && !filter.kinds.includes(event.kind)) return false;
if (authors && !authors.includes(event.pubkey.toLowerCase())) {
return false;
}
// Filter by event ids when present — required for lost-ACK recovery queries.
if (idsSet && !idsSet.has(event.id)) return false;
if (
filter["#d"] &&
!event.tags.some(
@@ -8806,7 +8870,7 @@ async function resolveMockUploadDescriptors(
}
async function resolveMockUploadDescriptorForBytes(
args: { data: number[]; filename?: string | null },
args: { data: number[] | Uint8Array; filename?: string | null },
config: E2eConfig | undefined,
): Promise<RawBlobDescriptor> {
const configured = config?.mock?.uploadDescriptors;
@@ -9428,7 +9492,16 @@ function sendToMockSocket(args: {
if (type === "AUTH") {
const event = rest[0] as RelayEvent;
sendWsText(socket.handler, ["OK", event.id, true, ""]);
const response = mockAuthResponses.shift() ?? {
success: true,
message: "",
};
sendWsText(socket.handler, [
"OK",
event.id,
response.success,
response.message,
]);
return;
}
@@ -9724,6 +9797,18 @@ function sendToMockSocket(args: {
]);
return;
}
if (
event.kind === KIND_PROJECT_ANNOUNCEMENT &&
window.__BUZZ_E2E_UNSUPPORTED_PROJECT_ANNOUNCEMENTS__
) {
sendWsText(socket.handler, [
"OK",
event.id,
false,
"restricted: unknown event kind",
]);
return;
}
const rejectionIndex =
window.__BUZZ_E2E_REJECT_PROJECT_EVENT_KINDS__?.indexOf(event.kind) ??
-1;
@@ -9741,6 +9826,30 @@ function sendToMockSocket(args: {
return;
}
getMockProjectEventStore().push(event);
const acceptedProjectEvents =
window.__BUZZ_E2E_ACCEPTED_PROJECT_EVENTS__ ?? [];
acceptedProjectEvents.push({
content: event.content,
kind: event.kind,
tags: event.tags,
});
window.__BUZZ_E2E_ACCEPTED_PROJECT_EVENTS__ = acceptedProjectEvents;
const failedAckIndex =
window.__BUZZ_E2E_FAIL_PROJECT_EVENT_ACK_KINDS__?.indexOf(event.kind) ??
-1;
if (failedAckIndex >= 0) {
window.__BUZZ_E2E_FAIL_PROJECT_EVENT_ACK_KINDS__?.splice(
failedAckIndex,
1,
);
sendWsText(socket.handler, [
"OK",
event.id,
false,
"mock lost project acknowledgement",
]);
return;
}
sendWsText(socket.handler, ["OK", event.id, true, ""]);
return;
}
@@ -9791,6 +9900,7 @@ export function maybeInstallE2eTauriMocks() {
mockClosedChannelLiveSubscription = false;
mockWebsocketUnavailable = false;
mockAuthResponses.length = 0;
relayWebsocketConnectAttemptStarts.length = 0;
mockGlobalAgentConfig = config.mock?.globalAgentConfig
? { ...config.mock.globalAgentConfig }
@@ -9820,6 +9930,12 @@ export function maybeInstallE2eTauriMocks() {
emit("huddle-tts-speaker-level", payload);
window.__BUZZ_E2E_SIGNED_EVENTS__ = [];
window.__BUZZ_E2E_WEBVIEW_ZOOM__ = 1;
window.__BUZZ_E2E_EMIT_MEDIA_UPLOAD_PHASE__ = async (input) => {
await emit("media-upload-phase", input);
};
window.__BUZZ_E2E_EMIT_MEDIA_UPLOAD_PROGRESS__ = async (input) => {
await emit("media-upload-progress", input);
};
window.__BUZZ_E2E_SET_MOCK_HUDDLE_SNAPSHOT__ = async ({
members,
transcriptionEnabled,
@@ -9958,14 +10074,6 @@ export function maybeInstallE2eTauriMocks() {
window.__BUZZ_E2E_GET_EVENT_CALL_COUNT__ = 0;
window.__BUZZ_E2E_DEFER_GET_EVENT__ = null;
deferredGetEventQueue = [];
deferredObserverArchivePolicyQueue = [];
window.__BUZZ_E2E_OBSERVER_ARCHIVE_POLICY_PENDING__ = 0;
window.__BUZZ_E2E_RELEASE_OBSERVER_ARCHIVE_POLICY__ = () => {
const queued = deferredObserverArchivePolicyQueue.splice(0);
window.__BUZZ_E2E_OBSERVER_ARCHIVE_POLICY_PENDING__ = 0;
for (const resolve of queued) resolve();
return queued.length;
};
deferNextChannelsRead = false;
deferredChannelsReadResolve = null;
window.__BUZZ_E2E_CHANNELS_READ_PENDING__ = 0;
@@ -10032,6 +10140,20 @@ export function maybeInstallE2eTauriMocks() {
};
window.__BUZZ_E2E_GET_RELAY_CONNECTION_STATE__ = () =>
relayClient.getConnectionState();
window.__BUZZ_E2E_QUEUE_AUTH_RESPONSES__ = (responses) => {
mockAuthResponses.push(...responses);
};
window.__BUZZ_E2E_CLOSE_LIVE_SUBSCRIPTIONS__ = (reason) => {
let closed = 0;
for (const socket of mockSockets.values()) {
for (const subId of [...socket.subscriptions.keys()]) {
sendWsText(socket.handler, ["CLOSED", subId, reason]);
socket.subscriptions.delete(subId);
closed += 1;
}
}
return closed;
};
window.__BUZZ_E2E_SEED_MOCK_REMINDERS__ = (reminders) => {
mockReminderEvents.length = 0;
@@ -10160,6 +10282,9 @@ export function maybeInstallE2eTauriMocks() {
const identity = getActiveIdentity(activeConfig);
window.__BUZZ_E2E_COMMANDS__?.push(command);
const loggedPayload = (() => {
if (payload instanceof Uint8Array) {
return { rawByteLength: payload.byteLength };
}
try {
return JSON.parse(JSON.stringify(payload ?? null));
} catch {
@@ -10181,6 +10306,21 @@ export function maybeInstallE2eTauriMocks() {
}
return snapshot;
}
case "get_voice_input_mode":
return mockHuddle?.state.voice_input_mode ?? "push_to_talk";
case "set_voice_input_mode": {
if (!mockHuddle) throw new Error("No active mock huddle.");
const mode = (payload as { mode?: unknown }).mode;
if (mode !== "push_to_talk" && mode !== "voice_activity") {
throw new Error("Missing voice input mode.");
}
mockHuddle.state.voice_input_mode = mode;
persistMockHuddle();
await emitMockHuddleState();
return null;
}
case "set_huddle_manual_mic_unmuted":
return null;
case "get_huddle_agent_pubkeys":
if (!mockHuddle) return [];
return [...mockHuddle.state.agent_pubkeys];
@@ -10212,7 +10352,7 @@ export function maybeInstallE2eTauriMocks() {
tts_enabled: false,
transcription_enabled: false,
is_creator: true,
voice_input_mode: "voice_activity",
voice_input_mode: "push_to_talk",
},
};
refreshMockHuddleMembership(activeConfig);
@@ -10306,7 +10446,7 @@ export function maybeInstallE2eTauriMocks() {
tts_enabled: false,
transcription_enabled: false,
is_creator: false,
voice_input_mode: "voice_activity",
voice_input_mode: "push_to_talk",
});
return null;
case "set_huddle_transcription_enabled":
@@ -10387,12 +10527,33 @@ export function maybeInstallE2eTauriMocks() {
return { matched_active_huddle: true, added };
}
case "add_agent_to_huddle": {
const error = activeConfig?.mock?.addAgentToHuddleError;
if (error) {
throw new Error(error);
}
const result = activeConfig?.mock?.addAgentToHuddleResult;
if (!result) {
throw new Error("No mock add-agent result configured.");
}
return structuredClone(result);
}
case "remove_agent_from_huddle": {
const agentPubkey = (payload as { agentPubkey?: string })?.agentPubkey;
if (!mockHuddle || !agentPubkey) {
throw new Error("No active huddle agent to remove.");
}
const initialCount = mockHuddle.members.length;
mockHuddle.members = mockHuddle.members.filter(
(member) => member.role !== "bot" || member.pubkey !== agentPubkey,
);
if (mockHuddle.members.length === initialCount) {
throw new Error("Agent is not in this huddle.");
}
refreshMockHuddleMembership(activeConfig);
persistMockHuddle();
await emitMockHuddleState();
return;
}
case "get_model_status":
return { stt: "ready", tts: "ready" };
case "get_tts_settings":
@@ -10525,6 +10686,8 @@ export function maybeInstallE2eTauriMocks() {
}
return settings;
}
case "interrupt_huddle_speech":
return;
case "set_pocket_voice": {
const voiceKey = (payload as { voiceKey?: string })?.voiceKey;
if (!voiceKey) throw new Error("Missing Pocket voice key");
@@ -12309,6 +12472,13 @@ export function maybeInstallE2eTauriMocks() {
payload as { data: number[]; filename?: string | null },
activeConfig,
);
case "upload_media_bytes_raw":
return resolveMockUploadDescriptorForBytes(
{
data: payload as Uint8Array,
},
activeConfig,
);
case "fetch_media_bytes": {
// The real command fetches relay media through Rust reqwest and
// replies with raw bytes (`tauri::ipc::Response` → ArrayBuffer). In
@@ -12587,7 +12757,7 @@ export function maybeInstallE2eTauriMocks() {
// install); create/merge/delete/remove mutate it with the same
// union / delete-row-when-empty semantics as the real Rust commands
// (see `archive/store.rs::merge_owner_p_kinds` / `remove_owner_p_kind`)
// so specs can drive fresh-internal-repair and toggle ON/OFF flows.
// so specs can drive default-on seeding and toggle ON/OFF flows.
case "list_save_subscriptions": {
const win = window as unknown as Record<string, unknown>;
if (!win.__BUZZ_E2E_IPC_COUNTERS__) {
@@ -12645,27 +12815,8 @@ export function maybeInstallE2eTauriMocks() {
case "archive_events":
// Returns the ArchiveBatchResult shape the UI expects.
return { persisted: 0, dropped: 0 };
case "observer_archive_default_enabled": {
if (activeConfig?.mock?.deferObserverArchiveDefaultEnabled) {
await new Promise<void>((resolve) => {
deferredObserverArchivePolicyQueue.push(resolve);
window.__BUZZ_E2E_OBSERVER_ARCHIVE_POLICY_PENDING__ =
deferredObserverArchivePolicyQueue.length;
});
}
const delayMs =
activeConfig?.mock?.observerArchiveDefaultEnabledDelayMs;
if (delayMs && delayMs > 0) {
await new Promise((resolve) => window.setTimeout(resolve, delayMs));
}
const error = activeConfig?.mock?.observerArchiveDefaultEnabledError;
if (error) {
throw new Error(error);
}
return activeConfig?.mock?.observerArchiveDefaultEnabled ?? false;
}
case "agent_metric_archive_default_enabled":
return activeConfig?.mock?.agentMetricArchiveDefaultEnabled ?? false;
return activeConfig?.mock?.agentMetricArchiveDefaultEnabled ?? true;
case "set_prevent_sleep_active":
return null;
case "plugin:window|is_fullscreen":