Zenn
🤖

【個人開発】GitHub Copilot Agent Modeを使って1日(12時間)でアプリを開発・デプロイした話

2025/03/01に公開

はじめに

こんにちは或いはこんばんは。Ryuzakiです。

2025年2月6日にGitHub Copilot Agent Modeのプレビュー版が提供されたというアナウンスがありました。まだ試せていなかったため、何がどこまでできるのかを色々検証してみました。

個人的に興味があったのは、可能な限りAIに丸投げでどこまでアプリ開発ができるのか、という点です。そこで、今回は個人開発で作る予定だったアイデアの1つをGitHub Copilot Agent Modeに任せることにしました。

作成したアプリの概要

今回作成したアプリは「SlideSynth」という、各種オンラインイベントや会議での画面共有のスクリーンショットを整理するためのアプリです。

アプリURL

https://slidesynth.vercel.app/

主な機能

初回リリースでは以下の機能を提供しています。

  • 画像アップロード機能(ファイル選択+ドラッグアンドドロップ)
  • 画像順序並び替え機能
  • 画像削除機能
  • アスペクト比設定機能
  • クロップ範囲の設定機能
  • クロップイメージのリアルタイムプレビュー機能(デスクトップ版・モバイル版)
  • クロップ範囲微調整機能
  • 一括クロップ・PDF化機能(進捗状況のリアルタイム通知込)
  • PDFダウンロード機能(ファイル名設定用のモーダル込)
  • テーマ(ライトモード/ダークモード)切り替え機能
  • 言語(日本語/英語)切り替え機能

実装の流れ

今回はすべての実装プロセスをなるべくAIに任せる形で実施しました。以下、具体的な実装の流れを紹介します。各項目のカッコ内の時間は大まかな作業時間です。

1. 前準備(Claude Sonnet 3.5)

このフェーズでは、GitHub Copilot Agent Modeに作成したいアプリケーションの内容を正しく伝えるために、Claude Sonnet 3.5を用いて3つのドキュメントを作成しました。

1.1 要件定義(30分)

1つ目のドキュメントとして、作成するアプリケーションで実装する機能や画面数等の要件を記載したドキュメントを作成しました。このドキュメントの作成には以下のプロンプトを用いました。

アプリケーション情報策定用プロンプト
あなたは、ユーザーのアプリケーション開発を支援する専門アシスタントです。以下の手順で、ユーザーが考えるアプリケーションの詳細情報を整理し、ドキュメント化してください。

## 実行手順

1. ユーザーが作成したいアプリケーションについて、以下の観点から質問を行ってください:
   - アプリケーションの目的と主な機能
   - 対象ユーザーとユースケース
   - UI/UXデザインの方針(色調、テーマなど)
   - 主要画面とそれぞれの機能
   - 特殊な要件や制約条件

2. 質問と回答のプロセスを通じて、アプリケーションの詳細を明確にしてください。

3. ユーザーが「ドキュメントを出力してください」と言うまで、必要に応じて追加質問を続けてください。

4. ユーザーからの回答に基づいて、以下のレイアウトに従ったマークダウン形式のドキュメントを作成してください。

## 作成するドキュメントのレイアウト

\```markdown
# {アプリケーション名}アプリケーション情報
## アプリケーション概要
(アプリケーションの概要を箇条書きで出力)

## 画面概要
### 全体概要
(アプリケーションの全体的なデザインや方針等の概要を箇条書きで出力)

#### UI定義
(利用する色情報などを基本的な要素ごとに明記)
(ダークモードとライトモードの両方が存在する場合は双方に関して出力)

#### 機能一覧
(アプリケーション全体に関わる機能の一覧を箇条書きで出力)

### {画面名}
(対象画面の概要を箇条書きで出力)

#### 機能一覧
(対象画面で利用される機能の一覧を箇条書きで出力)
\```

## 重要な注意点

- コードの生成は行わず、概念レベルでの理解と計画に焦点を当ててください
- 技術的な専門用語は必要最低限に抑え、わかりやすい言葉で説明を行ってください
- ユーザーの回答がない部分については、適切に質問を行い情報を収集してください
- 各セクションは箇条書きでシンプルかつ明瞭に記述してください

それでは、ユーザーが開発したいアプリケーションについて質問を始めてください。
実際に使用したアプリケーション情報(Claudeの出力内容を一部手直し)
# SlideSynthアプリケーション情報

## アプリケーション概要

- スクリーンショット画像からスライドを効率的に抽出し、PDFドキュメントを生成するWebアプリケーション
- Next.jsを使用したフロントエンドアプリケーション
- Tailwind CSSによるモダンなUIデザイン
- レスポンシブ対応(デスクトップ/モバイル)
- シングルページアプリケーション(SPA)としての実装
- 4つの主要画面で構成(ホーム・メイン・進捗確認・ダウンロード)

## 画面概要

### 全体概要

- グラデーションを活用したモダンなデザイン
- 装飾的な背景要素による視覚的な魅力
- レスポンシブデザインによる各デバイスへの最適化
- アニメーションによる滑らかなUI/UX
- 一貫したグラデーションテーマカラー(青系統)の使用

### UI定義

### 基本カラー

- ライトモード
    - 背景色: `#ffffff`(白)
    - 前景色: `#171717`(濃いグレー)
- ダークモード
    - 背景色: `#0a0a0a`(黒)
    - 前景色: `#ededed`(明るいグレー)

### グラデーション

- メインビジュアル(ボタン、ヘッダー等)
    - ライトモード: `from-blue-600 (#2563eb) to-blue-800 (#1e40af)`
    - ダークモード: `from-blue-400 (#60a5fa) to-blue-600 (#2563eb)`
- 背景装飾
    - ライトモード: `from-blue-500/8`(透明度8%の#3b82f6)
    - ダークモード: `from-blue-400/10`(透明度10%の#60a5fa)

### UI要素カラー

- ステータス表示
    - エラー: `#ef4444`(red-500)
    - 成功: `#22c55e`(green-500)
- テキスト
    - 主要テキスト: `#4b5563`(gray-600)
    - 補助テキスト: `#9ca3af`(gray-400)
- ボーダー
    - ライトモード: `#d1d5db`(gray-300)
    - ダークモード: `#4b5563`(gray-600)

### 機能一覧

- ダークモード切り替え機能(全画面共通)
- エラー表示機能(トースト形式)
- アニメーションエフェクト(フェードイン、フロート)
- BuyMeCoffeeによる開発者サポート機能
    - 全画面共通の右下固定ポップアップ(ウィジェット)
    - ダウンロード画面でのリンクボタン

### ホーム画面

- アプリケーションのエントリーポイント
- シンプルかつ魅力的なランディングページデザイン
- アプリケーションの主要機能の簡潔な説明

### 機能一覧

- ロゴとタイトル表示
- アプリケーション概要の表示
- エディタ画面への誘導(CTAボタン)
- アニメーション付きの装飾要素

### メイン画面

- 画像処理とクロップ設定の中心画面
- 画像管理と編集機能を統合
- リアルタイムプレビュー機能

### 機能一覧

- 画像アップロード機能(複数ファイル対応)
- 画像一覧表示(ドロワー形式)
- 画像並び替え機能
- クロップ設定機能
    - 縦横比プリセット(16:9, 16:10, 4:3, 自由)
    - スライド自動検出機能(β)
    - 手動微調整機能(X座標、Y座標、幅、高さ)
- リアルタイムクロッププレビュー
- PDF生成開始機能

### PDF生成進捗確認画面

- PDF生成プロセスの視覚的フィードバック
- 生成状況のリアルタイム表示

### 機能一覧

- プログレスバーによる進捗表示
- 生成状態のステータス表示
- 処理キャンセル機能
- 自動的なダウンロード画面への遷移

### PDFダウンロード画面

- 生成されたPDFのダウンロード管理
- 完了通知とファイル管理

### 機能一覧

- PDFファイル名カスタマイズ機能(モーダル形式)
- PDFダウンロード機能
- ダウンロード完了表示
- ホームへの戻る機能
- 開発者サポートリンク(BuyMeCoffee)

1.2 ディレクトリ構成策定(5分)

2つ目のドキュメントとして、アプリケーションのディレクトリ構成をまとめたドキュメントを作成しました。このドキュメントの作成には、上記で作成したアプリケーションの情報と以下のプロンプトを用いました。

ディレクトリ構成策定用プロンプト
あなたは最適なアプリケーションディレクトリ構造を作成する専門家です。以下のタスクを実行してください:

1. ユーザーがアップロードした「アプリケーション情報」ドキュメントの内容を詳細に分析してください。

2. この情報に基づいて、以下の要件を満たす理想的なアプリケーションディレクトリ構造を生成してください:
   - ドキュメントに記載されているフレームワークのベストプラクティスに従ってください
   - フレームワークの指定がない場合は、ユーザーに使用予定のフレームワークを丁寧に質問してください
   - 完全な実装に必要なすべてのディレクトリとファイルを含めてください
   - 網羅的に作成し、必要なファイルやディレクトリを省略しないでください

3. 出力は以下のような整理されたツリー形式で提示してください:
\```
project-root/
├── src/
│   ├── components/
│   ├── pages/
│   └── utils/
├── public/
│   ├── images/
│   └── fonts/
├── config/
└── package.json
\```

4. 回答はディレクトリツリー構造のみを含め、説明や導入、結論は含めないでください。

「アプリケーション情報」ドキュメントを分析し、要件に基づいた適切なディレクトリ構造を生成してください。
実際に利用したディレクトリ構成
slidesynth/
├── README.md                 // プロジェクト概要と設定情報
├── package.json              // 依存関係、スクリプト、パッケージ管理
├── tsconfig.json             // TypeScriptコンパイラ設定
├── src/
│   ├── app/                  // Next.js App Router用ルートディレクトリ
│   │   ├── layout.tsx        // ルートレイアウト
│   │   ├── page.tsx          // ホーム画面用ページ
│   │   ├── main/           // メイン画面(画像アップロード/クロップ設定)
│   │   │   └── page.tsx
│   │   ├── processing/       // PDF生成進捗画面
│   │   │   └── page.tsx
│   │   └── download/         // PDFダウンロード画面
│   │       └── page.tsx
│   ├── components/           // UIコンポーネント
│   │   ├── common/           // 共通コンポーネント
│   │   │   ├── ThemeToggle.tsx       // カラーモード切替
│   │   │   └── ErrorBanner.tsx       // エラー表示
│   │   ├── features/         // 機能毎のコンポーネント
│   │   │   ├── ImageUploader.tsx     // 画像アップロード
│   │   │   ├── ImageList.tsx         // 画像一覧表示
│   │   │   ├── ImageCropper.tsx      // クロップ設定/プレビュー
│   │   │   └── ProgressBar.tsx       // PDF生成進捗表示
│   │   └── layouts/          // レイアウトコンポーネント
│   │       ├── Header.tsx            // ヘッダー(メニューボタン含む)
│   │       └── Footer.tsx            // フッター(クレジット、サポートリンク)
│   ├── hooks/                // カスタムフック
│   │   ├── useImageList.ts     // 画像追加/削除/並び替え管理
│   │   ├── useImageCrop.ts     // クロップ座標・アスペクト比管理
│   │   ├── useSlideDetection.ts // スライド自動検出処理
│   │   ├── usePdfGenerator.ts  // PDF生成処理制御
│   │   └── usePdfStore.ts      // グローバルPDFステート管理
│   ├── lib/                  // ユーティリティ関数や設定ファイル
│   │   └── ...               
│   ├── types/                // TypeScript型定義
│   │   └── index.ts
│   ├── styles/               // グローバルスタイル
│   │   └── globals.css
│   └── utils/                // ヘルパー関数
│       └── validators.ts
└── docs/                     // 設計ドキュメント

1.3 コーディング規約策定(5分)

最後のドキュメントとして、各種ベストプラクティスに沿ったコーディング規約のドキュメントを作成しました。なお、設定するコーディング規約の内容は、Makiさんの以下のドキュメントを参考に設定しました。
https://github.com/Sunwood-ai-labs/MysticLibrary/blob/main/prompts/coding/BEST_PROGRAMMING_PRACTICES_REQUIREMENTS_JA.md

コーディング規約策定用プロンプト
Next.js/App Routerを用いたプロジェクトにおいて適切なコーディング規約を提示してください。 なお、命名規約やコメント等はベストプラクティスに習ったものにしてください。

また、以下のコーディングの原理・原則はすべて含めるようにしてください。

\```markdown
# コーディング・ドキュメント作成原則
以下の原則はコードだけでなく、ドキュメント(Markdown形式のファイルを含む)にも適用

## DRY(Don't Repeat Yourself)
- 同一・類似処理は関数・モジュール化することで再利用性を高める
- ドキュメントでも情報の重複を避け、必要に応じて相互参照を使用する

## 責務の分離(Separation of Concerns)
- 各モジュール・クラス・関数は単一責務を明確にし、表現・ロジック・データ処理を分離する
- ドキュメントも目的別にファイルを分け、適切に構造化する

## KISS(Keep It Simple, Stupid)
- コードは可能な限りシンプルに保ち、過度な複雑化を避ける
- ドキュメントも簡潔で理解しやすい記述を心がける

## 分割統治(Divide and Conquer)
- 大きな問題は小さな単位に分割し、テスト・保守性を向上させる
- 大きなドキュメントは適切に章立てし、必要に応じて複数のファイルに分割する

## 防御的プログラミング(Defensive Programming)
- 入力値検証、例外処理、エラー対策を行い、堅牢性とセキュリティを確保する
- ドキュメントでも想定外の使用シナリオや注意点を明記する

## YAGNI(You Aren't Gonna Need It)
- 現在の要件に集中し、不要な将来予測による過剰実装を避ける
- ドキュメントも現時点で必要な情報に焦点を当てる

## 可読性とドキュメンテーション
- 変数・関数・クラス名は英語で、役割が一目でわかるような命名を行う
- コメントやREADMEでコードの意図・ロジックを日本語で明確に説明する
- ドキュメントは一貫した書式とスタイルを維持する

## SOLID原則の適用
- SRP, OCP, LSP, ISP, DIPを考慮し、拡張性・保守性の高い設計を行う
- ドキュメントも単一責任の原則に従い、適切に構造化する
\```
実際に利用したコーディング規約(Claudeの出力内容を一部手直し)
# SlideSynthコーディング規約

## 命名規則

### 変数名・関数名

- **変数名**: camelCase で英語の明確な名前を使用
  \```tsx
  // 良い例
  const userProfile = { ... };
  const isLoading = true;

  // 悪い例
  const data = { ... };
  const flag = true;
  \```

- **関数名**: 動詞で始める camelCase (例: `getData`, `updateUser`)
  \```tsx
  // 良い例
  const fetchUserData = async (userId: string) => { ... };

  // 悪い例
  const userData = async (userId: string) => { ... };
  \```

### コンポーネント名

- PascalCase での命名
- 名前は役割を明確に表す
- 関連コンポーネントはグループ化する

\```tsx
// 良い例
// ProductCard.tsx
export default function ProductCard() { ... }

// ProductCard/index.tsx
import ProductImage from './ProductImage';
import ProductDetails from './ProductDetails';

export default function ProductCard() { ... }
\```

### 定数

- 全て大文字のスネークケース
- 関連する定数はオブジェクトにグループ化

\```tsx
// constants.ts
export const MAX_ITEMS_PER_PAGE = 20;

export const API_ENDPOINTS = {
  USERS: '/api/users',
  PRODUCTS: '/api/products',
} as const;
\```

## コンポーネント設計

### コンポーネントの分類

- **UIコンポーネント**: 純粋な表示機能、再利用可能
- **ページコンポーネント**: ルート単位のコンポーネント
- **機能コンポーネント**: 特定の機能セット
- **レイアウトコンポーネント**: ページ構造を定義

### サーバーコンポーネントとクライアントコンポーネント

- デフォルトでサーバーコンポーネントを使用
- クライアントが必要な場合のみ `'use client'` ディレクティブを使用
- 混在する場合はクライアントコンポーネントを最小範囲に限定

### Props の定義

- TypeScript インターフェイスまたは型エイリアスを使用
- 必須とオプションのプロパティを明示
- デフォルト値を適切に設定

## データフェッチング

### 基本方針

- サーバーコンポーネントでのデータフェッチを優先
- RSC (React Server Components) でのデータ取得パターンを活用
- データを取得する関数は再利用可能にモジュール化

### キャッシュと再検証

- キャッシュ戦略の設計
  - `cache: 'no-store'` - 動的データ
  - `{ next: { revalidate: 秒数 } }` - 時間ベースの再検証
  - デフォルト - 静的データ

## 状態管理

### ローカル状態

- `useState``useReducer` を適切に使い分け
- 複雑な状態には `useReducer` を使用

### グローバル状態

- Context API を活用
- 必要に応じて zustand や jotai などの軽量ライブラリを検討

## エラーハンドリング

### App Router のエラーハンドリング

- `error.tsx` ファイルを使用して UI レベルのエラー境界を実装

### データフェッチのエラーハンドリング

- try-catch パターンを一貫して使用
- エラーメッセージを標準化

## パフォーマンス最適化

### コンポーネントの最適化

- メモ化の適切な使用: `useMemo`, `useCallback`, `memo`
- 不要な再レンダリングを防止

### 画像最適化

- Next.js の Image コンポーネントを使用
- 適切なサイズと優先度を設定

### コード分割

- ダイナミックインポートを活用

## 型定義

### 基本的な型定義

- 適切な型を常に定義
- `any` 型は避ける
- 共通型は集中管理

### API レスポンス型

- API レスポンスの型を明示的に定義
- Zod などのバリデーションライブラリの使用も検討

## テスト

### テスト方針

- ユニットテスト、インテグレーションテスト、E2Eテストを適切に組み合わせる
- テストカバレッジ目標を設定

### コンポーネントテスト

- React Testing Library を使用
- ユーザー行動を中心にテスト

### API モックとテスト

- MSW などを使用して API のモック

## アクセシビリティ

### 基本方針

- WCAG ガイドラインに従う
- キーボード操作対応
- スクリーンリーダー対応
- 色のコントラスト確保

### チェックリスト

- 適切な HTML セマンティクス使用
- `alt` 属性を全ての画像に付与
- ARIA 属性の適切な使用
- フォーカス順序の管理

## ドキュメント作成

### コードドキュメント

- JSDoc スタイルのコメント
- 複雑なロジックには詳細な説明

### README とプロジェクトドキュメント

- 一貫した形式
- セットアップ手順、依存関係、使用方法を明記
- API や重要な概念の説明

## コーディング原則の適用

### DRY(Don't Repeat Yourself)

- **ポイント**: 同一ロジックの重複を避ける
- **適用方法**:
  - 共通ロジックを関数化、共通コンポーネントを作成
  - ユーティリティ関数を `utils/` ディレクトリに集約
  - 共通スタイルを CSS 変数または Tailwind のコンポーネントクラスで管理

### 責務の分離(Separation of Concerns)

- **ポイント**: コンポーネント、関数、モジュールは単一責任を持つべき
- **適用方法**:
  - ビジネスロジックと UI を分離 (カスタムフックでロジックを分離)
  - データ取得と表示を分離 (サーバコンポーネントでデータ取得、クライアントコンポーネントで UI 操作)
  - レイアウトと機能コンポーネントを分離

### KISS(Keep It Simple, Stupid)

- **ポイント**: シンプルなコードは理解しやすく、バグも少ない
- **適用方法**:
  - 過度に抽象化しない
  - 複雑なワンライナーより読みやすい複数行のコードを優先
  - 過剰な最適化を避ける(必要になるまでメモ化しない)

### 分割統治(Divide and Conquer)

- **ポイント**: 大きな問題を小さな単位に分割して解決
- **適用方法**:
  - 大きなコンポーネントを小さなコンポーネントに分割
  - ルート単位で機能を分割
  - コンポーネント設計時に階層構造を意識

### 防御的プログラミング(Defensive Programming)

- **ポイント**: 予期せぬエラーに対して堅牢なコードを書く
- **適用方法**:
  - props や API レスポンスにデフォルト値や検証を追加
  - エラーバウンダリを適切に配置
  - API 呼び出しには常に try-catch を使用

### YAGNI(You Aren't Gonna Need It)

- **ポイント**: 現在必要ないものは実装しない
- **適用方法**:
  - 現在の要件に集中し、将来の機能拡張を過度に予測しない
  - 必要になるまで機能を追加しない
  - リファクタリングをいとわない姿勢を持つ

### 可読性とドキュメンテーション

- **ポイント**: コードは書く時間より読む時間の方が長い
- **適用方法**:
  - 意味のある変数名、関数名を使用
  - 複雑なロジックには適切なコメントを追加
  - README や JSDoc を活用して知識共有

### SOLID原則の適用

- **単一責任の原則 (SRP)**: クラスやモジュールは単一の責任を持つべき
- **開放閉鎖の原則 (OCP)**: コードは拡張に対して開かれ、修正に対して閉じているべき
- **リスコフの置換原則 (LSP)**: サブタイプは基本型と置換可能であるべき
- **インターフェース分離の原則 (ISP)**: クライアントは使用しないインターフェースに依存すべきでない
- **依存性逆転の原則 (DIP)**: 抽象化に依存し、具象化に依存しない

**適用方法**:
- コンポーネントは単一の責任を持つように設計
- 条件分岐よりもコンポーネント合成を優先
- インターフェースを使用してコンポーネント間の結合度を下げる
- 依存性注入パターンを活用して柔軟性を高める

2. 環境整備

2.1 VS Code Insidersインストール + GitHubアカウントの連携(10分)

執筆時点では、GitHub Copilot Agent Modeを利用するにはVSCode Insidersが必要です。
VSCode Insidersのインストール方法やGitHubアカウントとの連携方法に関しては以下の記事で分かりやすく説明されていますので、ご参照ください。
https://developer.mamezou-tech.com/blogs/2025/02/16/try-github-copilot-agent/
https://zenn.dev/ncdc/articles/eb1fc13c001031

2.2 GitHub Copilot Agent Modeの初期設定(5分)

GitHub Copilotは.github/copilot-instructions.mdというファイルを用いてCustom Instructions(システムプロンプト)が設定可能です。今回は上記で作成したアプリケーション情報とディレクトリ構成を合わせ、英訳したものを設定しました。

Custom Instructions
.github/copilot-instructions.md
# SlideSynth Application Information

## Application Overview

* Web application that efficiently extracts slides from screenshot images and generates PDF documents
* Frontend application built with Next.js
* Modern UI design using Tailwind CSS
* Responsive design (desktop/mobile)
* Implemented as a Single Page Application (SPA)
* Composed of four main screens (Home, Main, Progress Check, Download)

## Project Structure

### Directory Structure

\```
slidesynth/
├── README.md                 // Project overview and configuration information
├── package.json              // Dependencies, scripts, package management
├── tsconfig.json             // TypeScript compiler configuration
├── src/
│   ├── app/                  // Root directory for Next.js App Router
│   │   ├── layout.tsx        // Root layout
│   │   ├── page.tsx          // Home screen page
│   │   ├── main/             // Main screen (image upload/crop settings)
│   │   │   └── page.tsx
│   │   ├── processing/       // PDF generation progress screen
│   │   │   └── page.tsx
│   │   └── download/         // PDF download screen
│   │       └── page.tsx
│   ├── components/           // UI components
│   │   ├── common/           // Common components
│   │   │   ├── ThemeToggle.tsx       // Color mode toggle
│   │   │   └── ErrorBanner.tsx       // Error display
│   │   ├── features/         // Feature-specific components
│   │   │   ├── ImageUploader.tsx     // Image upload
│   │   │   ├── ImageList.tsx         // Image list display
│   │   │   ├── ImageCropper.tsx      // Crop settings/preview
│   │   │   └── ProgressBar.tsx       // PDF generation progress display
│   │   └── layouts/          // Layout components
│   │       ├── Header.tsx            // Header (including menu button)
│   │       └── Footer.tsx            // Footer (credits, support links)
│   ├── hooks/                // Custom hooks
│   │   ├── useImageList.ts     // Image add/delete/reorder management
│   │   ├── useImageCrop.ts     // Crop coordinates and aspect ratio management
│   │   ├── useSlideDetection.ts // Automatic slide detection processing
│   │   ├── usePdfGenerator.ts  // PDF generation process control
│   │   └── usePdfStore.ts      // Global PDF state management
│   ├── lib/                  // Utility functions and configuration files
│   │   └── ...               
│   ├── types/                // TypeScript type definitions
│   │   └── index.ts
│   ├── styles/               // Global styles
│   │   └── globals.css
│   └── utils/                // Helper functions
│       └── validators.ts
└── docs/                     // Design documents
\```

## Screen Overview

### General Overview

* Modern design utilizing gradients
* Visual appeal through decorative background elements
* Optimized for each device through responsive design
* Smooth UI/UX with animations
* Consistent gradient theme colors (blue variations)

### UI Definition

#### Base Colors
* Light Mode
  - Background color: `#ffffff` (white)
  - Foreground color: `#171717` (dark gray)
* Dark Mode
  - Background color: `#0a0a0a` (black)
  - Foreground color: `#ededed` (light gray)

#### Gradients
* Main Visual (buttons, headers, etc.)
  - Light Mode: `from-blue-600 (#2563eb) to-blue-800 (#1e40af)`
  - Dark Mode: `from-blue-400 (#60a5fa) to-blue-600 (#2563eb)`
* Background Decorations
  - Light Mode: `from-blue-500/8` (8% opacity #3b82f6)
  - Dark Mode: `from-blue-400/10` (10% opacity #60a5fa)

#### UI Element Colors
* Status Display
  - Error: `#ef4444` (red-500)
  - Success: `#22c55e` (green-500)
* Text
  - Primary Text: `#4b5563` (gray-600)
  - Secondary Text: `#9ca3af` (gray-400)
* Borders
  - Light Mode: `#d1d5db` (gray-300)
  - Dark Mode: `#4b5563` (gray-600)

#### Features List

* Dark mode toggle (common across all screens)
* Error display function (toast format)
* Animation effects (fade-in, float)
* Developer support via BuyMeCoffee
  - Fixed popup widget in bottom right of all screens
  - Link button on the download screen

### Home Screen

* Entry point of the application
* Simple yet attractive landing page design
* Concise explanation of the application's main features

#### Features List

* Logo and title display
* Application summary display
* Navigation to editor screen (CTA button)
* Decorative elements with animations

### Main Screen

* Central screen for image processing and crop settings
* Integration of image management and editing features
* Real-time preview functionality

#### Features List

* Image upload functionality (supports multiple files)
* Image list display (drawer format)
* Image reordering functionality
* Crop setting features
  - Aspect ratio presets (16:9, 16:10, 4:3, free)
  - Automatic slide detection feature (beta)
  - Manual fine adjustment (X-coordinate, Y-coordinate, width, height)
* Real-time crop preview
* PDF generation start function

### PDF Generation Progress Screen

* Visual feedback of the PDF generation process
* Real-time display of generation status

#### Features List

* Progress bar for progress display
* Generation status display
* Process cancel functionality
* Automatic transition to download screen

### PDF Download Screen

* Download management for generated PDFs
* Completion notification and file management

#### Features List

* PDF filename customization feature (modal format)
* PDF download functionality
* Download completion display
* Return to home functionality
* Developer support link (BuyMeCoffee)

3. 実装(GitHub Copilot Agent Mode)

ここからは、GitHub Copilot Agent Modeを使用して実装を進めました。なお、モデルはClaude Sonnet 3.5のみを使用しました。また、各処理を行う際には、前述のコーディング規約を添付し、「Make sure to align with the coding standards.(コーディング規約に沿うようにしてください。)」という指示を加えました。

実際の実装の流れと各ステップでやったことの概要、および、各ステップのおおまかな時間を以下に記載します。12ステップすべてを書き出すとかなりの分量になってしまったため、興味がある方はトグルを開いてお読みください。

実装の詳細な流れ(全12ステップ)

3.1 ホーム画面(1分)

「Please implement the Home page.(ホーム画面を実装してください)」という指示だけで一発成功しました。シンプルでありながら魅力的なランディングページが生成されました。

3.2 メイン画面(40分)

メイン画面では以下の機能を実装しました。

  • 画像管理用ドロワーメニュー(画像アップロード/画像並び替え/画像削除を含む)
  • アスペクト比設定
  • クロップ範囲設定/クロップイメージのリアルタイムプレビュー

画像管理用ドロワーメニューは一発で成功しましたが、アスペクト比の固定やリアルタイムプレビューのアップデート頻度の調整等で少し苦戦しました。

3.3 PDF生成進捗画面(15分)

一括クロップ・PDF化機能の実装は一発で成功しましたが、進捗状況のリアルタイム通知とプログレスバーの表示、次画面への自動遷移で少し苦戦しました。

3.4 PDFダウンロード画面(4分)

基本的な機能はすべて一発で実装できました。デフォルトのファイル名等の調整に少しだけ時間がかかりました。

3.5 クロップ範囲微調整機能(1時間)

微調整機能のUIやクロップ値と実際のクロップ範囲の同期に苦戦しました。クロップ範囲の同期に関しては手動でデバッグを行い、変更内容を指示して修正しました。

3.6 スライド自動検出機能(2時間)

スライドの自動検出機能の実装にはかなり苦戦しました。何度やっても検出されない、または、他の機能を破壊してしまったため、最終的に実装を断念しました。

3.7 テーマ切り替えトグル(30分)

大枠の実装は一発で成功しましたが、画面ロード時のフラッシュ抑制等の実装に少し苦戦しました。時間の大半は各モードでの色の調整に使用しました。

3.8 BuyMeCoffeeウィジェット(5分)

BuyMeCoffeeのウィジェットの実装と各画面への配置も一発で成功しました。この時点で当初作成した想定ディレクトリ構成と差異が出始めていたため、その修正もここで合わせて行いました。

3.9 言語選択トグル(1時間)

言語選択トグル、および、全画面の大半のメッセージの設定ファイルの実装を一発で成功しました。イテレーション時間がかなり長く、何度も「処理を続けますか?」という旨のメッセージが出力されましたが、一応一発で最後まで実装を成功しました。時間の大半はトグルで使用するアイコンの調整やモバイルでのUI調整に使いました。

3.10 モバイル専用のクロップ画面(1時間)

モバイルでのUX向上のため、新たにreact-mobile-cropperというライブラリを導入しました。モデル側に当ライブラリに関する情報がほとんど無いことに加え、類似ライブラリが多数存在していることにより、モデルが各ライブラリの情報を混同してしまっており、実装にかなり苦戦しました。最終的にドキュメントの情報を元に実装方法を細かく指示することで実装を完遂しました。

3.11 UI微調整(3時間)

各種アイコン(初期の出力ではほとんど絵文字を使用)やアニメーションの調整を実施しました。絵文字の代わりになるSVGアイコンの生成はどれも一発で成功しましたが、プログレスバーのアニメーション調整には苦戦しました。

初期の出力ではプログレスバーの斜線が横に移動するのを一定時間で繰り返すだけのアニメーションでしたが、2時間以上かけても滑らかな動きにすることができず、最終的に手動で調整することになりました(今回唯一の手動調整箇所)。

3.12 ビルドエラー修正(1時間半)

ビルドエラーの修正には苦戦しました。これまで一度もリントチェックをしていなかったこともあり、ESLintのエラーが多数出力されました。

ビルドの実行からお願いしたところ、長いイテレーションの後にビルドエラーがすべて解消されたものの、機能の大半が破壊されていることが判明しました(エラーが出ている箇所を片っ端から削除していた)。

そこで方針を変更し、ビルドエラーを1つずつ渡して修正を指示すると、ほぼすべて一発で解消できました。解消できなかった場合は変更を取り消して、改めて指示し直すことで解消できました。

GitHub Copilot Agent Modeを利用する際のTips

今回のアプリケーション実装の試行錯誤から得た知見を共有します。

1. 指示はすべて英語で行うべき

はじめ日本語でやり取りをしていたのですが、指示が無視されたり、ステップを忘れてしまいがちでした(モデル側のトークンの問題?)。コーディング規約などの追加で渡すコンテキストも含め、すべて英語でやり取りをするようにするとこのようなケースがかなり減りました。

2. なるべく小さなタスク/機能に分割して指示するべき

執筆時点では、恐らくシングルエージェントでタスクを処理している様子です(公式ブログにもマルチエージェント的な記載はありません)。大きなタスクや機能を渡してしまうと、はじめは良い感じにタスク分解ができていても、その分解したステップ自体を忘れてしまう傾向がありました。

どうしても分割しにくいタスクの場合は、はじめに実装プランをMarkdown形式で書き出させる指示をし、その後にそのプランのドキュメントを参照させるようにすると多少マシになりました。また、GitHub Copilot Chatでタスク分解を手伝ってもらい、分解されたタスクを1つずつGitHub Copilot Agent Modeへ指示していくのも結構有効でした。

3. エラーの場所や修正すべきファイルは明示すべき

執筆時点では、裏側で渡されるワークスペースに関する情報とコードベースの検索機能を用いて修正すべきファイルを特定している様子です。似たようなファイル名や変数名が多数存在する場合は誤った箇所を修正してしまったり、そもそも検索ループに陥ってしまう傾向がありました。

そのため、エラーの原因や修正すべきファイルが分かっている場合は、コンテキストとしてそのファイルの情報を初めから渡してあげた方が成功確率を高められそうです。

4. 対話は控えるべき

やり取りが続くほど挙動が不安定になる傾向がありました。3回以上続けると、現状ブラウザを確認する能力が無いにも関わらず、「UIが正しく変更されたか確認します。」「正しく修正されていないですね。全く別のアプローチを取ってみましょう。」という旨の出力を繰り返し、修正ループに陥ることがありました。

出力内容に修正点がある場合は、出力内容を一度Keepし、新たなチャットで修正内容を指示した方が指示した内容を完遂する傾向がありました。

5. 適宜レビュー・リファクタリングを実施すべき

GitHub Copilot Agent Modeには自動的にエラーの確認・修正する機能がありますが、その場しのぎの解決策が積み重なることでコードがスパゲッティ化しがちです。

GitHub Copilot Chatの方でリファクタリングしたいファイルとコーディング規約のコンテキストを渡して「How should I modify the code so that the code aligns better with the coding standards?(何を修正すれば、コーディング規約にもっと沿う形になりますか?)」と質問し、提案された内容を1つずつGitHub Copilot Agent Modeの方で指示することである程度は改善ができました。

6. コード以外のエラーを出す拡張機能はDisableするべき

「テキスト校正くん」のようなコード以外のエラーを出す拡張機能は、GitHub Copilot Agent Modeが「修正すべきエラー」と判断し、無駄な修正ループに入ってしまう傾向がありました。

感想

正直なところ、コーディング経験があまりなかったとしても、たった12時間でここまで多機能なアプリが作れてしまうことに目を見張りました。システムエンジニアとしてもっと研鑽を積まないと、あっという間に仕事を奪われてしまう側になってしまうなという危機感も感じています。
最初はただの試しに使ってみるかぐらいの軽い気持ちだったのですが、実際に使ってみると「えっ、もうできたの!?」というような驚きの連続でした。特に以下の点が印象的でした。

  • コード出力時の内部制御が素晴らしい:Clineなどでは長いコードの生成に失敗したり、中途半端な状態で出力されてしまったりすることが多いのですが、GitHub Copilot Agent Modeでは内部で上手く制御されており、そういったことはほぼ起こらないという印象です(今回の検証でも失敗したのは1度のみ)。また、コードの出力速度も驚くほど速く、「待ってる間に他のタスクをやるか」という隙間時間もほとんど発生しませんでした。
  • 追加料金不要で利用可能:エージェントはトークン数がかさみがちなため、その料金を気にせずに使用できるのは心理的にかなり大きいです。
  • アイデアの実現ハードルの低下こちらの記事でも述べられていますが、「あ、こんなアプリあったら便利かも」から「完成」までの距離が信じられないほど縮まります。むしろ「次は何を指示すればいいかな?」というような人間側の思考速度が新たなボトルネックになってしまう印象です。

今でも十分戦力になりますが、今後マルチエージェント化されたり、ブラウザを使ったデバッグができるようになったら…と考えると、もう本当に開発の概念が根本的に変わってしまうんだろうなという印象です。コーディング部分はほぼAIに任せて、人間はビジネスロジックや創造的な部分に集中する、という世界が急速に近づいていると感じました。

おわりに

今回はGitHub Copilot Agent Modeを用いたアプリケーション開発の経験を共有させていただきました。まだプレビュー版とはいえ、個人開発におけるAIアシスタントの可能性を強く実感することができました。

これからもGitHub Copilot Agent Modeには注視していきたいと考えています。みなさんもGitHub Copilot Agent Modeを用いたオススメの開発フローやTips等があればコメント欄で共有してほしいです!

ここまでお読みいただき、ありがとうございました。

Discussion

ログインするとコメントできます