Adds a generate_image tool: Claude hands image requests to the local Codex (ChatGPT) CLI and gets back the saved file.

ชุด mod สำหรับ Claude Code บน Windows
| Mod | ทำอะไร |
|---|---|
statusline/statusline.js | Status bar 2 บรรทัด: ชื่อโปรเจค, git branch, แถบ context (ไล่สีเขียว→แดง), จำนวน token, ชื่อโมเดล และแถบเรทลิมิต Session (5 ชม.) / Week พร้อมเวลารีเซ็ต (ภาษาไทย) |
mods/clipboard-image-paste | วางรูปจาก Win+V ลงแชทได้ทันทีโดยไม่ต้องกด Alt+V และมีคำสั่ง /pasteimg ให้วางรูปจาก clipboard ซ้ำ |
mods/done-and-ask-sounds | มีเสียงเตือนตอน Claude ตอบเสร็จ และตอนถามคำถามหรือขอ permission (เงียบถ้ากำลังดูหน้าต่าง terminal อยู่) |
mods/codex-imagegen | เพิ่ม tool generate_image ให้ Claude สั่งสร้างรูปผ่าน Codex CLI (ChatGPT) ในเครื่อง (ไม่บังคับ) |
bypass/claude.cmd | พิมพ์ claude --bypass ได้เลย (แปลงเป็น --dangerously-skip-permissions) ใช้ได้ทั้งใน cmd, PowerShell และช่อง address bar ของ File Explorer |
%USERPROFILE%\.local\bin\claude.exe)codex-imagegengit clone https://github.com/bngxyz/claude-mods.git
cd claude-mods
powershell -ExecutionPolicy Bypass -File install.ps1
ถ้าจะใช้ codex-imagegen ด้วย ให้ใส่ path ของ codex.exe:
powershell -ExecutionPolicy Bypass -File install.ps1 -CodexPath "C:\Users\<you>\AppData\Local\Programs\OpenAI\Codex\bin\codex.exe"
เสร็จแล้วให้ ปิดแล้วเปิด Claude Code ใหม่ และ sign out/in หรือ restart Explorer (Task Manager → Windows Explorer → Restart) เพื่อให้ PATH ใหม่มีผล
statusline.js ไปที่ %USERPROFILE%\.claude\%USERPROFILE%\.claude\mods\%USERPROFILE%\.claude\settings.json (สำรองไฟล์เดิมเป็น settings.json.bak ก่อน)statusLine → node "<...>\statusline.js"env.CLAUDE_CODE_PLUGIN_DIRS → เพิ่ม path ของแต่ละ mod (คั่นด้วย ;)pluginConfigs.codex-imagegen.options.codexPath (เฉพาะตอนใส่ -CodexPath)claude.cmd ไปที่ %USERPROFILE%\.local\claude-wrap\ แล้วใส่โฟลเดอร์นี้ไว้หน้าสุดของ user PATHHKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\claude.exe ชี้ไปที่ claude.cmd เพื่อให้ address bar ของ Explorer และ Win+R เรียกผ่าน wrapperclaude # เปิดปกติ
claude --bypass # เปิดแบบข้าม permission ทั้งหมด
ในช่อง address bar ของ File Explorer พิมพ์ claude --bypass แล้วกด Enter จะเปิด Claude Code ในโฟลเดอร์นั้นเลย
ถ้าไม่อยากเห็นหน้าต่างเตือนทุกครั้งที่เปิดแบบ bypass ให้เพิ่มใน settings.json:
{
"skipDangerousModePermissionPrompt": true
}
Remove-Item "$env:USERPROFILE\.claude\statusline.js"
Remove-Item -Recurse "$env:USERPROFILE\.claude\mods\clipboard-image-paste", "$env:USERPROFILE\.claude\mods\done-and-ask-sounds", "$env:USERPROFILE\.claude\mods\codex-imagegen"
Remove-Item -Recurse "$env:USERPROFILE\.local\claude-wrap"
Remove-Item "HKCU:\Software\Microsoft\Windows\CurrentVersion\App Paths\claude.exe"
จากนั้นลบ statusLine, env.CLAUDE_CODE_PLUGIN_DIRS และ pluginConfigs.codex-imagegen ออกจาก settings.json และลบ %USERPROFILE%\.local\claude-wrap ออกจาก user PATH (Settings → System → About → Advanced system settings → Environment Variables)
hooks/register.ts 74 lines1import type { Register } from 'claude-code'
2
3const TOOL = 'mcp__codex-imagegen__generate_image'
4
5export const register: Register = (on, options) => {
6 const codexPath = options.codexPath
7 if (typeof codexPath !== 'string' || codexPath === '') {
8 throw new Error('codex-imagegen: option "codexPath" is required (full path to codex.exe)')
9 }
10
11 on('session.start', async ($, e, next) => {
12 await $.tool.register({
13 name: 'generate_image',
14 description:
15 'Generate an image by delegating to ChatGPT via the local Codex CLI. ' +
16 'Use this whenever the user asks to create/draw/generate an image. ' +
17 'Codex saves the image to output_path; the tool returns that path.',
18 inputSchema: {
19 type: 'object',
20 properties: {
21 prompt: { type: 'string', description: 'Detailed description of the image to generate.' },
22 output_path: {
23 type: 'string',
24 description: 'Absolute path of the PNG file to save, e.g. D:\\images\\cat.png.',
25 },
26 },
27 required: ['prompt', 'output_path'],
28 },
29 isDeferred: false,
30 })
31 return next(e)
32 })
33
34 on('tool.call', { tool: TOOL }, async ($, e) => {
35 const { prompt, output_path } = e as unknown as { prompt?: unknown; output_path?: unknown }
36 if (typeof prompt !== 'string' || prompt === '') {
37 return { deny: 'generate_image: "prompt" is required.' }
38 }
39 if (typeof output_path !== 'string' || output_path === '') {
40 return { deny: 'generate_image: "output_path" is required.' }
41 }
42
43 $.ui.status('Codex: generating image…')
44 try {
45 const instruction =
46 'Use your image generation tool to create the following image, then save the ' +
47 `resulting image file exactly at this absolute path: ${output_path}\n` +
48 'Reply with only the final saved path, or an error message if you could not.\n\n' +
49 `Image request:\n${prompt}`
50
51 const run = await $.process.run(
52 [
53 codexPath,
54 'exec',
55 '--skip-git-repo-check',
56 '--sandbox',
57 'workspace-write',
58 '--color',
59 'never',
60 '-',
61 ],
62 { stdin: instruction, timeoutMs: 600000 },
63 )
64
65 if (run.exitCode !== 0) {
66 return { result: `Codex failed (exit ${run.exitCode}): ${run.stderr.slice(-2000)}`, isError: true }
67 }
68 return { result: `Codex finished. Output:\n${run.stdout.trim()}\nExpected file: ${output_path}` }
69 } finally {
70 $.ui.status(undefined)
71 }
72 })
73}
74