【Codex】③ Codex AppでWorktree・SDD・Gitレビューを実践する:四則演算CLIの開発記録

未分類

「四則演算コマンドライン計算機」を題材に、ローカル環境で、Worktree(User/Codex/…)に別ブランチを立ち上げ、アプリ開発.

  • Codex app起動方法ワークスペースから”Codex app . ”で立ち上げる、若しくは、WinスタートメニュからChatGPTを起動し、左上でCodexを選択
  • Worktree (User/Codex/…)により、別ブランチで開発し、最後に統合
  • VSCode+Codexとの違い順次差分を承認しながらLocalで開発するか、WorkTreeのブランチで開発し、最後にPull&Margeするかの違い

はじめに

Codex主要コンポーネント習得プログラムの第3回として、今回はCodex Appを使った実践開発を行った。

題材には、前回までに作成した簡単なPython除算プログラムを使用し、次の機能を持つ四則演算CLIへ拡張した。

python app.py <left> <operator> <right>

今回の主な学習項目は次のとおりである。

  • Codex Appからローカルリポジトリを開く
  • Codex Worktreeによる隔離された開発
  • AGENTS.mdを使った開発ルールの適用
  • SDD(Specification-Driven Development)
  • Codexによる実装、テスト、レビュー
  • Worktreeのコミットを元のリポジトリへ統合
  • Gitブランチとstashを使った安全な作業

1.使用環境

今回使用した環境は次のとおり。

OS             : Windows 11
Python         : Python 3.11系
Codex CLI      : codex-cli 0.144.5
Gitブランチ    : master
テスト         : Python unittest

対象プロジェクトは以下。

D:\usr8_work\work_23_chatgpt\16_PoCs\1001_Codex\
1001_Codex\02_codex-extension-tutorial

開始時点では、除算関数divide()と2件の単体テストが存在していた。

def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("b must not be zero")
    return a / b

初期テスト結果は次のとおり。

Ran 2 tests in 0.001s

OK

また、この時点ではGitHubリモートは未設定だった。


2.作業開始前のGit状態を整理

最初にGit状態を確認した。

git status
git branch --show-current
git remote -v
python -m unittest -v
codex --version

確認結果では、次のファイルに未コミット変更があった。

modified: app.py
modified: test_app.py

untracked:
AGENTS.md
run.bat
タイトルなし.png

Codex AppでWorktreeを使う前に、現在の状態を基準版としてコミットすることにした。

git diff --check

git add app.py test_app.py AGENTS.md run.bat

git commit -m "chore: establish Codex tutorial baseline"

作成された基準コミットは次のとおり。

c0301a0 chore: establish Codex tutorial baseline

ブログ用の画像はコード変更に含めず、stashへ一時退避した。

git stash push -u -m "temporary: blog screenshot before Codex App exercise"

これにより、作業ツリーはクリーンになった。

On branch master
nothing to commit, working tree clean

3.Codex Appを起動する

プロジェクトフォルダーから次を実行した。

codex app .

初回はCodex Desktopが見つからず、インストーラーが開いた。

Codex Desktop not found; opening Windows installer...

After installing Codex Desktop, open workspace
D:\usr8_work\...\02_codex-extension-tutorial

インストール後、Codex Appから対象プロジェクトを開いた。


4.読み取り専用でリポジトリを調査

最初からコードを編集させるのではなく、次の内容をCodexへ指示した。

このリポジトリを読み取り専用で調査してください。
この段階ではファイルを変更しないでください。

app.py、test_app.py、run.bat、AGENTS.mdの役割、
現在の機能、テスト結果、不足文書、
四則演算CLIへの拡張計画を報告してください。

Codexは元のプロジェクトを直接変更せず、次のWorktree内で調査を行った。

C:\Users\ohide\.codex\worktrees\10ab\
02_codex-extension-tutorial

これがCodex AppにおけるWorktreeの重要なポイントである。

元のフォルダーとは別の作業領域で調査・実装するため、通常の開発フォルダーを直接汚さずに変更を進められる。

Codexは調査の結果、次のSDD文書が不足していると判断した。

docs/spec.md
docs/architecture.md
docs/task.md

これはAGENTS.mdに記載した開発ルールをCodexが読み取り、従った結果である。


5.SDD文書を先に作成

今回は、実装前に仕様・構成・タスクを文書化するSDDを採用した。

spec.md

docs/spec.mdには、次の仕様を定義した。

CLI形式:
python app.py <left> <operator> <right>

対応演算子:
+ - * /

入力値:
整数、小数、負数
内部ではfloatとして処理

正常終了:
結果を標準出力へ表示
終了コード0

異常終了:
標準エラーへメッセージを表示
終了コード2

architecture.md

docs/architecture.mdでは、計算ロジックとCLI処理を分離する方針を定義した。

計算ロジック
  add()
  subtract()
  multiply()
  divide()
  calculate()

CLI境界
  main()

外部ライブラリは使わず、Python標準ライブラリのみを使用する。

task.md

docs/task.mdには、作業を5段階に分割した。

TASK-001:SDD文書の作成
TASK-002:四則演算ロジックの実装
TASK-003:CLI処理の実装
TASK-004:単体テストとCLIテストの追加
TASK-005:最終検証と文書同期

TASK-001完了時点では、既存のapp.pytest_app.pyrun.batには変更を加えなかった。


6.Codex App上でブランチを作成

Codex AppのGit画面では、「Create branch here」という名称のボタンは表示されなかった。

実際のUIでは「新しいブランチ」を選択し、ブランチ名とコミットメッセージを入力した。

最終的にCodex Worktree側で使用されたブランチは次の名前となった。

calculator-sdd-01

SDD文書のコミットは次のとおり。

7ac9f16 docs: define calculator SDD

今回、Codex Appの画面操作ではブランチ名の接頭辞が自動で付く場合があり、ローカル側で作成したブランチ名とは異なる点に注意が必要だった。


7.四則演算ロジックを実装

TASK-002では、次の関数を追加した。

def add(a: float, b: float) -> float:
    return a + b


def subtract(a: float, b: float) -> float:
    return a - b


def multiply(a: float, b: float) -> float:
    return a * b


def calculate(a: float, operator: str, b: float) -> float:
    if operator == "+":
        return add(a, b)
    if operator == "-":
        return subtract(a, b)
    if operator == "*":
        return multiply(a, b)
    if operator == "/":
        return divide(a, b)

    raise ValueError(f"unsupported operator: {operator}")

既存のdivide()は互換性を維持した。

def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("b must not be zero")
    return a / b

未対応演算子では、次の例外を返す。

ValueError("unsupported operator: <operator>")

TASK-002終了時点で、テストは2件から10件へ増加した。

Ran 10 tests in 0.001s

OK

8.CLI処理を実装

続けてTASK-003からTASK-005を実行した。

CLI形式は次のとおり。

python app.py <left> <operator> <right>

例:

python app.py 10 + 2
python app.py 10 - 2
python app.py 10 "*" 2
python app.py 10 / 2

乗算記号*はシェルによる展開を防ぐため、Windows環境でも引用符を付けた。

CLI処理はmain()へ分離した。

def main(args=None) -> int:
    ...

正常時には計算結果のみを標準出力へ表示する。

12.0

異常時は、Pythonのトレースバックを表示せず、標準エラーへ原因だけを表示する。

error: b must not be zero

終了コードは次のように定義した。

正常終了:0
異常終了:2

9.CLIテストを追加

test_app.pyには、計算関数の単体テストに加えて、subprocess.run()を使った実プロセスのCLIテストを追加した。

テストではシェルを介さず、引数をリスト形式で渡した。

subprocess.run(
    [sys.executable, "-B", "app.py", "10", "+", "2"],
    capture_output=True,
    text=True,
)

追加した主なテストは次のとおり。

正常系

加算
減算
乗算
除算
小数
負数

異常系

引数不足
引数過多
左オペランドが数値ではない
右オペランドが数値ではない
未対応演算子
ゼロ除算

異常系では次を確認した。

終了コードが2
標準出力が空
標準エラーに原因が表示される
Tracebackが表示されない

最終的なテスト数は22件となった。

Ran 22 tests

OK

10.Codexレビューを実施

実装完了後、Codexへ読み取り専用の最終レビューを依頼した。

確認項目は次のとおり。

SDD文書との整合性
四則演算の正しさ
CLIの終了コード
標準エラー処理
divide()の後方互換性
テスト不足
Windowsでのrun.bat
セキュリティと保守性

レビュー結果では、Critical、High、Mediumの問題はなかった。

Lowとして次の2点が指摘された。

  1. 右オペランドが非数値の場合の自動テストが不足
  2. stdout.strip()では余分な空白を許容する

これらはコミット前に修正した。

正常系CLIテストでは、次のように出力全体を厳密に比較するよう変更した。

self.assertEqual(result.stdout, "12.0\n")

Codexによるレビューを単なる確認で終わらせず、指摘を自動テストへ反映できた点は有用だった。


11.コミットとWorktreeからの統合

Codex Worktree側では、次の2コミットが作成された。

7ac9f16 docs: define calculator SDD
63465c5 feat: complete four-operation calculator CLI

一方、元の作業フォルダーでは次のブランチを作成していた。

feature/codex-calculator

この時点では、完成コミットは元のブランチではなく、Codex Worktree側のcalculator-sdd-01に存在していた。

状態確認には次を使用した。

git worktree list
git log calculator-sdd-01 --oneline --decorate -5

表示結果:

63465c5 calculator-sdd-01
7ac9f16 docs: define calculator SDD
c0301a0 chore: establish Codex tutorial baseline

ローカル側に残っていたAGENTS.mdの変更と.codex/は、マージ前にstashへ退避した。

git stash push -u -m "temporary: local files before calculator merge"

その後、Fast-forwardで統合した。

git merge --ff-only calculator-sdd-01

結果:

Updating c0301a0..63465c5
Fast-forward

続いてmasterへ切り替え、完成ブランチを統合した。

git switch master

git merge --ff-only feature/codex-calculator

最終ログは次のとおり。

63465c5 (HEAD -> master, feature/codex-calculator, calculator-sdd-01)
feat: complete four-operation calculator CLI

7ac9f16
docs: define calculator SDD

c0301a0
chore: establish Codex tutorial baseline

12.ローカルでの動作確認

元のプロジェクトフォルダーから、代表的なコマンドを実行した。

加算

python -B app.py 10 + 2
12.0

乗算

python -B app.py 10 "*" 2
20.0

ゼロ除算

python -B app.py 10 / 0
error: b must not be zero

run.bat経由

cmd /c run.bat 10 + 2
12.0

run.batはもともと引数をapp.pyへ転送する構造だったため、変更せずに利用できた。

@echo off
setlocal
python "%~dp0app.py" %*
exit /b %errorlevel%

13.今回分かったこと

Codex Appは元のフォルダーを直接編集するとは限らない

Codex Appでは、次のような独立したWorktreeが作成された。

C:\Users\ohide\.codex\worktrees\10ab\...

そのため、元のフォルダーでgit logを確認しても、Codexが作ったコミットが最初は表示されなかった。

Worktreeとブランチの関係を確認するには、次が重要である。

git worktree list
git branch
git log <branch-name> --oneline

AGENTS.mdの指示は実際に反映された

CodexはAGENTS.mdを読み取り、いきなり実装を開始せず、不足していたSDD文書を先に作成した。

また、「読み取り専用」と指定した調査では、コード変更を行わなかった。

実装とレビューを分けると安全性が上がる

今回は次の段階に分けた。

調査
仕様作成
ロジック実装
CLI実装
テスト
レビュー
修正
コミット
マージ

Codexへ一度にすべて任せるよりも、重要な区切りで内容を確認した方が、意図しない変更を防ぎやすい。

コミットがどのWorktreeにあるか確認する必要がある

Codex App上でコミットしても、元の作業ブランチへ自動的に反映されるとは限らない。

今回のように、Codex Worktree側のブランチを明示的にFast-forwardマージする必要がある場合がある。


14.今回の成果

今回のCodex App実習では、単純な除算プログラムを次のCLI計算機へ拡張できた。

python app.py <left> <operator> <right>

実装した機能:

加算
減算
乗算
除算
小数
負数
入力エラー処理
ゼロ除算処理
終了コード制御

開発成果:

SDD文書:3ファイル
Gitコミット:2件
最終テスト:22件
Critical問題:0件
High問題:0件
Medium問題:0件

今回の実習を通じて、Codex Appは単なるコード生成画面ではなく、次の作業を統合して進められることを確認できた。

リポジトリ調査
仕様策定
隔離Worktreeでの実装
テスト実行
コードレビュー
Gitコミット
ブランチ統合

次回は「④ Codex Cloud」として、このリポジトリをGitHubへ登録し、クラウド環境で複数のCodexタスクを並列実行する。

コメント

タイトルとURLをコピーしました