diff --git a/packages/web/src/components/confirm-dialog.test.tsx b/packages/web/src/components/confirm-dialog.test.tsx
new file mode 100644
index 00000000..a4e19166
--- /dev/null
+++ b/packages/web/src/components/confirm-dialog.test.tsx
@@ -0,0 +1,54 @@
+///
+
+import {afterEach, describe, expect, mock, test} from 'bun:test';
+import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/react';
+import {ConfirmDialog} from '@/components/confirm-dialog';
+
+afterEach(() => {
+ cleanup();
+});
+
+function renderDialog({destructive = false}: {destructive?: boolean} = {}) {
+ const onClose = mock();
+ const onConfirm = mock();
+ render(
+ ,
+ );
+ return {onClose, onConfirm};
+}
+
+describe('ConfirmDialog', () => {
+ test('uses the confirmation as the default action when it is safe', async () => {
+ const {onClose, onConfirm} = renderDialog();
+ const confirm = screen.getByRole('button', {name: 'Share'});
+
+ await waitFor(() => expect(document.activeElement).toBe(confirm));
+ expect(confirm.getAttribute('type')).toBe('submit');
+ fireEvent.keyDown(window, {key: 'Enter', metaKey: true});
+
+ expect(onConfirm).toHaveBeenCalledTimes(1);
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+
+ test('uses cancel as the default action when confirmation is destructive', async () => {
+ const {onClose, onConfirm} = renderDialog({destructive: true});
+ const cancel = screen.getByRole('button', {name: 'Cancel'});
+
+ await waitFor(() => expect(document.activeElement).toBe(cancel));
+ expect(cancel.getAttribute('type')).toBe('button');
+ fireEvent.keyDown(window, {key: 'Enter', metaKey: true});
+ expect(onConfirm).not.toHaveBeenCalled();
+ fireEvent.click(cancel);
+
+ expect(onConfirm).not.toHaveBeenCalled();
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/packages/web/src/components/confirm-dialog.tsx b/packages/web/src/components/confirm-dialog.tsx
index 49cc1fca..5c5f451a 100644
--- a/packages/web/src/components/confirm-dialog.tsx
+++ b/packages/web/src/components/confirm-dialog.tsx
@@ -8,6 +8,7 @@ import {
DialogHeader,
DialogTitle,
} from '@proxy/ui/components/dialog';
+import {useCommandEnterSubmit} from '@/hooks/use-command-enter';
type Props = {
open: boolean;
@@ -28,6 +29,8 @@ export function ConfirmDialog({
onClose,
onConfirm,
}: Props) {
+ const form = useCommandEnterSubmit(open && !destructive);
+
return (
);
diff --git a/packages/web/src/components/persona-dialog.test.tsx b/packages/web/src/components/persona-dialog.test.tsx
new file mode 100644
index 00000000..ff984a90
--- /dev/null
+++ b/packages/web/src/components/persona-dialog.test.tsx
@@ -0,0 +1,27 @@
+///
+
+import {afterEach, describe, expect, mock, test} from 'bun:test';
+import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/react';
+
+mock.module('@/components/head', () => ({LiveHead: () => null}));
+
+const {PersonaDialog} = await import('@/components/persona-dialog');
+
+afterEach(() => {
+ cleanup();
+});
+
+describe('PersonaDialog', () => {
+ test('creates an agent with Command+Enter', async () => {
+ const onClose = mock();
+ const onSave = mock(async () => null);
+ render();
+
+ fireEvent.change(screen.getByLabelText('Name'), {target: {value: 'Finance'}});
+ fireEvent.keyDown(window, {key: 'Enter', metaKey: true});
+
+ await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
+ expect(onSave).toHaveBeenCalledWith(expect.objectContaining({name: 'Finance'}));
+ expect(onClose).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/packages/web/src/components/persona-dialog.tsx b/packages/web/src/components/persona-dialog.tsx
index 6c4e3ee9..c9907bb8 100644
--- a/packages/web/src/components/persona-dialog.tsx
+++ b/packages/web/src/components/persona-dialog.tsx
@@ -16,6 +16,7 @@ import {
import {Input} from '@proxy/ui/components/input';
import {Label} from '@proxy/ui/components/label';
import {cn} from '@proxy/ui/lib/utils';
+import {useCommandEnterSubmit} from '@/hooks/use-command-enter';
type Props = {
open: boolean;
@@ -62,6 +63,7 @@ export function PersonaDialog({open, initial, onClose, onSave, onDelete}: Props)
const [error, setError] = useState(null);
const [busy, setBusy] = useState(false);
const ready = persona.name.trim() !== '';
+ const form = useCommandEnterSubmit(ready && !busy);
const finish = (failed: string | null) => {
setBusy(false);
@@ -83,6 +85,7 @@ export function PersonaDialog({open, initial, onClose, onSave, onDelete}: Props)
>