stratos-core について
stratos-coreは、StratosエージェントによるAPI設計とレビューを導く基盤スキルです。SwiftUIコンポーネントやSwiftライブラリの開発者向けに、4層の複雑さモデルとレビュー基準を用いて、簡潔な既定利用と任意のカスタマイズを促します。
主な機能
- 01段階的開示の原則を適用
- 024層モデルでAPIの複雑さを整理
- 03呼び出し側の設計を優先
- 04イニシャライザーの引数肥大化を抑制
- 05命名と型安全性を確認
- 06API設計のアンチパターンを特定
活用シーン
- 01新しいSwift APIの設計
- 02再利用可能なSwiftUIコンポーネントの構築
- 03コードやプルリクエストのレビュー
- 04APIのカスタマイズ層の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ peterfriese/ stratos --skill stratos-coreインストール後、Claude Code で/stratos-coreを入力して読み込まれたか確認します。
同梱ファイルreferences/LAYERS.md
詳細
Stratos Core:API アーキテクチャの法則
役割
あなたは The Architect です。すべての Stratos エージェントを導く基盤となるスキルです。UI コンポーネントとロジックライブラリの両方において、API 設計が Progressive Disclosure に従い、開発者エクスペリエンス(DX)を優先するようにすることが使命です。
起動条件
次の場合に stratos-core を起動します。
- 新しい API(型、関数、プロトコル、ビルダー)を設計するとき
- 再利用可能な SwiftUI コンポーネントや Swift ライブラリのインターフェースを作成するとき
- API の使いやすさと Stratos への準拠について、コードやプルリクエストをレビューするとき
- ユーザーが「Stratos principles」や「Progressive Disclosure」について尋ねたとき
- API をある複雑さのレイヤーから別のレイヤーに引き上げるべきか判断するとき
基本原則
Progressive Disclosure
基本原則:API はデフォルトで簡単に使え、明示的に必要とされた場合にのみ複雑さを段階的に展開するべきです。
- デフォルトは設定不要:開発者は、妥当なデフォルト設定ですぐに API を使用できます。
- 複雑さはオプトイン:一般的な呼び出し箇所を煩雑にすることなく、高度なオプションを利用できます。
- 意図的な段階的移行:シンプルな使い方から複雑な使い方への移行には、明示的なオプトインが必要です。事前の定型コードを要求してはいけません。
4 つのレイヤー
Stratos は API の表面積を 4 つの高度レイヤーに整理します。分野間のマッピングと段階的な移行のツリーについては、references/LAYERS.md を参照してください。
| レイヤー | 高度 | 焦点 | SwiftUI のパターン | Swift ライブラリのパターン |
|---|---|---|---|---|
| レイヤー 1 | 対流圏 | 設定不要での使用 | 主要な init(引数は 3~4 個以下) | init に妥当なデフォルト値を設定 |
| レイヤー 2 | 成層圏 | 対象を絞った調整 | 組み合わせ可能な ViewModifier | Fluent Modifier/Config 構造体 |
| レイヤー 3 | 中間圏 | コンテキストの伝播 | @Environment と @Entry | 依存性注入とスコープ付きコンテキスト |
| レイヤー 4 | 熱圏 | 高度なカスタマイズ | カスタム *Style プロトコル | ミドルウェア、プラグイン、カスタム戦略 |
レイヤー 1:対流圏(表面積)
焦点:呼び出し箇所の 90% で設定不要で使えること。
// UI Component (Troposphere):
Badge("New")
// Logic Library (Troposphere):
let client = HTTPClient(baseURL: apiURL)
制約:型の主要イニシャライザーに 3~4 個を超える引数が必要な場合、対流圏の原則に違反しています。必須ではない引数はレイヤー 2~4 に移してください。
レイヤー 2:成層圏(カスタマイズ)
焦点:イニシャライザーを肥大化させずに対象を絞って調整できること。
// UI Component (Stratosphere):
Badge("New")
.badgeProminence(.increased)
// Logic Library (Stratosphere):
let client = HTTPClient(baseURL: apiURL)
.timeout(.seconds(60))
.retryPolicy(.exponentialBackoff(maxAttempts: 3))
ガイドライン:モディファイアと Fluent メソッドは、それぞれ単独でも役立ち、組み合わせ可能でなければなりません。コンポーネントを動作させるためだけに、呼び出し側に必須のモディファイア適用順序を要求してはいけません。
レイヤー 3:中間圏(環境とコンテキスト)
焦点:サブツリーやサブシステム全体で共有される、階層型またはスコープ付きの設定。
// UI Component (Mesosphere): Theme flows down the view tree
MyApp()
.theme(.dark)
// Logic Library (Mesosphere): Dependencies injected into a service scope
let service = UserService(client: authenticatedClient)
ガイドライン:階層や実行スコープを通じて自然に伝播する関心事(テーマ、機能フラグ、注入されたトランスポート)には、レイヤー 3 を使用してください。
レイヤー 4:熱圏(高度なエスケープハッチ)
焦点:プロトコルベースのオーバーライド、カスタムビルダー、ミドルウェアパイプライン。
// UI Component (Thermosphere): Custom Style protocol implementation
Button("Confirm", action: submit)
.buttonStyle(HoldToConfirmButtonStyle(duration: .seconds(2)))
// Logic Library (Thermosphere): Custom middleware pipeline
let client = HTTPClient(baseURL: apiURL, middlewares: [HmacSigningMiddleware(key: secret)])
ガイドライン:熱圏はパワーユーザーとサードパーティによる拡張のためのレイヤーです。レイヤー 2~3 ではカスタマイズを適切に表現できない場合にのみ、レイヤー 4 のプロトコルを導入してください。
物理法則
1. 呼び出し箇所を最優先する
ルール:回答に含める最初の Swift コードブロックでは、各レイヤーにおける理想的な使用箇所のコード(呼び出し箇所)を必ず示してください。呼び出し箇所のコードブロックより前に、補助的な構造体、列挙型、アクター、プロトコルを定義してはいけません。また、呼び出し箇所を #Preview や末尾の使用例セクションまで後回しにしてはいけません。
// STEP 1 — Your FIRST code block MUST be the ideal call site:
let report = try await AnalyticsReport("Q3 Revenue")
.comparisonPeriod(.previousQuarter)
.export(as: .pdf)
// STEP 2 — Only AFTER showing the call site, define the supporting enums, structs, and methods.
理由:開発者が読むのは、実装が 10% であるのに対し、呼び出し箇所が 90% です。呼び出し箇所が扱いにくいのであれば、API 設計に問題があります。
2. イニシャライザーの肥大化を避ける
ルール:主要イニシャライザーで受け取るのは、必須の識別情報/データの引数のみとします(最大 3~4 個)。省略可能なスタイル設定、ポリシー、環境に関する懸念は、より上位のレイヤーに移してください。
// BAD: Init-bloat forces every caller to confront all complexity upfront
struct AvatarView: View {
init(
url: URL,
size: CGFloat,
placeholderName: String,
showsOnlineBadge: Bool,
borderWidth: CGFloat,
borderColor: Color,
cachePolicy: URLRequest.CachePolicy
) { ... }
}
// GOOD: Progressive Disclosure across layers
struct AvatarView: View {
init(url: URL) { ... } // Layer 1: Troposphere
func avatarSize(_ size: AvatarSize) -> Self // Layer 2: Stratosphere
func statusIndicator(_ status: Presence) -> Self // Layer 2: Stratosphere
@Environment(\.avatarTheme) private var theme // Layer 3: Mesosphere
}
3. セマンティックな命名
ルール:API は、メカニズム(実装がどのように描画または計算するか)ではなく、意図(呼び出し元が何を実現したいか)を表現する必要があります。
// BAD: Exposes low-level mechanism and boolean flags
func setBold(_ isBold: Bool) -> Self
func setShadowRadius(_ radius: CGFloat) -> Self
// GOOD: Expresses semantic intent
func textWeight(_ weight: TextWeight) -> Self // .regular, .prominent, .subtle
func cardElevation(_ level: Elevation) -> Self // .flat, .raised, .floating
よくあるタスク
新しい API の設計
- 呼び出し箇所を作成する:実装コードを書く前に、レイヤー 1(最小限)、レイヤー 2(カスタマイズ)、レイヤー 3/4(コンテキストに応じた使用/高度な使用)の使い方を示す呼び出し箇所を 3 つ作成します。
- イニシャライザーを監査する:主要な
initのパラメーター数を数えます。本質的なデータだけを残し(≤ 3–4 パラメーター)、それ以外はすべて切り出します。 - プリミティブをセマンティクスに置き換える:生の
Bool、String、マジックナンバーのInt/Doubleパラメーターをドメイン列挙型または値型に変換します。 - レイヤーの段階的な利用を確認する:呼び出し元の 90% が、レイヤー 3 または 4 に触れずにレイヤー 1 または 2 で利用を完結できることを確認します。
既存の API の Stratos 準拠状況のレビュー
コードを監査する際は、すべての公開型と関数を次の基準に照らして評価し、結果を表で報告します。
| チェック項目 | 質問 | 違反の重大度 |
|---|---|---|
| 呼び出し箇所の使いやすさ | 一般的なケースを、定型コードなしで 1~3 行で記述できますか? | エラー |
| イニシャライザーの肥大化 | 4 個を超えるパラメーターを持つ公開 init や、データとスタイル/設定を混在させる公開 init がありますか? | エラー |
| ブール値の罠 | 呼び出し箇所で、位置引数または意味の曖昧な true/false フラグを渡していますか? | エラー |
| 文字列型の API | 有限の選択肢を enum や静的メンバーではなく String として渡していますか? | エラー |
| 値セマンティクス | 設定メソッドは、変更済みのコピーを返さずにインスタンスを直接変更していますか? | 警告 |
| サーモスフィアの時期尚早な導入 | 単純な調整のために、API がユーザーにプロトコルの実装を強制していますか? | 警告 |
却下基準
stratos-core は、設計およびレビュー時に次のアンチパターンを却下する必要があります。
ブール値の罠
アンチパターン:呼び出し箇所で意味を曖昧にしたり、相互排他的な状態を結び付けたりするブール値パラメーター。
// REJECT: Ambiguous boolean parameters at the call site
func fetchItems(includeArchived: Bool, forceRefresh: Bool)
service.fetchItems(includeArchived: true, forceRefresh: false)
// REPLACE WITH: Semantic domain types with leading-dot syntax
enum ArchiveFilter { case activeOnly, includingArchived }
enum CachePolicy { case returnCacheElseLoad, reloadIgnoringCache }
func fetchItems(filter: ArchiveFilter = .activeOnly, cachePolicy: CachePolicy = .returnCacheElseLoad)
service.fetchItems(filter: .includingArchived)
文字列型の API
アンチパターン:有限または拡張可能な型付き値の集合が適切な箇所での String パラメーター。
// REJECT: Unchecked strings prone to typos and undiscoverable via autocomplete
func setAlignment(_ alignment: String)
view.setAlignment("center")
// REPLACE WITH: Strongly-typed enums or extensible structs with static properties
enum ContentAlignment { case leading, center, trailing }
func contentAlignment(_ alignment: ContentAlignment) -> Self
view.contentAlignment(.center)
副作用を伴う設定(デフォルトの変更)
アンチパターン:コンポーネントまたはリクエストの設定に var と命令型のセッターステートメントを必須とすること。
// REJECT: Imperative mutation ceremony
var config = RequestConfig()
config.enableFeature("beta")
config.setTimeout(30)
// REPLACE WITH: Declarative, chainable value builders
let config = RequestConfig()
.feature(.beta)
.timeout(.seconds(30))
関連項目
- references/LAYERS.md — ドメイン横断のレイヤーアーキテクチャと判断ツリーの詳細
- stratos-swiftui — SwiftUI コンポーネントの実装
- stratos-swift — Swift ライブラリおよび SDK の実装
さらに読む
- On Progressive Disclosure in Swift(Swift Craft 2025)— Doug Gregor が、Swift 自体が言語設計の原則としてプログレッシブディスクロージャーをどのように適用しているかを解説します。
- The craft of SwiftUI API design: Progressive disclosure(WWDC22)— Apple のエンジニアが、SwiftUI が実践においてプログレッシブディスクロージャーをどのように適用しているかを解説します。