[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
見出し画像

GitHub Copilot Workspace テクニカルプレビュー版を触ってみる_1_新規作成~ブレインストーム~プラン作成~コード実装~動作確認まで


はじめに

対象読者

  • 生成 AI / LLM に興味関心のある方

    • とりわけ IT エンジニアリングに知見のある方

  • GitHub Copilot Workspace に興味関心のある方

  • GitHub を使った経験はある方


GitHub Copilot Workspace とは

  • GitHub が提供する AI 駆動型の開発環境で、自然言語を用いてソフトウェア開発のプロセスを効率化することを目的とされている。

  • 開発者が記述した Issue を基に、AI が仕様書を作成し、実装計画を立案、コードを生成し、デバッグまでを自動で行うことができる。

    • ……とのことだけれど、まだデバッグの自動実行はできない。

  • 2024/11/08 現在でまだテクニカルプレビュー版であり、利用するにあたっては `Join the waitlist` から申請を出して承認が下りるのを待つ必要がある

    • 筆者は 2024/05 に申請してから承認が下りるまで 5 ヶ月半ほどかかった

Join the waitlist
  • note の `GitHubCopilotWorkspace` タグでは、実際に触ってみた記事は 2024/11/08 時点では見当たりませんでした

  • zenn では以下のような記事/スクラップがあり、Qiita では見つからず

  • ……ということで、2024/11/08 時点ではまだ使える人がかなり限られているもよう

    • dev.to とかでも見当たらない

  • GitHub Copilot とは別?

    • 別!

  • GitHub Copilot Edits とは別?

    • 別!

  • GitHub Spark とは別?

    • 別!


前置き

  • 記事作成にあたり、利用規約等からスクリーンショット等問題なさそうなことは確認済み

  • GitHub で自身が所属している organization のいずれに Copilot Workspace からのアクセス許可を与えるかという段取りは省略します

  • 現時点 2024/11/08 で GitHub Copilot Workspace は英語 UI しかありません

    • 入力言語が日本語でも問題ありません

    • しかし返ってくるのは全て英語です


最終更新日

  • 2024/11/08



触ってみる

前段の確認

  • まずメインの画面は非常に簡素で、あくまでもプレビュー版だなということがよくわかる

メインの画面
  • この画面から始めるにあたっては、`Choose a repository` または `Create new repository` を押して、既存のものを選ぶか新しく作るかどちらかから進めることになる

`Choose a repository` または `Create new repository` を押す
  • あるいは GitHub の issues 内の各 issue に、Copilot Workspace へのボタンが表示されるようになっているので、既に issue を立てている場合は、そこから進めることもできる

各 issue に、Copilot Workspace へのボタンが表示


新しくリポジトリを作成して進める

  • ひとまず今回は、新しいリポジトリを作るところからやってみる

  • ボタンを押すと、以下のような画面が表示される。Brainstorm をおこなわせる、ということで、ここに issue を書く

issue を書く
  • issue を考えてみる。シンプルに実装して動作確認できるようにするために、以下のようなものにしてみる

# what
- ユーザによって特定のテキストフィールドに入力された正規表現が、文法的に正しいかどうかを判定するための簡素なアプリケーションを作成したい

# spec
- React
  • 上記を入力して `Brainstorm` ボタンを押すと、以下のように表示される

`Brainstorm` ボタンを押した結果
  • 個別に拡大して見てみると、まず、三つのアイディアが出されている

三つのアイディア
  • 分かりやすく日本語に直すと以下の通り

    • 上から一つ目

      • ユーザーが正規表現を入力し、その構文が正しいかどうかをチェックできるシンプルなReactアプリケーションを作成 📝

      • 正規表現が有効かどうかを示すメッセージを表示 ✅

      • ユーザーがテストできるように、有効・無効な正規表現の例を提供 📚

    • 上から二つ目

      • ユーザーが正規表現とテスト文字列を入力できるReactアプリケーションを開発 📝

      • テスト文字列が正規表現にマッチするかどうかをチェックして結果を表示 🔍

      • ユーザーが正規表現とテスト文字列を保存・読み込みできる機能を実装 💾

    • 上から三つ目

      • 様々なユースケース(メールアドレス検証、電話番号検証など)に対応する一般的な正規表現のライブラリを作成 📚

      • ユーザーがこれらの正規表現を閲覧・コピーできるReactアプリケーションを開発 🔍

      • ライブラリ内の各正規表現に対する説明と例を提供 📝

  • つまりは、並べられた三つのアイディアは、重なり合うところがありつつ、微妙に内容が異なっているので、いずれかを採用するか、あるいは各項目の内容を選定・統合してからタスク化するという流れになる

  • ということで、ひとまず一番上のものをタスク化してみるべく `Add a task` ボタンを押すと、以下のように左サイドバー内の `Ideas from brainstorming` に `Regex validator app` が追加された

`Regex validator app` が追加
  • また、先ほど出された三つのアイディアの下の方に、`Suggested questions` というものも生成されているのが見て取れる

`Suggested questions`
  • これも日本語に直すと、以下の通り

    • ユーザーインターフェースはどのようにデザインするべきか?

    • 正規表現のバリデーションに役立つライブラリやツールにはどのようなものがあるか?

    • エラーメッセージをユーザーにどのように表示するべきか?

    • 正規表現のバリデーションにおいて考慮すべきエッジケースにはどのようなものがあるか?

    • 正規表現バリデーターアプリの機能向上のためのアイデア

    • Reactの状態管理について学ぶ

  • では、具体的に一番目の `ユーザーインターフェースはどのようにデザインするべきか?` を選択してみると、また別の Brainstorm の結果として三つのアイディアが表示された

    • ここで、Brainstorm が別タブになればよいのでは?🤔 とは思った

UI についての三つのアイディア
  • UI についての三つのアイディアを日本語にすると以下の通り

    • 上から一つ目

      • クリーンでミニマリスティックなデザインのシングルページアプリケーションを作成 🎨

      • ユーザーが正規表現を入力できるテキスト入力フィールドを配置 📝

      • バリデーションプロセスを開始する「検証」ボタンを追加 ✅

      • 入力フィールドの下に、正規表現が有効かどうかを示すメッセージを表示 📢

      • ユーザーがテストできるように、いくつかの正規表現の例を入力フィールドの下に提供 📚

    • 上から二つ目

      • モダンで視覚的に魅力的なデザインのシングルページアプリケーションを作成 🎨

      • ユーザーが正規表現を入力できるテキスト入力フィールドを配置 📝

      • バリデーションプロセスを開始する「検証」ボタンを追加 ✅

      • 入力フィールドの下に、正規表現が有効かどうかを示すメッセージを表示 📢

      • ユーザーがテストできるように、いくつかの正規表現の例を入力フィールドの下に提供 📚

      • 正規表現の書き方に関する情報を提供するツールチップまたはヘルプアイコンを入力フィールドの横に追加 ℹ️

      • ユーザーの過去の入力とバリデーション結果を表示する履歴セクションを含める 🕒

    • 上から三つ目

      • プロフェッショナルで機能が豊富なデザインのシングルページアプリケーションを作成 🎨

      • ユーザーが正規表現を入力できるテキスト入力フィールドを配置 📝

      • バリデーションプロセスを開始する「検証」ボタンを追加 ✅

      • 入力フィールドの下に、正規表現が有効かどうかを示すメッセージを表示 📢

      • ユーザーがテストできるように、いくつかの正規表現の例を入力フィールドの下に提供 📚

      • 正規表現の書き方に関する情報を提供するツールチップまたはヘルプアイコンを入力フィールドの横に追加 ℹ️

      • ユーザーの過去の入力とバリデーション結果を表示する履歴セクションを含める 🕒

      • 将来使用するために正規表現を保存・読み込みできる機能を追加 💾

      • ユーザーがサンプルテキストに対して正規表現を記述・テストできるセクションを含める 🧪

  • 見ていて分かる通り、下へ行けば行くほど複雑な要件になっているので、今回も、一番上のものを選ぶことにする

  • すると、左サイドバーの `Ideas from brainstorming` に `Simple and clean interface` が追加された

`Ideas from brainstorming` に `Simple and clean interface` が追加
  • そしてまた `Suggested questions` を確認すると、別の内容が表示されている

`Suggested questions` を確認すると、別の内容が表示
  • 日本語にすると以下の通り

    • Reactで正規表現を検証するために使用できるライブラリにはどのようなものがありますか?

    • 不正な正規表現のエラーをどのように適切に処理すべきですか?

    • 正規表現の保存と読み込み機能を実装すべきでしょうか?

    • 正規表現バリデーターアプリのテストにおけるベストプラクティスは何ですか?

    • ユーザー体験を向上させるためのその他のアイデア

    • Reactの状態管理について学ぶ

  • この中で、最低限の要件として固めておきたいものとしては `Reactで正規表現を検証するために使用できるライブラリにはどのようなものがありますか?` になるので、こちらも押すと、また別の Brainstorm の結果として三つのアイディアを出してくれます

正規表現ライブラリの三つのアイディア
  • 日本語にすると以下の通り

    • regexpp

      • JavaScriptの正規表現パーサーです 📜

      • 正規表現の構文を検証するために使用できます ✅

      • 不正な正規表現に対して詳細なエラーメッセージを提供します 🛠️

    • xregexp

      • JavaScriptの拡張正規表現ライブラリです 📚

      • 正規表現に追加機能と構文を提供します ✨

      • Reactアプリケーションで正規表現の検証や操作に使用できます 🛠️

    • re2

      • 高速で安全な正規表現ライブラリです 🚀

      • 大規模で複雑な正規表現を効率的に処理できるように設計されています 💪

      • Reactアプリケーションで正規表現の検証に使用できます 🛠️

  • `re2` は Google が出している正規表現ライブラリで、メンテナに対する信頼感はまあまああるので、今回はこれを選ぶことにする

    • ……ツッコミを入れたくなった方、後ほどまでお待ちください……

  • `re2` が左サイドバーの `Ideas from brainstorming` に追加された

`re2` が左サイドバーの `Ideas from brainstorming` に追加
  • そしてまた `Suggested questions` を見てみると、

    • `re2` をどのように React に組み込めばよいか?

    • 正規表現におけるエッジケース問題は?

  • など、言われてみたら「あー、そういやそういうのも考慮しないといけないよね」というのが出てくるので、このあたりも追加で対応していく

さらなる Suggested questions
  • このようにして、この段階では `Suggested questions` をたくさんおこない、実行すべきタスクを増やし、ヌケモレが起こらないようにしていく作業を重ねることになる

  • ということで、全部を記事にしていくとキリがないのでちょっと省略しつつ、まずは `Ideas from brainstorming` に以下の内容を放り込んでみた

Ideas from brainstorming

Brainstorm を終えてプラン作成へ

  • Brainstorm を終えてタスク化が無事にできたと判断されたら、左サイドバーの `Ideas from brainstorming` の下にある `Generate plan` ボタンを押す

`Ideas from brainstorming` の下にある `Generate plan` ボタン
  • たまーに、生成中のまま固まることがあるのだけれど、その場合はエラーを吐いて `Retry` ボタンが表示されるまで待つ……

プラン生成中
  • プランが生成されると、作成されるべきファイル/ディレクトリの一覧が表示された上で、それぞれのファイルにおいてどのような実装をするかという概要があわせて表示される

作成されるべきファイル/ディレクトリの一覧
  • それぞれの項目に対して、修正の手を入れたり、削除したり、あるいは項目を手動で追加したり……といった細かい調整も可能ではある

    • が、AI 駆動開発として本格的に次世代の開発パラダイムへ移っていく準備段階/訓練としては、ここでの修正を人間がおこなうのは悪手で、むしろ前段階に戻って Brainstorm → タスク追加 → Plan 生成をやり直した方が良いと思われます

細かい調整も可能
  • 今回はこのファイルは含めない、などチェックを外すことも可能

今回はこのファイルは含めない、などチェックを外すことも可能


コードの実装へ

  • それではプランは原案通りとした上で、コードの実装へ進める

  • 手直しはしない、とはいえ、`README.md` のところに `日本語で出力` と書いておかないと、全て英語で出力されてしまうので、それだけは追記した上で、最後に `Implement selected files` ボタンを押す

`Implement selected files` ボタンを押す
  • そして以下のように出力された

コードが出力された
  • 正直、あれだけ UI について色々とタスクに追加したのは何の効果があったの……? という感じもするようなコードが、以下の通りである

  • src/App.js

import React, { useState } from 'react';
import RE2 from 're2';

function App() {
  const [regex, setRegex] = useState('');
  const [isValid, setIsValid] = useState(null);

  const validateRegex = () => {
    try {
      new RE2(regex);
      setIsValid(true);
    } catch (e) {
      setIsValid(false);
    }
  };

  return (
    <div className="App">
      <h1>Regex Validator</h1>
      <input
        type="text"
        value={regex}
         => setRegex(e.target.value)}
        placeholder="Enter your regex here"
      />
      <button 
      {isValid !== null && (
        <p>{isValid ? 'Valid regex' : 'Invalid regex'}</p>
      )}
    </div>
  );
}

export default App;
  • public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Regex Validator App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
  • src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
  • src/App.css

.App {
  font-family: Arial, sans-serif;
  text-align: center;
  margin-top: 50px;
}

input {
  padding: 10px;
  font-size: 16px;
  width: 300px;
  margin-bottom: 10px;
}

button {
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
}

p {
  font-size: 18px;
  font-weight: bold;
}
  • README.md

# Regex Validator App

This is a simple React application that allows users to input a regular expression and checks if it is syntactically correct. The application displays a message indicating whether the regular expression is valid or not. It also provides examples of valid and invalid regular expressions for users to test.

## How to Run the Application

1. Clone the repository:
   ```
   git clone https://github.com/githubnext/workspace-blank.git
   ```
2. Navigate to the project directory:
   ```
   cd workspace-blank
   ```
3. Install the dependencies:
   ```
   npm install
   ```
4. Start the development server:
   ```
   npm start
   ```
5. Open your browser and go to `http://localhost:3000` to see the application.

## Examples of Valid and Invalid Regular Expressions

Here are some examples of valid and invalid regular expressions that you can test with the application:

### Valid Regular Expressions
- `^[a-zA-Z0-9]+$`
- `\d{3}-\d{2}-\d{4}`
- `\b\w+\b`
- `\s+`
- `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$`

### Invalid Regular Expressions
- `[a-z`
- `\d{3}-\d{2}-\d{4`
- `\b\w+\b\`
- `\s+*`
- `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,`

## 日本語で出力

このアプリケーションは、ユーザが正規表現を入力し、その正規表現が文法的に正しいかどうかを判定するためのシンプルなReactアプリケーションです。アプリケーションは、正規表現が有効かどうかを示すメッセージを表示します。また、ユーザがテストできる有効な正規表現と無効な正規表現の例も提供します。

### アプリケーションの実行方法

1. リポジトリをクローンします:
   ```
   git clone https://github.com/githubnext/workspace-blank.git
   ```
2. プロジェクトディレクトリに移動します:
   ```
   cd workspace-blank
   ```
3. 依存関係をインストールします:
   ```
   npm install
   ```
4. 開発サーバーを起動します:
   ```
   npm start
   ```
5. ブラウザを開き、`http://localhost:3000`にアクセスしてアプリケーションを確認します。

### 有効な正規表現の例
- `^[a-zA-Z0-9]+$`
- `\d{3}-\d{2}-\d{4}`
- `\b\w+\b`
- `\s+`
- `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$`

### 無効な正規表現の例
- `[a-z`
- `\d{3}-\d{2}-\d{4`
- `\b\w+\b\`
- `\s+*`
- `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,`
  • まあ、このモデルの性能の低さが今の Copilot Workspace の頭打ちな点かなという印象を受けてしまうけれど、ひとまず動作検証へ向けてやってみよう

  • なお、画面右上のボタン群の中に `Create repository` ボタンがあるが、これは既にリポジトリが存在している場合は `Create pull request` になり、ここからプルリクを出せるようになっている

    • プルリクの description も `Generate description` で自動生成できるので、そこが便利

画面右上のボタン群
  • ひとまずこのボタン群の中から、動作確認をするためのものを押す。分かりづらいけれど、以下画像の `Open codespace` ボタンを押すと、GitHub 環境に紐付いたブラウザ IDE が起動する

Open codespace
  • 押したら勝手に立ち上がるわけではなくて、右下に「準備ができたよ!」という通知が表示されるので再度 `Open codespace` ボタンを押す

右下の Open codespace ボタン
  • オクトキャットが出迎えてくれる

オクトキャットのお出迎え
  • Codespace 起動!

Codespace 起動
  • README に起動方法が書いてあるので、信じて実行してみる。`npm install` ポチッと!

README の通りにターミナルで npm install
  • エラーが出た。それはそう。だって `package.json` 作ってくれていなかったからね

package.json がないよ! エラー
  • ということで GitHub Copilot Workspace へ戻り、画面下の方にある `Revise` に以下内容を打ち込んで修正させる

GitHub Codespace 環境で `npm install` を実行したら以下エラーが起こったので対処してください。

`npm error enoent Could not read package.json: Error: ENOENT: no such file or directory, open '/workspaces/workspace-blank/package.json'`

Revise への指示
Revise
  • すると Plan に `package.json` が追加された

    • あえてスルーしてエラーを踏んだけれど、最初から作成してくれよと思わずにはいられない

`package.json` が追加
  • `package.json` にチェックを入れると、左サイドバー下端の `Update selected files` ボタンが enabled 状態になるので、これを押す

`Update selected files` ボタン
  • そして生成された `package.json` のコードが以下

{
  "name": "regex-validator-app",
  "version": "1.0.0",
  "description": "A simple React application to validate regular expressions",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "re2": "^1.15.9"
  },
  "devDependencies": {
    "react-scripts": "4.0.3"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
  • ではこれで再度 `Open codespace` ボタンを押して Codespace を開き `npm install` を実行すると、今度は成功するものの、次の `npm start` でコケる……

Starting the development server...

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:79:19)
    at Object.createHash (node:crypto:139:10)
    at module.exports (/workspaces/workspace-blank/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:471:10)
    at /workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:503:5
    at /workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:358:12
    at /workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at iterateNormalLoaders (/workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
/workspaces/workspace-blank/node_modules/react-scripts/scripts/start.js:19
  throw err;
  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:79:19)
    at Object.createHash (node:crypto:139:10)
    at module.exports (/workspaces/workspace-blank/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:417:16)
    at /workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:452:10
    at /workspaces/workspace-blank/node_modules/webpack/lib/NormalModule.js:323:13
    at /workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:367:11
    at /workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:233:18
    at context.callback (/workspaces/workspace-blank/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at /workspaces/workspace-blank/node_modules/babel-loader/lib/index.js:59:103 {
  opensslErrorStack: [
    'error:03000086:digital envelope routines::initialization error',
    'error:0308010C:digital envelope routines::unsupported'
  ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
  • これはねー……


いったん信念を捨て手で直して動作確認

  • はい、このあたりで記事も長くなってきた、ということで、とりあえずアプリケーションの起動までは持っていきたいな、と思いまして、原因特定などこちらでして Codespace 上でサクッと修正してしまおうと思います……

  • こちらは Node.js というか OpenSSL のバージョンが最近のものだとセキュリティ強化されていまして、スタートスクリプトに `NODE_OPTIONS='--openssl-legacy-provider'` を追記しましょうということになります。ということで `package.json` の中身を書き換えて……

  "scripts": {
    "start": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts start",
    "build": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts build",
    "test": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts test",
    "eject": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts eject"
  }
  • で、あらためて `npm start` を押すと、アプリケーションの起動には成功、ブラウザで別タブが立ち上がり……

  • 驚きの白さ!

真っ白!
  • コンソール確認すると、エラー出てますね、はい

エラーがたくさん
  • 何でって? だって `re2` ってブラウザ環境で動作させるライブラリじゃないんですもの……


ΩΩΩ<な、なんだってー!?

MMR


  • ……はい、先ほど書いていた、以下の箇所ですね。ツッコミを入れたくなった方につきましては、ここまで大変お待たせいたしました

`re2` を選んだのが伏線
  • 「どうして失敗するって分かっていて `re2` にしたの?」と問われたら、だって、途中どこかで GitHub Copilot Workspace が指摘して修正してくれるかなーという期待をしていたのですよ……しかし期待は裏切られた。うーん。モデルに Claude が選べたら結果は変わっていたのかもしれない

  • ということで Claude 3.5 Sonnet に以下を書き直させてみた

  • App.js

import React, { useState, useCallback } from 'react';
import './App.css';

function App() {
  const [regex, setRegex] = useState('');
  const [testString, setTestString] = useState('');
  const [isValid, setIsValid] = useState(null);
  const [matches, setMatches] = useState(null);

  const validateRegex = useCallback(() => {
    if (!regex) {
      setIsValid(null);
      setMatches(null);
      return;
    }

    try {
      new RegExp(regex);
      setIsValid(true);
      
      if (testString) {
        const re = new RegExp(regex);
        const matched = re.test(testString);
        setMatches(matched);
      }
    } catch (e) {
      setIsValid(false);
      setMatches(null);
    }
  }, [regex, testString]);

  return (
    <div className="App">
      <h1>正規表現バリデータ</h1>
      
      <div className="input-group">
        <label className="input-label">正規表現:</label>
        <input
          type="text"
          value={regex}
           => setRegex(e.target.value)}
          
          placeholder="正規表現を入力(例: ^[a-z]+$)"
        />
      </div>

      <div className="input-group">
        <label className="input-label">テスト文字列:</label>
        <input
          type="text"
          value={testString}
           => setTestString(e.target.value)}
          
          placeholder="テストする文字列を入力"
        />
      </div>

      <button 

      {isValid !== null && (
        <div className={`result ${isValid ? 'valid' : 'invalid'}`}>
          {isValid ? '✅ 正規表現は有効です' : '❌ 正規表現が無効です'}
        </div>
      )}

      {isValid && matches !== null && (
        <div className={`match-result ${matches ? 'matched' : 'not-matched'}`}>
          {matches ? '✅ テスト文字列がマッチしました' : '⚠️ テスト文字列はマッチしませんでした'}
        </div>
      )}
    </div>
  );
}

export default App;
  • package.json

{
  "name": "regex-validator-app",
  "version": "1.0.0",
  "description": "A simple React application to validate regular expressions",
  "main": "index.js",
  "scripts": {
    "start": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts start",
    "build": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts build",
    "test": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts test",
    "eject": "NODE_OPTIONS='--openssl-legacy-provider' react-scripts eject"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "react-scripts": "4.0.3"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
  • App.css

.App {
  font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  max-width: 800px;
  margin: 2rem auto;
  padding: 2rem;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

h1 {
  color: #2d3748;
  margin-bottom: 2rem;
  font-size: 2.25rem;
  font-weight: 700;
  text-align: center;
}

.input-group {
  margin-bottom: 1.5rem;
}

.input-label {
  display: block;
  margin-bottom: 0.5rem;
  color: #4a5568;
  font-weight: 600;
  font-size: 0.95rem;
}

input {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 2px solid #e2e8f0;
  border-radius: 8px;
  font-size: 1rem;
  transition: all 0.2s ease;
  background: #f8fafc;
}

input:focus {
  outline: none;
  border-color: #4299e1;
  box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.15);
}

input::placeholder {
  color: #a0aec0;
}

button {
  width: 100%;
  padding: 0.75rem 1.5rem;
  background: #4299e1;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-top: 1rem;
}

button:hover {
  background: #3182ce;
  transform: translateY(-1px);
}

button:active {
  transform: translateY(0);
}

.result {
  margin-top: 1.5rem;
  padding: 1rem;
  border-radius: 8px;
  font-weight: 600;
  text-align: center;
}

.result.valid {
  background: #c6f6d5;
  color: #276749;
}

.result.invalid {
  background: #fed7d7;
  color: #9b2c2c;
}

.match-result {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 8px;
  font-weight: 600;
  text-align: center;
}

.match-result.matched {
  background: #c6f6d5;
  color: #276749;
}

.match-result.not-matched {
  background: #feebc8;
  color: #9c4221;
}

@media (max-width: 640px) {
  .App {
    margin: 1rem;
    padding: 1rem;
  }

  h1 {
    font-size: 1.75rem;
  }
}

/* アニメーション効果 */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.result, .match-result {
  animation: fadeIn 0.3s ease;
}
  • Codespace 上で直接書き換えてから `npm start` で動作確認すると……

  • 良い感じに表示された!

表示に成功
  • メールアドレスでの動作検証をしてみましょう

    • 正規表現

      • ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

      • test@example.com

      • user.name+tag@example.co.jp

      • invalid.email@.com

      • @example.com

OK の例
NG の例
そもそも正規表現が無効な場合
  • ということで、上記の通り、正規表現チェックの動作は OK でした!


おわりに

結論

  • 新時代の開発体験を味わえるのは確か!

  • ……だが、クセ強というか、実用レベルに持っていくまでにかなりの工夫が必要そうで、現時点だとその労力が見合うかどうか!?

  • もしかしたら、既存リポジトリの改修なら話が違ってくるかもしれない? ということで、次回の続編記事は、そこへ踏み込んでみる予定

  • Claude 3.5 Sonnet 優秀!


雑感

  • GitHub Copilot Workspace の中のモデルがサボり過ぎというか、何というか……

  • とりわけ、たくさんブレインストーミングをしてタスクを追加した割に、プラン生成でほとんど反映されないというのが何なんだといいますか

  • 一週間前、この記事書くより前に既存リポジトリで試していた時は、もうちょっと賢かったんですが、うーむ🤔

  • Claude 3.5 Sonnet 優秀!


自己紹介
  • 野口 啓之 / Hiroyuki Noguchi

  • 株式会社 きみより 代表

  • LLM も使いつつ 10 年超の CTO / CIO 経験をもとに DX 推進のための顧問などなどやっております


いいなと思ったら応援しよう!