Cursor_ComposerってChat機能と何が違うの？

## はじめに

私はCursorの利用を初めてから1年が経つのですが、
Chat機能に満足していたため、Composer機能は特に使用していませんでした。
Web上で調べてみてもどのような違いがあるのかわからないため、
実際に使用して試してみることにしました！

## Composerとは

Cursorの新機能で複数のファイルを編集することが可能です。
ただし、Chatでも複数ファイルの提案はしてくれるため今回は具体的に試してみました。

## 1. ChatとComposerにシンプルな命令

まずはChatとComposer両方に同じシンプルな命令をしてみました。

```
質問内容1：emailとパスワードを入力するログイン処理を追加して下さい
```

### Chatの回答

回答は間違ってはいないけど、
console.logで結果を表示するだけの回答が返ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/feada4f1-ed92-476c-894d-e873eaf35c4c.png)


<details><summary>Chat回答詳細(クリックで開く)</summary>

```typescript


// 以下のコードは、Homeコンポーネントにメールとパスワードを入力する
// ログインフォームを追加する方法を示しています。
// useStateを使用して入力値を管理し、handleSubmit関数でフォームの送信を処理します。


import React, { useState } from 'react';

const Home = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    // ログイン処理をここに追加
    console.log('Email:', email);
    console.log('Password:', password);
  };

  return (
    <div>
      <h1>Home</h1>
      <p>welcome to my home page</p>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="email">Email:</label>
          <input
            type="email"
            id="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div>
          <label htmlFor="password">Password:</label>
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <button type="submit">Login</button>
      </form>
    </div>
  );
}

export default Home;

```

</details>


### Composerの回答

Chatとはあまり変わらずconsole.logを出力するだけの回答です。
ただし、lint errorのチェックや、今後必要な処理の解説をしてくれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/11134ee3-d05c-49f0-56f6-82533140349c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/f7efe8b3-b14a-653f-f682-c556c6e0cda5.png)

<details><summary>Chat回答詳細(クリックで開く)</summary>

```typescript


// ログインフォームを作成し、入力されたemailとパスワードを処理する機能を追加します。
// まず、必要なコンポーネントとスタイルを確認しましょう。

// では、ログインフォームを実装していきます。src/pages/home/index.tsxにログインフォームを追加し、
// 状態管理のためにReactのuseStateを使用します。

// 以下の機能を実装しました：
// メールアドレスとパスワードの入力フィールド
// フォームの状態管理（useState）
// フォーム送信処理の基本実装
// モダンなUIデザイン（Tailwind CSSを使用）
// 主な特徴：
// 入力フィールドにはバリデーション（required属性）を設定
// パスワードフィールドは非表示入力
// レスポンシブデザイン
// フォーカス時のスタイリング
// ホバー効果のあるボタン
// 現在は、フォーム送信時にコンソールにログを出力するだけの実装になっています。
// 実際のログイン処理（APIとの連携など）が必要な場合は、
// handleSubmit関数内に適切な処理を追加する必要があります。

// 必要に応じて以下のような機能を追加することができます：
// ログイン状態の管理（例：Context APIやReduxの使用）
// エラーメッセージの表示
// ローディング状態の表示
// パスワードリセット機能
// 「パスワードを記憶する」機能
// これらの追加機能が必要な場合は、お知らせください。

import { useState } from "react"

const Home = () => {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    // TODO: ここにログイン処理を実装
    console.log("Login attempt:", { email, password })
  }

  return (
    <div className="min-h-screen flex items-center justify-center bg-gray-100">
      <div className="bg-white p-8 rounded-lg shadow-md w-96">
        <h1 className="text-2xl font-bold mb-6 text-center">ログイン</h1>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label htmlFor="email" className="block text-sm font-medium text-gray-700">
              メールアドレス
            </label>
            <input
              type="email"
              id="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
              required
            />
          </div>
          <div>
            <label htmlFor="password" className="block text-sm font-medium text-gray-700">
              パスワード
            </label>
            <input
              type="password"
              id="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
              required
            />
          </div>
          <button
            type="submit"
            className="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
          >
            ログイン
          </button>
        </form>
      </div>
    </div>
  )
}

export default Home


```

</details>


## 2. ChatとComposerに詳細な命令

```
emailとパスワードを入力するログイン処理を追加して下さい。
その際、Contextも一緒に作成して下さい。
```

### Chatの回答

複数ファイルに分けて回答してくれます。
・homeファイルの追加修正
・AuthContextの作成
・_app.tsxの修正

ただし、反映に関しては各提案のApplyを押下する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/26eb3b96-953c-eb12-c9c9-5cce37be0e05.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/965cb6e3-980a-3b4d-0446-f82bd92caeb2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/ea5cd3bd-d865-9088-4b3b-e1369dc67d4f.png)

### Composerの回答

Chatの回答にプラスでログインフォームを追加してくれています。
・homeファイルの追加修正
・AuthContextの作成
・_app.tsxの修正
・LoginFormコンポーネント // new

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/9c23700e-8497-fdcf-a37f-f6cc2735a762.png)

機能の多さに関しては気まぐれと考えることもできますが、
Composerの方が命令を実行するために多くの提案をしてくれそうです。
また、一番最後に全ての変更を適用するための「Accept all」が追加されています。
（個別にApplyすることも可能）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/9e5c4f39-4100-1974-fc49-1510e2639448.png)

## 3. ChatとComposerに追加命令

```
ログインフォームに関して、
パスワードリセットへのリンクとパスワードリセットのページを作って
```

### Chatの回答

しっかりパスワードリセットページの作成と、
LoginFormへのリンク追加をしてくれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/204c3c48-d98d-e887-21c1-686d8e7146bb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425282/6e5e4ab8-81c7-ec21-87d7-0e0857eed1a5.png)

### Composerの回答

Chatと同様に下記を追加してくれています。
・パスワードリセットページ作成
・LoginFormへのリンク追加
・AuthContextにパスワードリセット機能追加 // new!

また、下記のようにしっかりと順序説明をしてくれるところがポイント高いですね！

```
以上で、パスワードリセット機能の実装が完了しました。実装した内容は以下の通りです：
/reset-password ページを作成し、メールアドレスを入力してパスワードリセットを要求できるフォームを実装
AuthContext にパスワードリセット機能を追加
ログインフォームに「パスワードをお忘れですか？」のリンクを追加
実際の認証システムと連携する場合は、AuthContext の resetPassword 関数内で実際のAPIを呼び出す必要があります。現在はモック実装となっています。
これで、ユーザーは以下の手順でパスワードリセットを行うことができます：
ログインページで「パスワードをお忘れですか？」リンクをクリック
パスワードリセットページでメールアドレスを入力
リセット用のメールが送信される（実際のAPI実装が必要）
```

## まとめ

ComposerはChat機能に比べて下記メリットがあると感じました。
・段階的に実装を考えて説明してくれる
・上記のことからChat機能にプラスαの実装をしてくれることが多い
・他のファイル全部を変更する操作が楽

ただ、普段の業務のようにファイル数が多い実装で試した経験は少ないため、
業務中に利用しながらChatとComposerの使い分けを学んでいきたいと思います。
皆さんのおすすめのComposerの活用方法があればコメントいただけると嬉しいです。


今までのカーソル記事まとめ
[Cursor_AIとのペアプログラミング(Next.js中心)](https://qiita.com/Matsu_L/items/7cbc7c480571c5ecb12a)
[Cursor_Proプランを半年以上使い続けた私の普段の使い方(Next.js中心)](https://qiita.com/Matsu_L/items/43876b45da42fe0dca68)
[Cursor_Copilot++の使用方法（Next.js中心）](https://qiita.com/Matsu_L/items/efe42059f7a4c49f00b8)
[Cursor_テキストエディタとしての活用](https://qiita.com/Matsu_L/items/1798db3c81815d6b82c6)
[ChatGPT_Structured Outputsの使い方(Javascript)](https://qiita.com/Matsu_L/items/1918bbd520e34d784c60)