Copilotを活用して、30分でVSCode用の爆速音声議事録拡張機能を作成

# はじめに

こんにちは！Gakken LEAPでフロントエンドエンジニアをしているkouです。

最近、Shikaku PassのUX改善のために週二回の会議を行い、その成果を議事録として整理しています。

**「議事録、面倒すぎない？」**

毎日VSCodeを使って開発しているので、ショートカットキーを使い、オフラインでも簡単に音声で議事録を記録できるVSCode拡張機能があれば便利ではないでしょうか？

## VSCode爆速音声議事録拡張機能拡張を作ってみた

ネットで調べてみると、VSCodeの拡張機能開発に関するマイクロソフト公式チュートリアル「VSCode Extension Guide」が見つかりました。

https://code.visualstudio.com/api/get-started/your-first-extension

このチュートリアルをベースにして、自分たち専用の拡張機能を作ってみましょう！

## 拡張機能の要件

私が今回作ろうとした拡張機能の要件は以下です。

### 要件

VSCode用の拡張機能を実装します。この拡張機能は、ショートカットキーで新しいファイルを作成し、音声入力モードを開始することで、会議内容を記録するためのものです。

### 基本理念：アジャイル開発

- **説明**: 各開発プロセスでは、最も重要な1つの機能だけを実装する。
- **理由**: 人間の脳は抽象的な内容を想像するのが苦手なため、実際に形にすることで次の思考を促進できる。

### 要件の分解

1. **第一歩：Hello World**
   基本的な「Hello World」を表示する機能を作成する
2. **第二歩：高速メモ**
   - メモ用の新しいファイルを作成する。
   - 作成したファイルを開いてユーザーが編集できるようにする。
3. **第三歩：音声入力の起動**
   `Voice: Start Dictation in Editor`（`workbench.action.editorDictation.start`）コマンドをトリガーして、音声入力を開始する。
4. **第四歩：ショートカットキーの設定**
   ショートカットキーを設定し、コマンドをトリガーできるようにする。

## Vscode拡張機能の作成実装もろもろ

### 一　Hello world

VSCodeで新しいフォルダを作成、公式チュートリアルに従って進めれば、自分専用のVSCode拡張機能を作成することができます。

```
npm install --global yo generator-code

yo code
```

ここでは下記のように選択/入力してみました。

```zsh
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? voicenoteplus
? What's the identifier of your extension? voicenoteplus
? What's the description of your extension? voicenoteplus
? Initialize a git repository? Yes
? Which bundler to use? esbuild
? Which package manager to use? npm
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/20bc91ee-044b-8d8d-4d10-2c69793b7161.png)

プロジェクトの初期化が完了するのを待ちます。ここまでの作業で、プロジェクトのひな形が作成されます。

#### 実行とデバッグ

VSCodeで「voicenoteplus」フォルダを開きます。

まず、すべての依存関係をインストールし、生成された拡張機能をビルドします。

```
npm install

npm run compile
```

`src/extension.ts` を開いた状態で F5 キーを押すと、新しい VSCode ウィンドウ が起動します。

**Command + Shift + P**（Windowsの場合は **Ctrl + Shift + P**）を押してコマンドパレットを開き、「実行とデバッグ」メニューから「Hello World」を実行すると、画面右下に通知が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/d814b50d-247d-257e-2365-e27695ebd676.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/2398f4ff-44c9-ec7a-1520-4cadbf7e2a81.png)

### 二　高速メモ：メモファイルの作成と編集

このメモ拡張機能の最も重要な機能は「音声メモファイルを迅速に作成すること」です。

音声入力は後ほど実装するとして、まずは最重要な部分から始めます。

幸い、会社が提供しているGitHub Copilot in VS Codeを活用し、AIを使って素早く開発を進められます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/20beb2e9-a258-77a5-4fd8-02af4ceae196.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/d11fe543-7e00-1628-318f-89b8010d44e5.png)

AIで生成したコードをプロジェクトにコピーします。

#### src/extension.ts

```js

import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';

export function activate(context: vscode.ExtensionContext) {
  console.log('Congratulations, your extension "voicenote-" is now active!');

  const disposable = vscode.commands.registerCommand(
    'voicenote.createNote',
    async () => {
      const workspaceFolders = vscode.workspace.workspaceFolders;

      let notePath: string;
      if (!workspaceFolders || workspaceFolders.length === 0) {
        // ワークスペースフォルダが開かれていない場合、一時ディレクトリにファイルを作成する
        const tempDir = os.tmpdir();
        const noteName = `note-${Date.now()}.md`;
        notePath = path.join(tempDir, noteName);
      } else {
        // ワークスペースフォルダが開かれている場合、ワークスペースフォルダにファイルを作成する
        const noteName = `note-${Date.now()}.md`;
        notePath = path.join(workspaceFolders[0].uri.fsPath, noteName);
      }

      fs.writeFileSync(notePath, '# ' + path.basename(notePath));

      const document = await vscode.workspace.openTextDocument(notePath);
      await vscode.window.showTextDocument(document);
    }
  );

  context.subscriptions.push(disposable);
}

export function deactivate() {}

```

そして、`package.json` に宣言を追加します。

#### package.json

```json
  "contributes": {
    "commands": [
      {
        "command": "voicenote.createNote",
        "title": "Create Note"
      }
    ]
  },
```

`npm run compile` を実行後、F5キーでプロジェクトを起動します。**Command + Shift + P**（Windowsの場合は **Ctrl + Shift + P**）でコマンドパレットを開き、`Create Note` と入力すると、新しいメモを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/9f063200-b6e7-e6b8-e103-7014e825a752.png)

### 三　音声入力の起動

まず、VSCode 内に音声入力に関連する機能があるかを調べます。

**Command + Shift + P**（Windowsの場合は **Ctrl + Shift + P**）を押して、Voice を検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/db53865d-28e2-7ae3-97b9-69c4ad1242a0.png)

もし見つからない場合は、拡張機能で「VS Code Speech」と検索し、該当する拡張機能をインストールしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/51882b14-d6e2-c789-3b25-30105f695be5.png)

これは、私たちが必要としている機能に似たAPIです。

`Voice: Start Dictation in Editor` コマンドの設定ページに移動すると、このコマンドのIDが `workbench.action.editorDictation.start` であることが確認できます。このIDをコピーします。

それでは、Copilot に質問してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/141dcd85-0d38-9dcc-d257-9d10e66a89ca.png)

Copilotの提案通り、`src/extension.ts` の最後にコマンドを追加します。

      // エディタのディクテーションコマンドを実行する
      await vscode.commands.executeCommand(
        'workbench.action.editorDictation.start'
      );

試してみると、音声記録機能が無事に実現できたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/faca3432-4aad-20ba-9d7d-a16857305027.png)

### 四　ショートカットキーの設定

手動でコマンドを入力するのは、効率があまりにも低すぎます。上司の**重要な発言**を最速で記録するには、ショートカットキーを使って、先ほど実装したロジックをトリガーする必要があります。

再び Copilot 先生に質問してみましょう。

```
#vscodeApi

ショートカットキーで `voicenote.createNote` をトリガーする方法は？
```

生成されたコードをpackage.jsonにコピーして

#### package.json

```json
  "contributes": {
    "commands": [
      {
        "command": "voicenote.createNote",
        "title": "Create Note",
        "icon": "./create-note.png"
      }
    ],
    "keybindings": [
      {
        "command": "voicenote.createNote",
        "key": "ctrl+alt+n",
        "mac": "cmd+alt+n",
        "when": "editorTextFocus"
      }
    ]
  },
```

`npm run compile` を実行した後、**Command + Alt + N**（Windowsの場合は **Ctrl + Alt + N**）を押すと、ワンクリックで音声メモをすばやくトリガーできます。

これで開発は完了です。次は、プロジェクトをパッケージ化してMicrosoftのストアに公開します。

### 五　 拡張機能のパッケージングとインストール

まず、AIで生成したアイコン `create-note.png` をルートディレクトリに配置し、`package.json` に発行者とアイコンを設定します。

```json
"publisher": "xxx",
"icon": "./create-note.png"
```

`npm install -g vsce` を実行して、vsce をインストールします。

> **vsce** は「Visual Studio Code Extensions」の略で、VSCode 拡張機能をパッケージ化、公開、および管理するためのコマンドラインツールです。
>
> パッケージ化を行う前に、README.md ファイルを修正する必要があります。

パッケージ化を実行します。

- コマンドを実行：`vsce package`
- プロジェクトのルートディレクトリに `voicenoteplus-0.0.1.vsix` が生成されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/60bb8273-9727-ca83-e838-7f09f4d053ee.png)

拡張機能ページで「VSIX ファイルからのインストール」を選択すると、インストールが完了します。

> パッケージ化がうまくいかない場合、ESLint Flat Config に問題がある可能性があります。この場合、"eslint" のバージョンを "^8.56.0" にダウングレードし、`eslint.config.mjs` を Copilot を使用して `.eslintrc.json` に変換してください。



### 六　 拡張機能の公開

Microsoft の管理プラットフォームで手動で公開します。

https://marketplace.visualstudio.com/vscode

- [Extensions for Visual Studio](https://marketplace.visualstudio.com/) -> 「Publish extensions」 -> 「+New Extension」 -> 「Visual Studio Code」 -> `voicenoteplus-0.0.1.vsix` ファイルをアップロードします。

```
It's live!
Your extension is now visible on the Marketplace (see it) and can be discovered and installed from every Azure DevOps organization.
```

15分後には、VSCodeのストアで拡張機能を検索できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/a231e9de-6151-de0c-7b8f-788d879301ca.png)

## 使用方法

1. 拡張機能をインストール：
   - VS Code 拡張機能ストアで "voicenoteplus を検索してインストールします。
2. 拡張機能を使用：
   - キーボードショートカット (`Ctrl+Alt+N` または `Cmd+Alt+N`) を押して新しい音声メモを作成します。

## 動かした結果

やっと実装と設定が終わったので、UX定例でvoicenoteplusを使用していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/9c5d2946-a355-e309-1594-44108979470c.png)

たしかに、音声認識が正確でないことや、誤字や脱字が発生することもあります。しかしさらに賢いcopilotに頼んで、メモを整理したら

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242020/3d6029c0-44dc-7144-42e0-6d8469d18465.png)

かなり便利で効率的になったのではないでしょうか！

今回作成した拡張機能のソースコードはGitHubで公開しています。

https://github.com/hjpotter1/voicenote-

興味のある方はぜひインストールしてみてください。

https://marketplace.visualstudio.com/items?itemName=hjpotter.voicenoteplus

間違いなどありましたらコメントにてご指摘ください。ここまで読んでいただきありがとうございました。

## 参考URL

https://zenn.dev/tatsuyasusukida/scraps/1e8233467e23ea

https://qiita.com/_ken_/items/06161e8d4bac5e0bd209

https://code.visualstudio.com/api/get-started/your-first-extension

## エンジニア募集

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています！！
ぜひお気軽にカジュアル面談へお越しください！！

https://gakken-leap.co.jp/recruit/