SLOPSHOPPER

Pop

Open a link or a file in its own window, straight from the prompt.

commandprocess
v0.1.1MITupdated 2026-10-11DJPalefaceSD/rostech-mods/plugins/pop
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · pop
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ 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 › /pop ⎿ pop: Nothing to open. /pop <url or path> opens it in a window of its own. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

Pop

Open a link or a file in its own app, in a window of its own, straight from the prompt. A link in a terminal is often not clickable, so Pop opens it for you instead of leaving you to copy it out.

  • /pop example.com opens a web page. A bare domain gets https in front.
  • /pop C:/notes/plan.md opens a file in the app your system uses for it.

It uses your system's own opener: Start-Process on Windows, open on macOS, and xdg-open on Linux. The address goes to that program as an environment value, never pasted into a command line. Nothing is sent anywhere else.

What it runs and sends

Nothing goes to any service from the mod itself. Here is each thing, plainly.

What it sends, and where.

  • The link or path you give /pop goes to your system's own opener program, on this machine. That is the only place the mod sends it.
  • The opener then opens it: a link in your web browser, a file in the app your system uses for it. That is the same as clicking it yourself.
  • The way out is $.process.run, Claude Code's call for starting a program on your machine. Pop uses it only to start the opener below.

Which programs it runs, and why.

  • One opener program, to open your link or file. It tries these in order and stops at the first that works:
  • Windows: powershell.exe -NoProfile -Command "Start-Process -FilePath $env:POP_TARGET"
  • macOS: open <your link or path>
  • Linux: xdg-open <your link or path>
  • On Windows the command is fixed text. Your link goes in as the environment value POP_TARGET, never inside the command.
  • On macOS and Linux the program name is fixed. Your link or path is its one argument, passed straight to it, never through a shell.
  • Each try stops after 8 seconds. It runs only when you type /pop.

What it puts in the prompts it submits.

  • It submits no prompts. It never touches your prompt box.

What each hook does.

  • session.start: adds the /pop command.
  • command.run for pop: puts https in front of a bare domain, runs the opener, and says whether it opened.

Tested with Claude Code 2.1.287 on Windows.

More mods

See every Rostech mod, live, at rostech.app.

Source 1 files
hooks/register.ts 43 lines
1import type { EngineInterface, Register } from 'claude-code'
2
3// Each system's own "open this" program, tried in order; the first that runs wins.
4function openers(target: string): readonly (readonly string[])[] {
5  return [
6    ['powershell.exe', '-NoProfile', '-Command', 'Start-Process -FilePath $env:POP_TARGET'],
7    ['open', target],
8    ['xdg-open', target],
9  ]
10}
11
12async function open($: EngineInterface, target: string): Promise<boolean> {
13  for (const argv of openers(target)) {
14    const ran = await $.process
15      .run(argv, { env: { POP_TARGET: target }, timeoutMs: 8000 })
16      .catch(() => null)
17    if (ran && ran.exitCode === 0) return true
18  }
19  return false
20}
21
22// A bare domain gets https in front, so "/pop example.com" opens a page and not a file.
23function target(arg: string): string {
24  const t = arg.trim().replace(/^"|"$/g, '')
25  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(t)) return t
26  if (/^[\w-]+(\.[\w-]+)+(\/\S*)?$/.test(t) && !/\.(md|txt|html?|png|jpe?g|pdf|json)$/i.test(t)) return `https://${t}`
27  return t
28}
29
30export const register: Register = on => {
31  on('session.start', async ($, e, next) => {
32    await $.command.register({ name: 'pop', description: 'Open a link or a file in its own app, in a window of its own. /pop <url or path>' })
33    return next(e)
34  })
35
36  on('command.run', { command: 'pop' }, async ($, e) => {
37    const t = target(e.args)
38    if (!t) return { text: 'Nothing to open. /pop <url or path> opens it in a window of its own.' }
39    const ok = await open($, t)
40    return { text: ok ? `🌐 Opened: ${t}` : `Could not open ${t} on this machine.` }
41  })
42}
43