ソース情報
- リポジトリ
- adamayoung/popcorn
- ソースの最終更新活動
- 2026年6月10日 15:42
- 検出された SKILL.md の言語
- 英語
- スター
- 1
- フォーク
- 0
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/adamayoung/popcorn --skill add-screenコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
SOC 職業分類に基づく
SKILL.md を表示中
| name | add-screen |
| description | Add a screen to an existing feature |
Guide for adding a new screen/view to an existing tab with MVVM navigation.
In MVVM, navigation is owned by the App layer: each tab has a Router
(@Observable @MainActor) holding a typed Route enum stack bound to a
NavigationStack(path:), plus a RouterNavigator value type that implements every
leaf feature's Navigating protocol by mutating the router. A view model never
pushes screens itself — it calls a method on its injected navigator.
Use App/Features/ExploreRoot/{ExploreRouter.swift, Views/ExploreRootView.swift}
and App/Composition/ViewModelFactory.swift as the canonical reference.
Ask the user for:
If the screen needs its own feature module, build it following the add-feature
workflow: a {ScreenName}ViewModel (@Observable @MainActor exposing
ViewState<ViewSnapshot>), a {ScreenName}Dependencies struct with
live(services:), a {ScreenName}Navigating protocol, and a {ScreenName}View
owning the view model via @State.
In App/Composition/ViewModelFactory.swift, add a make{ScreenName} method that
wires the feature's Dependencies.live(services:) to a navigator:
func make{ScreenName}(
id: Int,
navigator: some {ScreenName}Navigating
) -> {ScreenName}ViewModel {
{ScreenName}ViewModel(
id: id,
dependencies: .live(services: services),
navigator: navigator
)
}
In the tab's router file, add a case to the Route enum. The enum is Hashable
and carries the values needed to build the destination view model:
enum {Tab}Route: Hashable {
case existingScreen(id: Int)
case {screenName}(id: Int) // Add this
}
The source feature's view model calls a method on its Navigating protocol. Add
that requirement to the protocol if it doesn't exist:
@MainActor
public protocol {SourceFeature}Navigating {
func open{ScreenName}(id: Int) // Add this
}
Then implement it in the tab's RouterNavigator by appending the new route:
@MainActor
struct {Tab}RouterNavigator: {SourceFeature}Navigating /* , ... */ {
let router: {Tab}Router
func open{ScreenName}(id: Int) {
router.path.append(.{screenName}(id: id))
}
}
And call it from the source view model:
public func selectSomeItem(id: Int) {
navigator.open{ScreenName}(id: id)
}
In the tab's root view, the NavigationStack(path:) is bound to $router.path.
Add the new case to the navigationDestination switch, building the view model
through the factory and a navigator bound to this router:
NavigationStack(path: $router.path) {
{Tab}View(viewModel: {tab}ViewModel)
.navigationDestination(for: {Tab}Route.self) { route in
destination(route)
}
}
@ViewBuilder
private func destination(_ route: {Tab}Route) -> some View {
switch route {
case .existingScreen(let id):
ExistingView(viewModel: factory.makeExisting(id: id, navigator: navigator))
case .{screenName}(let id):
{ScreenName}View(viewModel: factory.make{ScreenName}(id: id, navigator: navigator)) // Add this
}
}
private var navigator: {Tab}RouterNavigator {
{Tab}RouterNavigator(router: router)
}
For a modal instead of a push, add an @Observable presentation item property to
the router (e.g. presented{ScreenName}: Presented{ScreenName}?), have the
navigator method set it, and present it with .sheet(item:) /
.fullScreenCover(item:) in the root view.
Use SCREAMING_SNAKE_CASE keys for all user-facing strings. Build first, then add
English values in Localizable.xcstrings — see SWIFTUI.md § Localization.
Navigating protocol and assert the
new method fires when the triggering view-model action runs.add-feature.$ARGUMENTS