用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/steipete/agent-scripts --skill swiftui-view-refactor命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | swiftui-view-refactor |
| description | SwiftUI view refactor/review: layout, DI, Observation, view models. |
Attribution: copied from @Dimillian’s Dimillian/Skills (2025-12-31).
Apply a consistent structure and dependency pattern to SwiftUI views, with a focus on ordering, Model-View (MV) patterns, careful view model handling, and correct Observation usage.
private/public let@State / other stored propertiesvar (non-view)initbody@State, @Environment, @Query, and task/onChange for orchestration.@Environment; keep views small and composable.body grows beyond a screen or has multiple logical sections, split it into smaller subviews.var header: some View { ... }) into dedicated View types when they carry state or complex branching.View struct only when it structurally makes sense or when reuse is intended.Example (extracting a section):
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HeaderSection(title: title, isPinned: isPinned)
DetailsSection(details: details)
ActionsSection(onSave: onSave, onCancel: onCancel)
}
}
Example (long body → shorter body + computed views in the same file):
var body: some View {
List {
header
filters
results
footer
}
}
private var header: some View {
VStack(alignment: .leading, spacing: 6) {
Text(title).font(.title2)
Text(subtitle).font(.subheadline)
}
}
private var filters: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(filterOptions, id: \.self) { option in
FilterChip(option: option, isSelected: option == selectedFilter)
.onTapGesture { selectedFilter = option }
}
}
}
}
Example (extracting a complex computed view):
private var header: some View {
HeaderSection(title: title, subtitle: subtitle, status: status)
}
private struct HeaderSection: View {
let title: String
let subtitle: String?
let status: Status
var body: some View {
VStack(alignment: .leading, spacing: 4) {
Text(title).font(.headline)
if let subtitle { Text(subtitle).font(.subheadline) }
StatusBadge(status: status)
}
}
}
init, then pass them into the view model in the view's init.bootstrapIfNeeded patterns.Example (Observation-based):
@State private var viewModel: SomeViewModel
init(dependency: Dependency) {
_viewModel = State(initialValue: SomeViewModel(dependency: dependency))
}
@Observable reference types, store them as @State in the root view.@State, @Environment, @Query, task, and onChange.@State view model initialized in init by passing dependencies from the view.@State for root @Observable view models, no redundant wrappers.body and non-view computed vars above init.references/mv-patterns.md.Control the user's existing signed-in Chrome: callable Codex Chrome plugin first, then OpenClaw extension-backed mcporter, with direct DevTools attachment only as a last fallback.
REQUIRED before ANY `op` command or whenever a task needs an API key, token, password, credential, or secret (OPENAI_API_KEY, ANTHROPIC_API_KEY, deploy tokens, live-test keys). Prompt-free 1Password service-account reads; wrong invocations spam macOS dialogs.
yt-dlp downloads: video, audio, subtitles, transcripts, clips, playlists.