AIとの対話でタイムテーブル作成ツール「ペタスク(旧TimeBlock)」を作ってみた

  • タイムテーブル作成ツール「PeTask(旧TimeBlock)」を作りました。
  • これは、生成AI(Claude 3.7 Sonnet)との対話で開発し、単一HTMLファイルからあっという間に複雑なモジュール構造まで発展できました。
  • 生成AIを活用すると、プログラミングの基礎知識をもとに、機能的なウェブアプリケーションが短期間で開発できます。

生成AIで「テコの原理」がはたらく「プログラミングの基礎知識」って何なんだろうね。
これまでの試行錯誤の経験なのかな。

オンラインツールTimeBlockを作った

週末の2日間で「PeTask(旧TimeBlock)」というオンラインツールを作りました。

一日のスケジュールや空き時間を画像形式でメッセージ共有するために特化したツールです。
PWAなので、ブラウザからインストールして利用することもできます。
すべてブラウザ内での処理で、データ保存にサーバは利用していません。

カレンダーとの連携ではなく、さっとタップ操作で埋まっている時間帯を入れて、画像共有する使い方を想定しています。

生成AIを活用して作った

「時間の積み木」みたいなイメージで命名したけど、他の人に使ってもらうなら「空き時間シェア」とか、もっとわかりやすい名前の方がいいかもね。
→ペタッとスケジュール、「ペタスク」に改名しました。

業務後の時間を使うと、これまでだったら半月はかかりそうなものです。
しかし、生成AI(Claude 3.7 Sonnet)との対話を通じて段階的に開発したことで、すぐに形になりました。

TimeBlockプロジェクトの成長過程 初期バージョン Version 1.0.0 2025-03-21 ファイル分割 Version 1.2.0 2025-03-22 午前 モジュール化 Version 1.3.0+ 2025-03-22 午後 完成形 最終バージョン 2025-03-22 夜 index.html HTML+CSS+JSが全て 1つのファイルに index.html styles.css script.js HTML/CSS/JSが それぞれ分離 index.html styles.css manifest.json service-worker.js js/ app.js utils/ core/ index.html styles.css manifest.json service-worker.js js/ app.js utils/ core/ ui/ interactions/ rendering.js modals.js 一つのファイル 3つのファイル モジュール化(9+ファイル) 完全な構造(15+ファイル)

単一のファイル(23KB)からスタートしたものが、わずか2日の間にプロジェクト(20ファイル:140KB)として発展しました。

それでも文字データは、写真などに比べると圧倒的に小さいです。
だいたい日本語だと 1文字が3バイト程度なので、140KBは約4万6千文字、小説だと約115ページ分ぐらいというイメージでしょうか。コードを読む順番さえわかれば、十分に読み取れる分量ですね。

開発プロセスでは、各段階での開発内容をAIに理解させ、次のステップに進むための要件定義書が生成しました。
これらの要件定義書は、AIとの対話を継続するための橋渡しとなり、プロジェクトの一貫性を保つ役割を果たしました。

3行のプロンプトと要件定義

まずは、アイデアをそのまま指示しました。

マウスクリックで操作するだけで、今日のタイムテーブルを設定できるウェブサイトを作りたいです。JavaScriptとCSSだけでサイトに設置します。
ユーザーが作成した画面は、画像形式で共有することをイメージしています。

どんな機能が必要か、まずは要件定義を一緒に考えよう

この要件定義を元に、自分で追加項目を加筆して最初の要件定義を作りました。

初期のファイル構成(2025年3月21日バージョン1.0.0):

TimeBlockプロジェクトは、たった一つのHTMLファイルから始まりました。
初期段階では、すべてのコード(HTML、CSS、JavaScript)が単一のファイルに含まれていました。

最終的なプロジェクトのファイル構造を見ると、複雑に見えます。
しかし、それぞれのファイルは1つのファイルを分割して、機能を追加し、また分割して、という流れで生まれていきました。

これは、既存のコードを読み解くうえでも大事な視点です。

シンプルなファイル構成からスタートすると、開発の初期段階では複雑なファイル管理や環境設定の必要がなく、すぐに機能の実装に集中できます。

/
└── index.html  # HTML, CSS, JSがすべて含まれた単一ファイル
Code language: PHP (php)

HTML構造で文字やボタンを表示し、JavaScriptで処理内容を記述しています。
ブラウザ内で処理を完結するようにすれば、比較的かんたんに作れます。

これは特に、プログラミング初心者やプロジェクトを素早く立ち上げたいユーザーにとって大きなメリットですよね。

初期バージョンの機能(v1.0)

単一ファイルながらも、初期バージョンも一応動作できるようになっていました。

タイムテーブル作成ツールの機能概要 初期化と主要機能 • DOMContentLoadedで起動 • 開始時間のデフォルト設定 • 9時間分のテーブル生成 • 15分刻みのセル配置 ユーザー操作処理 • クリックでイベント追加 • イベント名・色の編集 • ドラッグ移動(15分単位) • 範囲内移動に制限 データ操作機能 • PNG画像として保存 • JSONデータ形式エクスポート • インポートで復元 • モーダルウィンドウ表示 ヘルパー関数 • HH:MM形式の時間処理 • イベントリスナー管理 • 位置・サイズ計算 アプリケーションワークフロー ページ読み込み イベント追加 イベント編集 画像保存 データ共有
  • タイムテーブルの表示(時間グリッド)
  • イベントの作成、編集、移動、削除
  • 色によるイベントの分類
  • 画像としての保存機能
<!-- 初期バージョンのHTMLサンプル(一部抜粋) -->
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>タイムテーブル作成ツール</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <style>
        /* CSSスタイルがここに直接記述されている */
        body {
            padding: 20px;
            background-color: #f5f5f5;
        }
        .timetable {
            width: 100%;
            border-collapse: collapse;
        }
        /* 残りのスタイル... */
    </style>
</head>
<body>
    <!-- HTMLマークアップ -->
    <div class="container">
        <h1>タイムテーブル作成ツール</h1>
        <!-- UI要素... -->
        <div class="timetable-container" id="timetable-container">
            <!-- テーブル... -->
        </div>
    </div>

    <script>
        // JavaScriptコードがここに直接記述されている
        document.addEventListener('DOMContentLoaded', function() {
            // 変数の初期化
            let startHour = 10;
            let events = [];
            // 残りのコード...
        });
    </script>
</body>
</html>
Code language: HTML, XML (xml)

まずは、動作するプロトタイプ(試作品)を作るのがコツです。

ファイル分割とモジュール化への第一歩(v1.2)

プロジェクト2日目(2025年3月22日)には、最初の大きな構造変更が行われました。
保守性と拡張性を高めるために、単一ファイルから、HTML、CSS、JavaScriptを別々のファイルに分離する作業を実施しました。

ファイル分割後の構成(バージョン1.2.0):

/
├── index.html          # HTMLマークアップのみ
├── styles.css          # CSSスタイル定義
└── script.js           # JavaScriptコード
Code language: PHP (php)

これらのコードをサーバにアップロードし、ブラウザから動作することを確認しました。

今回のプロジェクトでは、「エントリーポイント」は index.html です。
したがって、「ファイル分割」では、新しいファイルをディレクトリ内に保存して、index.htmlから読み取るようにします。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>プロジェクト名</title>
    <!-- 外部CSSファイルの読み込み -->
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- HTMLコンテンツ -->
    <!-- 外部JavaScriptファイルの読み込み-->
    <script src="script.js"></script>
</body>
</html>Code language: HTML, XML (xml)

外部CSSファイルは head タグ内で、外部JavaScriptファイルは bodyの終了タグ直前に配置するのが一般的です。
基本的には、ファイルを追加するたびに読み込む外部スクリプトファイルを追加します。

この変更は単純ですが、コードの管理と拡張性を大きく向上させます。
生成AIにコードを修正させる場合には、ファイルの粒度を小さくしておくことがコツだからです。

生成AIにはトークン制限があり、大きなファイルを読み込ませると、細部を見落としやすくなるからです。
それぞれのファイルが特定の役割に集中できるようになり、修正や機能追加が容易になるからです。

本格的なモジュール化とPWA対応(v1.3)

その後、AIとの対話を通じて、JavaScriptのコードは機能ごとにモジュール化され、構造化していきます。

モジュール化されたファイル構成:

/
├── index.html          # メインのHTMLファイル
├── styles.css          # スタイルシート
├── manifest.json       # PWAマニフェスト(新規追加)
├── service-worker.js   # サービスワーカー(新規追加)
└── js/                 # JavaScriptファイル(ディレクトリ化)
    ├── app.js          # アプリケーション初期化と管理
    ├── utils/          # ユーティリティ(サブディレクトリ)
    │   ├── debug.js    # デバッグとログ関連
    │   └── helpers.js  # ヘルパー関数
    ├── core/           # コア機能(サブディレクトリ)
    │   ├── storage.js  # データ保存と読み込み
    │   └── appointments.js  # 予定操作のコア機能
    └── ui/             # UI関連(サブディレクトリ)
        ├── rendering.js    # UI描画
        ├── modals.js       # モーダルとダイアログ
        └── interactions.js # ユーザー操作
Code language: PHP (php)

ここでの重要な変化は、単一のJavaScriptファイルが機能ごとに分割され、ディレクトリ構造に整理していったことです。
この変更により、コードの可読性と保守性が大幅に向上しました。

「スマートフォン用アプリ」として手軽に使えるようにしたかったので、この段階で Progressive Web App(PWA)としての機能も追加しました。
manifest.jsonservice-worker.jsが追加し、オフライン機能やホーム画面へのインストールができるようにしました。

ファイルにコードが追加して見にくくなったら分割する、という繰り返しで、どんどん構造化されていきました。
私の頭では、だいたい 400行(20KBほど)を超えて来ると見通しが悪くなってくるので、分割したくなってきます。
もちろん、コードの分割は細心の注意が必要で、分割後に同じ動作になるように整合性を確認するのは大変です。
しかし、ファイルサイズが大きくなると収集がつかなくなるので、必要な作業です。

さらなる細分化と機能拡張(v1.4)

プロジェクトが進むにつれ、特にユーザー操作(interactions)部分が細かくなることがわかりました。
使いやすくするには、モバイルデバイスのタッチ操作対応など、複雑な条件分けが必要になるからです。

そのため、「interactions.js」を8つに細分化しました。

最終的なファイル構成:

/
├── index.html
├── styles.css
├── manifest.json
├── service-worker.js
└── js/
    ├── app.js
    ├── utils/
    │   ├── debug.js
    │   └── helpers.js
    ├── core/
    │   ├── storage.js
    │   └── appointments.js
    └── ui/
        ├── rendering.js
        ├── modals.js
        ├── interactions.js              # メインのインタラクションモジュール
        └── interactions/                # サブモジュールに分割(新規追加)
            ├── feedback.js              # 視覚的フィードバック管理
            ├── update.js                # DOM要素とデータの更新
            ├── calculate.js             # 位置・サイズの計算
            ├── detect.js                # ユーザー操作の検出・判別
            ├── appointment-handlers.js  # 予定操作関連
            ├── modal-handlers.js        # モーダル操作関連
            ├── settings.js              # 設定関連
            └── data-management.js       # データ管理関連
Code language: PHP (php)

ユーザー操作の処理を「検出→計算→更新→フィードバック」というフローに沿って整理しました。

なかなか思った通りに動作してくれないときに、どのコードを修正するのかがわかりやすくなります。

AIとのコラボレーションがもたらしたもの

生成AIの画期的なことは、専門的な開発スキルが不足していても、AIとの対話を通じて現代的なプログラミング手法を学びながら実践できることだと言えます。

もちろん、ユーザーにまったく知識がなくても作れるわけではありません。
コードの問題点をおおまかに理解したり、プロジェクトを進める方向性は理解していないといけません。
しかし、個別の技術的な内容に立ち入らずとも、動作するプログラムを完成させることができました。

AIとの対話で学ぶプログラミング:段階的進化のコツ AIとプログラミング学習の新しいアプローチ 専門知識がなくても、AIとの対話を通じて段階的に学びながら実用的なアプリを開発できます フェーズ1 単一HTMLファイル からスタート すべてのコードが 1ファイルに集約 フェーズ2 ファイル分割 HTML/CSS/JS 役割ごとに 分離して管理 フェーズ3 モジュール化 機能ごとに分割 保守性と 拡張性の向上 完成形 堅牢なアプリケーション 機能拡張と最適化 小さなステップの積み重ねが 高品質なアプリを生み出す 最初から複雑なコードを作らずに、理解しながら発展させる
  1. 知識のギャップを埋める:
    AIが専門的な知識(モジュール化、PWA対応、タッチ操作の最適化など)を提供し、開発者は自分のペースで経験しながら実装できました。
  2. 段階的な複雑性:
    単一ファイルからはじめて徐々に複雑化していくアプローチで、開発者は何がどこにあるのか段階的に理解して開発を進められました。
  3. 要件定義のサポート:
    AIとの対話から生成された要件定義書が、次のステップに進むための明確な指針となりました。

ふわっとしたイメージを具体的なコードに落とし込むサポートとして、生成AIが役に立つわけです。

実際の開発のようす

開発者は各段階で、実装したい機能や直面している課題をAIに伝え、AIからの提案やコードサンプルをもとに実装を進めました。

例えば、タッチ操作の対応については、AIが視覚的フィードバックの実装方法や長押し検出の仕組みを提案し、それを開発者が自分の理解に合わせて適用していきました。

// AIとの対話から生まれたタッチフィードバック実装例
function showTouchFeedback(x, y) {
  feedbackElement = document.createElement('div');
  feedbackElement.className = 'touch-feedback';
  feedbackElement.style.left = `${x - 50}px`;
  feedbackElement.style.top = `${y - 50}px`;
  document.body.appendChild(feedbackElement);
}
Code language: JavaScript (javascript)

自分にとって使いやすいアプリを作れる

最終的に完成したTimeBlockアプリケーションは、単なる学習プロジェクトを超えた実用性を持っています:

  • 5種類のテーマ(ライト、ダーク、パステル、カラフル、ミニマル)
  • タッチデバイス対応の直感的な操作
  • 予定の重要度に応じた5段階の色分け
  • データのインポート/エクスポート機能
  • 画像共有機能
  • オフライン使用可能なPWA対応

これらの機能は、いずれも自分にとって必要なアイデアをAIとの対話を通して実装方法を具体化していきました。

【考察】AIが変える開発の未来

TimeBlockプロジェクトは、生成AIが「プログラミングの民主化(誰でもプログラムを作れる)」にどのように貢献できるかを示す好例だと思います。
つまり、プログラミングの専門知識がそれほど豊富でなくても、AIとの対話を通じて段階的に学びながら、実用的なアプリケーションを開発できるようになったのです。

ただ、それにはコツがあります。
いきなり完成コードを作らせるよりも、単一HTMLファイルから始めるのが大事です。

それを徐々に複雑なモジュール構造へと進化させていくプロセスによって、ユーザーが自分の作っているソフトウェアを理解していくことができるのです。
「ファイル構成の進化」が視覚的に示すように、小さなステップの積み重ねが結果として堅牢なアプリケーションを生み出しています。

今後、AIとの対話を通じたプログラミング学習と開発はさらに普及していくでしょう。
プログラミングの障壁を下げ、より多くの人々がテクノロジー創造の喜びを体験できると思います。