Security + upstream fixes

- Network core moves to a root-only folder; BroV talks to a narrow root helper (netctl.py) over a user-only socket; install script verifies the mihomo SHA256 and migrates keys (scripts/netcore)
- Hardened runtime, no get-task-allow; bypassPermissions removed from the chat; concealed clipboard items are not restored; DangerCheck knows core, LaunchAgents and hook paths; dropped-file copies expire after 7 days
- Ported from upstream Coucou: 1h crash fix (d05f22b), safe settings.json writes (918d30e), Escape/fold for pending approvals (6012900, 40e3ba8), auto-close delay + reopen (74984f2, ea244a7), full AskUserQuestion (52b1562)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
maksarsanjeev
2026-10-07 23:49:11 +03:00
parent dc47247340
commit 52e1e8288b
21 changed files with 1070 additions and 188 deletions
+38 -1
View File
@@ -395,7 +395,7 @@ struct QuestionView: View {
Text(item.question)
.font(.system(size: 13, weight: .semibold))
.foregroundColor(Color(hex: "#F5F6F8"))
.lineLimit(2)
.fixedSize(horizontal: false, vertical: true)
// Options (wrapping) or "Other…" compact inline row
if curOther {
HStack(spacing: 6) {
@@ -429,6 +429,43 @@ struct QuestionView: View {
.buttonStyle(.plain)
.foregroundColor(Color(hex: "#6B7079"))
}
} else if item.hasDescriptions {
// Options with descriptions: a vertical list, label + description underneath.
VStack(alignment: .leading, spacing: 6) {
ForEach(Array(item.options.enumerated()), id: \.offset) { idx, opt in
let isSelected = curSel.contains(opt.label)
Button {
if isMulti {
toggleSelection(qi: qi, label: opt.label)
} else {
selectAndProceed(q: q, qi: qi, label: opt.label, isLast: isLast)
}
} label: {
VStack(alignment: .leading, spacing: 2) {
Text(opt.label)
.font(.system(size: 12, weight: .medium))
.foregroundColor(isSelected ? Color(hex: "#67E8F9") : Color(hex: "#F5F6F8"))
if !opt.description.isEmpty {
Text(opt.description)
.font(.system(size: 11))
.foregroundColor(Color(hex: "#9AA0A8"))
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 10).padding(.vertical, 6)
.background(isSelected ? Color(hex: "#22D3EE").opacity(0.22) : Color.white.opacity(0.07))
.clipShape(RoundedRectangle(cornerRadius: 8))
.overlay(RoundedRectangle(cornerRadius: 8).stroke(isSelected ? Color(hex: "#22D3EE").opacity(0.55) : Color.white.opacity(0.1), lineWidth: 1))
}
.buttonStyle(.plain)
.keyboardShortcut(KeyEquivalent(Character(String(idx + 1))), modifiers: [])
}
SecondaryButton("Другое…") {
if qi < showOther.count { showOther[qi] = true }
}
}
} else {
ChipFlowLayout(spacing: 6) {
ForEach(Array(item.options.enumerated()), id: \.offset) { idx, opt in