# マニフェスト (fluxlay.yaml)

マニフェストファイルは壁紙のアイデンティティ、権限、機能を定義します。

## 完全なスキーマ

```yaml title="fluxlay.yaml"
# 必須フィールド
schemaVersion: 1 # マニフェストスキーマのバージョン（現状は 1 のみ）
name: string # 表示名
slug: string # URL セーフなユニーク識別子（小文字、数字、ハイフン）
version: string # セマンティックバージョン（例："0.1.0"）
kind: web | video | image # バンドル種別

# 条件付き必須：kind が video / image の場合
source: string # メディアファイルのパス（プロジェクトルートからの相対）

# オプション
description: string # 簡単な説明

# オプション：シェルコマンド
shell:
  <command-id>:
    run: string # 実行するコマンド
    reason: string # このコマンドが必要な理由
    required: # 必要なプログラム
      - string

# オプション：ネットワークアクセス
network:
  - origin: string # URL オリジン（例："https://api.example.com"）
    reason: string # アクセスが必要な理由

# オプション：壁紙が要求する権限
permissions:
  - keyboard # 例：useKeyboard でグローバル打鍵を購読する場合に必要

# オプション：カスタムプロパティ
properties:
  <property-id>:
    type: number | range | color | boolean | text | select | multi-select | image | file | font
    label: string # UI に表示するラベル
    # default は型ごとに異なる（image / file は default を持たない）
    default: any
    # 型ごとの追加フィールド（詳細は「properties」セクション参照）
```

## フィールド

### schemaVersion

マニフェストスキーマのバージョン。現状は `1` のみがサポートされており、必須フィールドです。`schemaVersion` を含まない、または未対応のバージョンを指定したマニフェストはバリデーションエラーになります。

### name

ギャラリーやデスクトップアプリに表示される表示名。あらゆる文字を使用可能です。

### slug

URL やストアで使われるユニーク識別子。パターン `[a-z0-9-]+` に一致する必要があります。初回公開後は変更できません。

### version

セマンティックバージョン文字列。公開ごとにまだ使われていないバージョンを指定する必要があります。

### kind

バンドル種別。`fluxlay publish` / `fluxlay build` 時の挙動を決定します。

| 値      | 内容                                                                                                                                   |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `web`   | React/Vite で構築するインタラクティブな壁紙。`vite.config.ts` を使ってビルドし、`dist/` の中身がバンドル化されます。                   |
| `video` | 動画ファイル単体の壁紙。`source` で指定された `.mp4` / `.webm` ファイルがバンドル化され、HTML はアプリ側が配信時に動的生成します。     |
| `image` | 画像ファイル単体の壁紙。`source` で指定された `.png` / `.jpg` / `.jpeg` / `.webp` / `.gif` がバンドル化され、HTML は動的生成されます。 |

### source

`kind: video` または `kind: image` の場合に必須。プロジェクトルートからの相対パスでメディアファイルを指定します。`web` kind では使用しません。

### description

壁紙の簡単な説明。ストアリスティングに表示されます。

### shell

壁紙が実行できるシェルコマンドを宣言します。各エントリのキーは SDK で使用するコマンド ID です（`useShell("command-id")`）。

| フィールド | 型         | 必須   | 説明                                                                     |
| ---------- | ---------- | ------ | ------------------------------------------------------------------------ |
| `run`      | `string`   | はい   | シェルコマンド文字列。`\|` で複数行対応。                                |
| `reason`   | `string`   | いいえ | 人間が読める説明。ユーザーの承認時に表示。                               |
| `required` | `string[]` | はい   | コマンドが依存するプログラム。依存なしの場合も `[]` を明示してください。 |

### network

壁紙がアクセスする必要のある外部オリジンを宣言します。宣言された origin は壁紙の CSP の `connect-src` / `img-src` / `media-src` / `font-src` に追加され、壁紙から `fetch` / `<img>` / `<video>` / `<audio>` / WebFont で到達できるようになります。`script-src` には追加されないため、外部スクリプトの読み込みは引き続き禁止されます。

| フィールド | 型       | 必須 | 説明                                   |
| ---------- | -------- | ---- | -------------------------------------- |
| `origin`   | `string` | はい | URL オリジン（スキーム + ホスト）。    |
| `reason`   | `string` | はい | アクセスが必要な理由。ユーザーに表示。 |

`origin` は `<scheme>://<host>[:<port>]` の純粋なオリジン形式である必要があります:

- スキームは `https` / `http` / `wss` / `ws` のいずれか
- パス・クエリ・フラグメント（`/`、`?`、`#`）を含めない（末尾スラッシュも不可）
- ワイルドカード（`*.example.com` 等）は不可。各 origin を個別に列挙してください

OK 例: `https://api.example.com`、`https://api.example.com:8080`、`wss://stream.example.com`
NG 例: `https://api.example.com/v1`（パス）、`https://*.example.com`（ワイルドカード）、`api.example.com`（スキーム無し）

> 💡 **Tip**: 宣言した origin に `fetch` しても `Access-Control-Allow-Origin` で弾かれる場合は、[外部 API の取得 (CORS 回避)](/ja/studio/developer/how-to/development/fetch-external-api.md) を参照してください。`proxiedFetch` でホスト経由にすれば CORS なしでも取得できます。

### permissions

壁紙が要求する権限を宣言します。グローバルなデスクトップ操作・OS リソースへのアクセスは全てここで明示する必要があり、宣言されていない権限の API は backend で 403 として拒否されます。

```yaml title="fluxlay.yaml"
permissions:
  - keyboard
  - ime-input
```

| 値          | 用途                                                                                                                                                                                                |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `keyboard`  | `useKeyboard` でグローバルキーボード入力を購読する場合に必須。全ウィンドウ・全アプリの打鍵が壁紙に流れるため、利用者にキーロガー扱いされ得る前提で宣言を必須としています。                          |
| `ime-input` | `useImeInput` で IME 経由のテキスト入力（日本語等）を受け取る場合に必須。壁紙自身のプロキシウィンドウに向けて入力された文字のみが対象で、他アプリの入力は一切見えないため `keyboard` とは別枠です。 |

宣言の重複・未知の値はバリデーションエラーになります。

### properties

壁紙のカスタムプロパティ（変数）を定義します。エンドユーザーが Fluxlay アプリの設定 UI からスライダー・カラーピッカー・トグル等で壁紙をカスタマイズできるようになります。各エントリのキーは SDK で使用するプロパティ ID です（`useProperties()` で取得）。

| 型             | UI コントロール                 | `default` の型 | 追加フィールド                                                                                                                                |
| -------------- | ------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `number`       | ステッパー / 入力               | `number`       | `min` / `max` / `step`（全て省略可）                                                                                                          |
| `range`        | スライダー                      | `number`       | `min` / `max` 必須、`step` 省略可。`min <= default <= max`                                                                                    |
| `color`        | カラーピッカー                  | `string`       | なし。`default` は 16 進カラー（`#rgb` / `#rrggbb` / `#rrggbbaa`）のいずれか                                                                  |
| `boolean`      | トグルスイッチ                  | `boolean`      | なし                                                                                                                                          |
| `text`         | テキスト入力                    | `string`       | `maxLength`（正の整数、省略可）/ `placeholder`（文字列、省略可）                                                                              |
| `select`       | ドロップダウン                  | `string`       | `options: [{value, label}]` 必須（1 件以上）。`default` は `options` の `value` のいずれかと一致必須                                          |
| `multi-select` | チェックリスト / マルチセレクト | `string[]`     | `options` 必須。`min` / `max`（選択数の下限・上限、非負整数）省略可。`default` の各要素は `options` に含まれる必要あり                        |
| `image`        | ファイルピッカー（画像）        | （なし）       | `accept`（MIME パターン配列、例: `["image/png"]`）/ `maxBytes`（正の整数）省略可。`default` を持たない                                        |
| `file`         | ファイルピッカー                | （なし）       | `accept` / `maxBytes` 省略可。`default` を持たない                                                                                            |
| `font`         | フォントセレクタ                | `string`       | `sources`（`system` および/または `google` の配列）必須。`category`（`sans-serif` / `serif` / `monospace` / `display` / `handwriting`）省略可 |

#### 補足

- 旧 `type: string` は廃止されました。ドロップダウン用途は `select`、自由入力テキスト用途は `text` に移行してください。
- `font` の `sources` に `google` を含む場合、Google Fonts 取得のため `network` 宣言が別途必要です。
- `image` / `file` の値は SDK ではローカル絶対パス（未設定時 `null`）として渡されます。

## 使用例

### Web 壁紙（React/Vite ベース）

```yaml title="fluxlay.yaml"
schemaVersion: 1
name: System Dashboard
slug: system-dashboard
version: 0.2.0
kind: web
description: システム情報と天気を表示するライブ壁紙。

shell:
  system-info:
    run: macchina
    reason: スタイル付きでシステム情報を表示します。
    required:
      - macchina
  weather:
    run: curl -s "https://wttr.in/?format=3"
    reason: 現在の天気情報を取得します。
    required:
      - curl

network:
  - origin: https://wttr.in
    reason: 現在の天気情報の取得に使用します。

permissions:
  - keyboard # WASD 等のキー入力で壁紙を操作する場合に宣言

properties:
  particleCount:
    type: number
    label: パーティクル数
    default: 100
    min: 10
    max: 500
    step: 10
  themeColor:
    type: color
    label: テーマカラー
    default: "#ff6b35"
  showClock:
    type: boolean
    label: 時計を表示
    default: true
  animationStyle:
    type: select
    label: アニメーションスタイル
    default: wave
    options:
      - value: wave
        label: Wave
      - value: spiral
        label: Spiral
  brightness:
    type: range
    label: 明るさ
    default: 0.8
    min: 0
    max: 1
    step: 0.05
  customLogo:
    type: image
    label: カスタムロゴ
    accept:
      - image/png
      - image/jpeg
    maxBytes: 1048576
```

### 動画壁紙

```yaml title="fluxlay.yaml"
schemaVersion: 1
name: My Video Wallpaper
slug: my-video-wallpaper
version: 0.1.0
kind: video
source: ./background.mp4
description: フルスクリーンでループ再生される動画壁紙。
```

### 画像壁紙

```yaml title="fluxlay.yaml"
schemaVersion: 1
name: My Photo Wallpaper
slug: my-photo-wallpaper
version: 0.1.0
kind: image
source: ./photo.png
description: 静止画の壁紙。
```
