+ {/* Tab bar */}
+
+ {files.map((f, i) => (
+
setActive(i)}
+ className={
+ 'flex cursor-pointer items-center gap-1 border-r border-border px-3 py-2 ' +
+ (i === active ? 'bg-bg' : 'text-muted hover:text-fg')
+ }
+ >
+ {f.path.split('/').pop()}
+
+
+ ))}
+
+ {/* View switcher */}
+
+ {(['source', 'diff', 'history'] as const).map((v) => (
+
+ ))}
+
{current.path}
+
+ {/* Body — Monaco lives here in M7. Stub shows the placeholder. */}
+
+
+ Monaco editor mounts here in M7. {current.view} view of {current.path}.
+
+
+
+ );
+}
diff --git a/apps/desktop/src/screens/Permissions.tsx b/apps/desktop/src/screens/Permissions.tsx
new file mode 100644
index 0000000..783d90a
--- /dev/null
+++ b/apps/desktop/src/screens/Permissions.tsx
@@ -0,0 +1,125 @@
+// Permissions screen — view + edit settings.permissions rules.
+// Spec: docs/VISUAL_DESIGN.html (permissions tab) · M3 permission rules
+// Milestone: M6-rest
+
+import { useEffect, useState } from 'react';
+
+type RuleType = 'allow' | 'ask' | 'deny';
+
+interface PermissionsView {
+ defaultMode: string;
+ allow: string[];
+ ask: string[];
+ deny: string[];
+ additionalDirectories: string[];
+}
+
+export function PermissionsScreen(): JSX.Element {
+ const [perm, setPerm] = useState