first-app / plan-and-build · 約 15 分
codex exec で生成する
制約付きプロンプトで server.js を作らせます。自分で置いても構いません。
学習目標
非対話の codex exec に、成果物と制約と検証を1つのプロンプトで渡します。
[codex-noninteractive]
前提
Git リポ。workspace-write が使えること。
なぜ必要か
対話だけだと再現しにくいです。exec なら同じプロンプトを再実行できます。
実行場所
codex exec は local-bridge です。Web実習 (browser) では starter の Node ファイルを実 FS に書いて node --check できます。プロンプト全文(starter の完了条件と一致):
このディレクトリに Node.js の小さな HTTP サーバを作ってください。
要件:
- package.json の name は hello-codex-school、type は module
- scripts.start は node server.js、scripts.test は node --test
- server.js は node:http のみを使う
- 127.0.0.1 のポート 4780(環境変数 PORT があればそれを使う)
- GET / と GET /health は 200 で本文 hello-codex-school
- その他は 404
- 応答に Access-Control-Allow-Origin: * と
Cross-Origin-Resource-Policy: cross-origin と
Cross-Origin-Embedder-Policy: require-corp を付ける
(学習サイトの COEP require-corp 下での iframe 埋込と、
サイト origin からの http_ok fetch 用。公開学習本文のみ)
- test/http.test.js を置く。server.js を別ポート(例: 4799)で spawn し、
fetch で GET / が 200 かつ hello-codex-school であること、
ACAO / CORP / COEP ヘッダがあることを assert する
- 依存パッケージを増やさない
- 秘密値をファイルに書かない
終わったら node --check server.js と npm test を実行して報告する。
npm test を codex の sandbox(workspace-write)内で走らせるときは、
-c sandbox_workspace_write.network_access=true が必要です
(既定では localhost の listen / fetch が拒否されます。このフラグは外向き通信も許可します。
ユーザー config の sandbox を緩めず、この実行だけに付けます)。
codex exec --sandbox workspace-write \
-c sandbox_workspace_write.network_access=true \
"$(cat <<'EOF'
このディレクトリに Node.js の小さな HTTP サーバを作ってください。
要件は README・package.json・test/http.test.js と一致させる。
scripts.test は node --test。依存を増やさない。秘密値を書かない。
終わったら node --check server.js と npm test を実行して報告する。
EOF
)" </dev/null </dev/null は非 TTY / スクリプト実行で、プロンプトを引数に渡したとき stdin 待ちで止まらないための EOF です。対話 TUI の codex では不要です。
node --check server.js が終了コード 0 であることと、test/http.test.js と npm test script があることが判定です。次の run-and-preview と capstone で HTTP と npm test を実実行します。
[codex-prompting]
test/http.test.js 全文:
import assert from "node:assert/strict";
import test from "node:test";
import { spawn } from "node:child_process";
test("GET / returns hello-codex-school with embed/CORS headers", async (t) => {
const port = "4799";
const child = spawn(process.execPath, ["server.js"], {
env: { ...process.env, PORT: port },
stdio: ["ignore", "pipe", "pipe"],
});
t.after(() => {
child.kill("SIGTERM");
});
await new Promise((resolve, reject) => {
const timer = setTimeout(resolve, 500);
child.stdout.on("data", () => {
clearTimeout(timer);
resolve();
});
child.on("error", reject);
});
const res = await fetch(`http://127.0.0.1:${port}/`);
assert.equal(res.status, 200);
assert.equal(await res.text(), "hello-codex-school");
assert.equal(res.headers.get("access-control-allow-origin"), "*");
assert.equal(res.headers.get("cross-origin-resource-policy"), "cross-origin");
assert.equal(res.headers.get("cross-origin-embedder-policy"), "require-corp");
});
ホスト上の確認:
npm test
sandbox 内で同じテストを走らせるときだけ:
codex sandbox -c 'sandbox_mode="workspace-write"' \
-c 'sandbox_workspace_write.network_access=true' -- npm test
成功結果
server.js に hello-codex-school と 127.0.0.1 があり、package.json に test script、test/http.test.js があります。
失敗対処
読み取り専用で書けないときは --sandbox workspace-write です。ネットワークインストールを始めたら、制約を再送してください。npm test が sandbox 内で fetch failed / EPERM なら、上記の network_access=true をその実行だけに付けます。global の sandbox 設定は緩めません。
このレッスンで接続する
ページを移動するとブラウザ内実習の接続とファイルは消えます。演習の直前に、このパネルから明示的に再接続してください(自動では戻りません)。