# シェル壁紙

このチュートリアルでは、シェルコマンドを実行し、ターミナルエミュレータで出力を表示する壁紙を作ります。

## 前提条件

先に[はじめよう](/ja/studio/developer/tutorials/getting-started.md)チュートリアルを完了してください。

## シェルコマンドの宣言

`fluxlay.yaml` に `shell` セクションを追加します。

```yaml title="fluxlay.yaml"
schemaVersion: 1
name: System Monitor
slug: system-monitor
version: 0.1.0
kind: web
description: ライブなシステム情報を表示する壁紙。

shell:
  macchina:
    run: macchina
    reason: スタイル付きでシステム情報を表示します。
    required:
      - macchina
  fetch-ip:
    run: curl -s https://httpbin.org/ip | jq -r '.origin'
    reason: パブリック IP アドレスを取得します。
    required:
      - curl
      - jq

network:
  - origin: https://httpbin.org
    reason: パブリック IP アドレスの取得に使用します。
```

各コマンドには `reason`（なぜ必要か）と `required`（依存するプログラム）の宣言が必要です。ユーザーはコマンド実行前に承認を求められます。

## ターミナル出力の表示

スタイリング用に Tailwind CSS をインストールします。

<PackageManagerCommand type="add" dev packages="tailwindcss @tailwindcss/vite" />

`vite.config.ts` に Tailwind プラグインを登録します。

```ts title="vite.config.ts"
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

import { fluxlay } from "@fluxlay/vite";

export default defineConfig({
  plugins: [react(), tailwindcss(), fluxlay()]
});
```

`src/main.tsx` を更新します。

```tsx title="src/main.tsx"
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { useTerminal, useShell, TerminalThemes } from "@fluxlay/react";
import "./index.css";

function SystemMonitor() {
  const { terminalRef, instance } = useTerminal({
    fontSize: 13,
    theme: TerminalThemes.tokyoNight
  });

  const { error } = useShell("macchina", {
    terminal: instance,
    refreshInterval: 60000
  });

  return (
    <main className="h-screen w-screen bg-zinc-900 p-8">
      <div className="h-full w-full rounded-xl overflow-hidden border border-zinc-700">
        {error && <p className="p-4 text-red-400 text-sm">{error}</p>}
        <div ref={terminalRef} className="h-full w-full" />
      </div>
    </main>
  );
}

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <SystemMonitor />
  </StrictMode>
);
```

`src/index.css` を作成します。

```css title="src/index.css"
@import "tailwindcss";

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
```

## runShell でカスタム表示

表示を自分で制御したい場合は `runShell` を使います。

```tsx
import { useEffect, useState } from "react";
import { runShell } from "@fluxlay/react";

function IpAddress() {
  const [ip, setIp] = useState<string>("...");

  useEffect(() => {
    const fetchIp = async () => {
      const result = await runShell("fetch-ip");
      if (result.success) setIp(result.stdout.trim());
    };
    fetchIp();
    const id = setInterval(fetchIp, 30000);
    return () => clearInterval(id);
  }, []);

  return <p className="text-zinc-400 text-sm">Public IP: {ip}</p>;
}
```

## 次のステップ

タスクごとの詳しいガイド:

- [シェルコマンドの実行](/ja/studio/developer/how-to/development/use-shell.md) — `useShell` の実用パターン集。
- [シェルコマンドを命令的に実行](/ja/studio/developer/how-to/development/run-shell.md) — `runShell` でイベント駆動実行。
- [ターミナル出力の表示](/ja/studio/developer/how-to/development/use-terminal.md) — ターミナルエミュレータのレンダリング詳細。
- [ターミナルテーマのカスタマイズ](/ja/studio/developer/how-to/development/customize-theme.md) — 色を変える。

完成したら:

- [壁紙を公開する](/ja/studio/developer/tutorials/publish-wallpaper.md) — Fluxlay ストアに公開する。

API リファレンス:

- [useShell](/ja/studio/developer/reference/sdk/use-shell.md) / [runShell](/ja/studio/developer/reference/sdk/run-shell.md) / [useTerminal](/ja/studio/developer/reference/sdk/use-terminal.md)
- [マニフェスト (fluxlay.yaml)](/ja/studio/developer/reference/cli/manifest.md)
