今話題のClineを使って'じゃんけん'してみた

## Clineとは

Clineは、フロントエンドの開発を支援するツールです。

https://github.com/cline/cline

> Claude 3.5 Sonnetのエージェントコーディング機能により、Clineは複雑なソフトウェア開発タスクをステップバイステップで処理することができます。ファイルの作成と編集、大規模なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行（許可を与えた後）などが可能なツールを使って、コード補完や技術サポート以上の方法であなたを支援することができます。クラインはモデル・コンテキスト・プロトコル（MCP）を使って新しいツールを作成し、自身の能力を拡張することもできる。自律AIスクリプトは従来、サンドボックス環境で実行されてきたが、この拡張機能は、ファイル変更とターミナルコマンドをすべて人間が承認するGUIを提供し、エージェント型AIの可能性を探るための安全でアクセスしやすい方法を提供する。

### 要約

https://zenn.dev/shunsuke_stack/articles/eb9cd6c167b835

こちらの記事で紹介しているAiderの上互換ではないかと思っています。

## 使用するプロジェクト

https://github.com/nakajima-sh-cnctor/vue-fizz-buzz-cursor

https://zenn.dev/shunsuke_stack/articles/277e75e9b3df27

## プロンプトの構築

- テストコードの作成
- コンポーネントの作成
- App.vueに追加
- テスト実行
- 動作確認

### テストコード生成

> src/components/__tests__配下にRockPaperScissors.spec.tsを作成してください。
> vitestを使用してテストコードを作成してください。
> 「ぐー」「ちょき」「ぱー」の3つのボタンを押したときに、それぞれの結果が表示されることを確認してください。

**下記実行結果**
惜しい！ここまでできて何故かvitestをimportできないという!

```ts:RockPaperScissors.spec.ts
import { mount } from '@vue/test-utils'
import RockPaperScissors from '../RockPaperScissors.vue' // Assuming the component is named RockPaperScissors.vue

describe('RockPaperScissors Component', () => {
  it('should display the correct result when "ぐー" button is clicked', async () => {
    const wrapper = mount(RockPaperScissors)
    await wrapper.find('button.gu').trigger('click')
    expect(wrapper.text()).toContain('ぐー')
  })

  it('should display the correct result when "ちょき" button is clicked', async () => {
    const wrapper = mount(RockPaperScissors)
    await wrapper.find('button.choki').trigger('click')
    expect(wrapper.text()).toContain('ちょき')
  })

  it('should display the correct result when "ぱー" button is clicked', async () => {
    const wrapper = mount(RockPaperScissors)
    await wrapper.find('button.pa').trigger('click')
    expect(wrapper.text()).toContain('ぱー')
  })
})
```

> vitestから必要なものをインポートしてください

### 驚異的な知能

レスポンスが英語だったので日本語で対応するかを確認しました
> 日本語で対応することはできますか？

![b7394a213a273b-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822984/fd599692-c228-7ba6-2039-6ed98acbafb9.png)



日本語で対応できるとかいう次元じゃなかった。
次のタスクを理解していることに驚きを隠せない

### テストを修正

テストを確認した感じ、詰めが甘いので修正します
クリックされたボタンの結果を表示するが、対戦結果が表示されていないので修正します

> テストコードを修正してください
> ボタンが押されたら対戦が擬似的に行われてその結果を出力するようにしてください


### コンポーネントの作成

> RockPaperScissors.vueを作成してください
> RockPaperScissors.spec.tsを仕様として作成してください
> setup lang="ts"で作成してください

**下記実行結果**

```vue:RockPaperScissors.vue
<template>
  <div>
    <button class="gu" @click="play('ぐー')">ぐー</button>
    <button class="choki" @click="play('ちょき')">ちょき</button>
    <button class="pa" @click="play('ぱー')">ぱー</button>
    <p>{{ result }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const result = ref('')

function play(choice: string) {
  const options = ['ぐー', 'ちょき', 'ぱー']
  const computerChoice = options[Math.floor(Math.random() * options.length)]
  if (choice === computerChoice) {
    result.value = '引き分け'
  } else if (
    (choice === 'ぐー' && computerChoice === 'ちょき') ||
    (choice === 'ちょき' && computerChoice === 'ぱー') ||
    (choice === 'ぱー' && computerChoice === 'ぐー')
  ) {
    result.value = `${computerChoice}に勝ちました`
  } else {
    result.value = `${computerChoice}に負けました`
  }
}
</script>

<style scoped>
button {
  margin: 5px;
}
</style>

```

### テストの実行

Clineに実行させても良いのですがVscodeで開いているテストファイルの左側のアイコンから実行できるのでそれで確認します
結果は全て緑なので正常に動いているみたいです
※ここまで描画確認一度もしていません。

![b7394a213a273b-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822984/01d4e095-c352-ca21-44e4-c0ae82036cda.png)


Clineで実装するとこんな感じになります

> テストを実行してください

![b7394a213a273b-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822984/98878c2a-fb47-0441-9de2-00a222ba8aa3.png)


**Run Cimmand**を押すと`npx vitest run`が実行されます

結果も特段問題なさそうです

```bash
 RUN  v2.1.8 /Users/nakajijmashunsuke/Documents/Workspace/vue-fizz-buzz-cursor

 ✓ src/components/__tests__/FizzBuzz.spec.ts (3)
 ✓ src/components/__tests__/HelloWorld.spec.ts (1)
 ✓ src/components/__tests__/RockPaperScissors.spec.ts (3)

 Test Files  3 passed (3)
      Tests  7 passed (7)
   Start at  00:00:08
   Duration  680ms (transform 198ms, setup 0ms, collect 333ms, tests 44ms, environment 977ms, prepare 125ms)
```

### App.vueに追加して描画確認

> App.vueにコンポーネントを追加してください

**下記実行結果**
既存のソースに追加する形で修正を入れてくれています

```vue:App.vue
<template>
  <v-app>
    <v-main>
      <v-container>
        <FizzBuzz :numbers="[1, 2, 3, 4, 5, 15, 30]" />
        <FizzBuzz :numbers="[6, 7, 8, 9, 10, 11, 12]" />
        <RockPaperScissors />
      </v-container>
    </v-main>
  </v-app>
</template>

<script setup lang="ts">
import FizzBuzz from './components/FizzBuzz.vue'
import RockPaperScissors from './components/RockPaperScissors.vue'
</script>

<style>
@import 'vuetify/styles';
</style>

```

vueの起動もClineで実行してくれています。
詳細は省きますが、テストの実行と同じです。


**実行結果**
ボタンのデザインがフォーマットされていて簡素ですが、「ぐー」「ちょき」「ぱー」のテキストをクリックすれば下に結果が表示されます

![b7394a213a273b-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822984/2732f467-88e9-b04b-4969-40426ecfdbf2.png)


## まとめ
Clineの使用感は”Aider”に似ています
Vscodeの拡張機能としてGUIから操作可能なので簡単操作でコードを生成できます。
Cursorとの違いは、Cursorはコーディングをアシストしてくれる機能に長けているのに対してClineはプロンプトから自動生成を行い、コマンドラインの実装などありとあらゆる工程を自動化できます
実際に今回の実装にあたり私自身は一行もコードを書いていません。

### 難点
これは私の使い方の問題かもしれませんが、同一タスク（チャット）で繰り返しプロンプトを投げると、そのタスクの結果がおかしくなってしまうことがあります。
そのため、タスクを切り分けてプロンプトを投げることを推奨します

## 一緒に働く仲間を募集しています！
株式会社コネクター・ジャパンでは一緒に働いてくれる仲間を募集しています！

事業拡大に伴い、エンジニアを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/cnctor/about
▼代表メッセージ
https://cnctor.jp/10years-anniversary/
▼応募はこちら
https://www.wantedly.com/companies/cnctor/projects