SLOPSHOPPER

clipboard-image-paste

Paste an image from the Windows clipboard (Win+V history) into the chat without Alt+V.

newcommandtoastpromptprocess
v0.1.0no licenseupdated 2026-10-22bngxyz/claude-mods/mods/clipboard-image-paste
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · clipboard-image-paste
› fix the failing auth test and add an audit log call ╭────────────────────────────────────────────╮ │ clipboard-image-paste │ ⏺ Read(src/auth.ts) │ clipboard-image-paste: the clipboard │ ⎿ Read 6 lines │ watcher stopped │ ⏺ Update(src/auth.ts) ╰────────────────────────────────────────────╯ ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /pasteimg ⎿ clipboard-image-paste: Pasting the clipboard image. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

claude-mods

ชุด mod สำหรับ Claude Code บน Windows

Modทำอะไร
statusline/statusline.jsStatus 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

สิ่งที่ต้องมี

  • Windows 10/11
  • Claude Code ติดตั้งแบบ native installer (%USERPROFILE%\.local\bin\claude.exe)
  • Node.js (สำหรับ status line)
  • Codex CLI ถ้าจะใช้ codex-imagegen

ติดตั้ง

git 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 ใหม่มีผล

install.ps1 ทำอะไรบ้าง

  1. ก๊อป statusline.js ไปที่ %USERPROFILE%\.claude\
  2. ก๊อป mod ไปที่ %USERPROFILE%\.claude\mods\
  3. แก้ %USERPROFILE%\.claude\settings.json (สำรองไฟล์เดิมเป็น settings.json.bak ก่อน)
  4. statusLine → node "<...>\statusline.js"
  5. env.CLAUDE_CODE_PLUGIN_DIRS → เพิ่ม path ของแต่ละ mod (คั่นด้วย ;)
  6. pluginConfigs.codex-imagegen.options.codexPath (เฉพาะตอนใส่ -CodexPath)
  7. ก๊อป claude.cmd ไปที่ %USERPROFILE%\.local\claude-wrap\ แล้วใส่โฟลเดอร์นี้ไว้หน้าสุดของ user PATH
  8. สร้าง registry HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\claude.exe ชี้ไปที่ claude.cmd เพื่อให้ address bar ของ Explorer และ Win+R เรียกผ่าน wrapper

ใช้งาน

claude            # เปิดปกติ
claude --bypass   # เปิดแบบข้าม permission ทั้งหมด

ในช่อง address bar ของ File Explorer พิมพ์ claude --bypass แล้วกด Enter จะเปิด Claude Code ในโฟลเดอร์นั้นเลย

ปิดหน้าต่างยืนยัน bypass

ถ้าไม่อยากเห็นหน้าต่างเตือนทุกครั้งที่เปิดแบบ 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)

Source 1 files
hooks/register.ts 83 lines
1import type { Hook, Register } from 'claude-code'
2
3type Engine = Parameters<Hook<'prompt.edit'>>[0]
4
5const PLUGIN = 'clipboard-image-paste'
6
7// One PowerShell for the session's life, started with everything loaded, so a
8// paste costs a file write instead of a process start. It waits for the
9// trigger file, and when the clipboard holds an image it has not pasted yet it
10// presses Alt+V, Claude Code's own image paste, once the prompt edit that
11// raised the trigger has finished. `force` (the /pasteimg command) pastes the
12// image again even if it was pasted already.
13const WATCHER_SCRIPT = `
14$ErrorActionPreference = 'Stop'
15Add-Type -AssemblyName System.Windows.Forms
16Add-Type -Namespace Win -Name Clip -MemberDefinition '[System.Runtime.InteropServices.DllImport("user32.dll")] public static extern uint GetClipboardSequenceNumber();'
17$trigger = $env:CLIP_TRIGGER
18$last = ''
19Write-Output 'ready'
20while ($true) {
21  if (Test-Path -LiteralPath $trigger) {
22    $mode = ''
23    try { $mode = (Get-Content -LiteralPath $trigger -Raw).Trim() } catch { Start-Sleep -Milliseconds 10; continue }
24    Remove-Item -LiteralPath $trigger -Force
25    $seq = [string][Win.Clip]::GetClipboardSequenceNumber()
26    if ([System.Windows.Forms.Clipboard]::ContainsImage() -and ($mode -eq 'force' -or $seq -ne $last)) {
27      $last = $seq
28      Start-Sleep -Milliseconds 50
29      [System.Windows.Forms.SendKeys]::SendWait('%v')
30    } elseif ($mode -eq 'force') {
31      Write-Output 'no-image'
32    }
33  }
34  Start-Sleep -Milliseconds 20
35}
36`
37
38function triggerPath($: Engine): string {
39  return `${$.plugin.root}/.paste-trigger`
40}
41
42export const register: Register = on => {
43  on('session.start', async ($, e, next) => {
44    await $.command.register({
45      name: 'pasteimg',
46      description: 'Paste the image on the clipboard as an attachment',
47    })
48
49    const started = await next(e)
50
51    void (async () => {
52      const watcher = $.process.spawn({
53        argv: ['powershell.exe', '-NoProfile', '-NonInteractive', '-STA', '-Command', WATCHER_SCRIPT],
54        env: { CLIP_TRIGGER: triggerPath($) },
55      })
56
57      for await (const { stream, text } of watcher) {
58        if (stream === 'stderr') $.ui.toast(`${PLUGIN}: ${text.trim()}`)
59        else if (text.includes('no-image')) $.ui.toast('There is no image on the clipboard.')
60      }
61
62      $.ui.toast(`${PLUGIN}: the clipboard watcher stopped`)
63    })()
64
65    return started
66  })
67
68  // A Win+V paste of an image-only clipboard reaches the editor as an empty
69  // paste: no key, nothing inserted, nothing replaced.
70  on('prompt.edit', async ($, e, next) => {
71    const isEmptyPaste = e.key === undefined && e.inputText === '' && e.start === e.end
72    if (isEmptyPaste) await $.fs.write(triggerPath($), 'auto')
73
74    return next(e)
75  })
76
77  on('command.run', { command: 'pasteimg' }, async $ => {
78    await $.fs.write(triggerPath($), 'force')
79
80    return { text: 'Pasting the clipboard image.' }
81  })
82}
83