{"_id":"@nyxsky404/vmup","_rev":"8-78f272e90d61b7196e793a2130f36885","name":"@nyxsky404/vmup","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@nyxsky404/vmup","version":"0.1.0","keywords":["ssh","scp","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.1.0","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"4b3e3e721e2e114f8a57fd2a620483c7c1926170","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.1.0.tgz","fileCount":32,"integrity":"sha512-L+7WL4Dx2WiYrTcZ31UvXDM9npA31CbELWhYnwcQIQuez+EhBsjkH2Md0127MkKV70DaeJ77X9v+PPEx6ufF6A==","signatures":[{"sig":"MEYCIQC9XWbzhXVzDpd/8cgHHzFc5dti52D2cRrFZS72HjNDBgIhAMUdBArcXWCMhWQ5s3RzT8AiRb5IS7XufEMVFYub/l3j","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69036},"type":"module","engines":{"node":">=18"},"gitHead":"ec7d79b4056ccba8c7998f65d73e9bf0858df00f","scripts":{"dev":"tsc --watch","test":"node --test dist/**/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"_npmVersion":"10.9.8","description":"Batch screenshots and media to a remote host for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.1.0_1789052092202_0.6444231992591232","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@nyxsky404/vmup","version":"0.1.1","keywords":["ssh","scp","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.1.1","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"a364cd32f083c889aade57bca24b22284370e35b","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.1.1.tgz","fileCount":32,"integrity":"sha512-7cDoAJHi92zto63Dw69Udb4br5U9GfYdekRK71Ke0jiYtGulIM8o49PNJqsZlbegf48rSS0KzKbba6IxS8fG7g==","signatures":[{"sig":"MEQCIAmOKVlYjiaq5hSvCEgkaoEq8iPGzQ+46RUbGCv1bzPeAiAVrtsLIsQw+T6m4rZB63IDZYGu5k9kYd3kD47cpbPzgA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69206},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"09a17c4dcfde7a72d93950cccf1fb4d07b4e3154","scripts":{"dev":"tsc --watch","test":"node --test dist/**/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"_npmVersion":"10.9.8","description":"Batch screenshots and media to a remote host for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.1.1_1789052472341_0.061505483993324006","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@nyxsky404/vmup","version":"0.2.0","keywords":["ssh","scp","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.2.0","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"9a7ab727b1b1b366b649048add41ff848b744269","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.2.0.tgz","fileCount":40,"integrity":"sha512-nh3qRQbwGeqYWYmNRGcV5IoVcVulylXAawhC6AFFYr4Zj59bZUSpsN5fzoa0lyvLrm76gHm5bcl916YLER+DHw==","signatures":[{"sig":"MEUCIQCSS8XR/b3XE/q9HsCVrT2q7DKGlQQ69rU9BUxOmytJxwIgQ1FbYXDzB9uBfF3bHSxK3dxweW2wpIKiR7IGZNMzXNc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84032},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"0009d19894c75f7494f22035014eaf05ede68fbf","scripts":{"dev":"tsc --watch","test":"node --test dist/**/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"_npmVersion":"10.9.8","description":"Batch screenshots and media to a remote host for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.2.0_1789060420964_0.5131044278832015","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@nyxsky404/vmup","version":"0.2.1","keywords":["ssh","scp","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.2.1","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"3c38140a6efbbfec3ef6d78414f0784f49c59f40","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.2.1.tgz","fileCount":42,"integrity":"sha512-qbJ+FOhmx4whybXUIhOY6vNdcKJ6KhPDke8cAQzR/SX9CMSnt9zGEnDnrFQy5yAlTCNsiZKzJ9HT939+yBCXWA==","signatures":[{"sig":"MEYCIQCp5bR+c80rZx4+3JMDefCpgkSoO4JLEZfJWIu+SQNbVwIhALmgSRde8XgcW5YxXIfTZJmiMp1Jjc+MOlfzt3hpVrTi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89298},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"0009d19894c75f7494f22035014eaf05ede68fbf","scripts":{"dev":"tsc --watch","test":"node --test dist/**/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"_npmVersion":"10.9.8","description":"Batch screenshots and media to a remote host for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.2.1_1789060943555_0.4844279970802834","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@nyxsky404/vmup","version":"0.3.0","keywords":["ssh","scp","files","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.3.0","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"homepage":"https://github.com/nyxsky404/vmup#readme","bugs":{"url":"https://github.com/nyxsky404/vmup/issues"},"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"5ab3832f2008cb14bd30ba60bae3ffd4c8952172","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.3.0.tgz","fileCount":43,"integrity":"sha512-FQPpV5FBWesW0eRWCmiuIgw6b6q7UTn09kiw/7pTyIc+q/xa1tjgF+kcjR80vdFlm//7le1x1uFQ5P2hZNxMOg==","signatures":[{"sig":"MEUCIFVnE1SbsVIVc4J4ERWx6AeU16B44nvhQ+siikFkwjy8AiEAxkG0qTKq/5V6Iv6Ta0bzBMKS/zdcgXzJdOATIFVXQ+g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIDSFcZ1T1gWfbngw76Qh84wQ303FKrTG5+tS8F7WmC4nAiBQDHnMGLULU2cj9HaqD69/TEluyGtkaZ3rXTRrwT+3cg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107326},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"a496844593db088812a7b38f9445ad0a493613bb","scripts":{"dev":"tsc --watch","test":"node --test dist/**/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"repository":{"url":"git+https://github.com/nyxsky404/vmup.git","type":"git"},"_npmVersion":"10.9.8","description":"Batch files to a remote host over SSH for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.3.0_1789068858811_0.21488449904030849","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@nyxsky404/vmup","version":"0.3.1","keywords":["ssh","scp","files","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.3.1","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"homepage":"https://vmup.vercel.app","bugs":{"url":"https://github.com/nyxsky404/vmup/issues"},"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"2eb7902dd9093bd4c8530b90856560c8116e5cc6","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.3.1.tgz","fileCount":43,"integrity":"sha512-EKmgeATkr1ULM7R9WKl8ZXI9YOfFAqxINyIf1CFXzw/bOF/C+KVqej/0jamzcSK9xC1VSKCGfDOzs093zEgZ/A==","signatures":[{"sig":"MEQCIFlEwWLVgOk9EDYH1mnOkXfQpyOwlbV9LLXJc7Y7bMSRAiBxAqI8RWlj1vKPkujX2Zx+j1HcrUpNaE4MipYfz3M1lA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIHZ94dkuIaBRPRrxcIZaKlZ8IDQi83olCjlw5AInGBh4AiEAubZA1bOhMxyscrkdwBnSy2trFaJjSoA41pLuiAWqSIA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":114199},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"d5739d80ef5f9d81cb2ccab451a05516d22dc7cc","scripts":{"dev":"tsc --watch","test":"node --test dist/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"repository":{"url":"git+https://github.com/nyxsky404/vmup.git","type":"git"},"_npmVersion":"10.9.8","description":"Batch files to a remote host over SSH for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.3.1_1789134588703_0.26731064653429093","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@nyxsky404/vmup","version":"0.3.2","keywords":["ssh","scp","files","screenshots","agents","cli","upload"],"license":"MIT","_id":"@nyxsky404/vmup@0.3.2","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"homepage":"https://vmup.dev","bugs":{"url":"https://github.com/nyxsky404/vmup/issues"},"bin":{"vmup":"dist/cli.js"},"dist":{"shasum":"c40a682b9649283e318c243e52b0973c14efd104","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.3.2.tgz","fileCount":43,"integrity":"sha512-1B9bFrHDtLAsXNIsNabw/12i7tg+IMipFWhec5LnT0anckSVwpo7NXFWopj3wS2bHWV8UkbJodno63zDmyXTZA==","signatures":[{"sig":"MEYCIQCvBdeUgnvYgo2GPSSboXlQtw2QQs+Qywjr13fFBQ0glAIhAPPXuBJoRjLMWT1U3Log96cJpG0KKxlnxTCpU9C3vDc9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGyB06hUTdjHkiIpFnralw7A0vOlnkL6X9pz26YdHv9HAiB23Na9b9dJ+EO36CyQnoxZfvZE9FWj5RyJugtnsVAEbA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":114332},"main":"./dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"537f1ece7b4ce9df1717856ea9ca31f35d9c6503","scripts":{"dev":"tsc --watch","test":"node --test dist/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"repository":{"url":"git+https://github.com/nyxsky404/vmup.git","type":"git"},"_npmVersion":"10.9.8","description":"Batch files to a remote host over SSH for coding agents","directories":{},"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"tmp":"tmp/vmup_0.3.2_1789159244104_0.9024171575663249","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@nyxsky404/vmup@0.4.0","bin":{"vmup":"dist/cli.js"},"bugs":{"url":"https://github.com/nyxsky404/vmup/issues"},"dist":{"shasum":"2a5fbf60399dcaa78cc7615298d3b6d22089b31c","tarball":"https://registry.npmjs.org/@nyxsky404/vmup/-/vmup-0.4.0.tgz","fileCount":45,"integrity":"sha512-rHuemfm05GnTf4USdgRhWcrEFst20U82PfMrWsSng8tEOVX/AiPJu8SVUuhMTIa+yK3lojxXFNjjfCHRxm1EzA==","signatures":[{"sig":"MEUCIQCkqeeQoTJ8G9+WGKBNWKK+6Y5UsuuZnPZMJFn05X+H5AIgQ2CJYi/9SFZQeF0z6FlsOVTBKofJFHBJLmAts+6UJs0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCzeDiF0vmhORyo330MW0/RvYTnTl2fp99XNl8I/JkL9AIhAKWUVPfeSsOAXaqizDx6UVuo6L14T9dUyywWAwiDgb4V"}],"unpackedSize":123182},"main":"./dist/cli.js","name":"@nyxsky404/vmup","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=18"},"exports":{".":"./dist/cli.js"},"gitHead":"1992d171bbc0a3fe6e2b5af6b7d533b0dac3b96f","license":"MIT","scripts":{"dev":"tsc --watch","test":"node --test dist/*.test.js","build":"tsc","start":"node dist/cli.js","prepare":"npm run build","prepublishOnly":"npm run build && npm test"},"version":"0.4.0","_npmUser":{"name":"nyxsky404","email":"nyxsky404@gmail.com"},"homepage":"https://vmup.dev","keywords":["ssh","scp","files","screenshots","agents","cli","upload"],"repository":{"url":"git+https://github.com/nyxsky404/vmup.git","type":"git"},"_npmVersion":"10.9.8","description":"Batch files to a remote host over SSH for coding agents","directories":{},"maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"_nodeVersion":"22.23.2","dependencies":{"chokidar":"^4.0.3","commander":"^13.1.0","smol-toml":"^1.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.2","@types/node":"^22.13.10"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vmup_0.4.0_1789205804797_0.9710602759589493"}}},"time":{"created":"2026-09-10T14:54:51.904Z","modified":"2026-09-12T09:36:45.061Z","0.1.0":"2026-09-10T14:54:52.347Z","0.1.1":"2026-09-10T15:01:12.486Z","0.2.0":"2026-09-10T17:13:41.106Z","0.2.1":"2026-09-10T17:22:23.681Z","0.3.0":"2026-09-10T19:34:18.902Z","0.3.1":"2026-09-11T13:49:48.798Z","0.3.2":"2026-09-11T20:40:44.183Z","0.4.0":"2026-09-12T09:36:44.903Z"},"bugs":{"url":"https://github.com/nyxsky404/vmup/issues"},"license":"MIT","homepage":"https://vmup.dev","keywords":["ssh","scp","files","screenshots","agents","cli","upload"],"repository":{"url":"git+https://github.com/nyxsky404/vmup.git","type":"git"},"description":"Batch files to a remote host over SSH for coding agents","maintainers":[{"name":"nyxsky404","email":"nyxsky404@gmail.com"}],"readme":"# vmup\n\n*Batch files to a remote host over SSH for coding agents*\n\n**Docs:** [https://vmup.dev/docs](https://vmup.dev/docs)\n\n[![npm version](https://img.shields.io/npm/v/@nyxsky404/vmup?style=flat-square)](https://www.npmjs.com/package/@nyxsky404/vmup)\n[![CI](https://github.com/nyxsky404/vmup/actions/workflows/ci.yml/badge.svg)](https://github.com/nyxsky404/vmup/actions/workflows/ci.yml)\n[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-3c873a?style=flat-square)](https://nodejs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-blue?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org)\n[![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](https://github.com/nyxsky404/vmup/blob/main/LICENSE)\n\n[Docs](https://vmup.dev/docs) • [Overview](#overview) • [Getting started](#getting-started) • [Quickstart](#quickstart) • [Usage](#usage) • [Commands](#commands) • [Config](#config) • [Troubleshooting](#troubleshooting)\n\nThe npm package is [`@nyxsky404/vmup`](https://www.npmjs.com/package/@nyxsky404/vmup). The command is `vmup`. Full documentation is on the [docs site](https://vmup.dev/docs).\n\nA coding agent on a VM reads files by path. Screenshots, PDFs, and recordings sit on your laptop. vmup copies them over SSH into one remote folder, prints a prompt, and copies that prompt to your clipboard. Paste it into the agent thread.\n\n```text\nUploaded 3 files → default\nAgent folder: ~/vmup/agents-20260911-140128-a1b2c3d4/\n\nPrompt:\nPlease inspect all files in ~/vmup/agents-20260911-140128-a1b2c3d4/\n```\n\n> **Important:** You need **Node.js 18+** and **OpenSSH** (`ssh` on your `PATH`). Native Windows is not supported; use [WSL](https://learn.microsoft.com/windows/wsl/).\n\n## Overview\n\nvmup is a small CLI for one job: collect files on your machine, stage a unique batch, upload it over SSH, and hand back **one folder path**.\n\n```text\ncollect → validate → stage → upload → print path + prompt → TTL cleanup\n```\n\n| Piece | Default |\n| --- | --- |\n| Config | `~/.config/vmup/config.toml` |\n| Local staging | `~/.cache/vmup/` |\n| Remote root | `~/vmup` |\n| Batch folder | `agents-<YYYYMMDD>-<HHMMSS>-<uuid>` |\n| Staged names | `image-01.png`, `video-01.mov`, `file-01.pdf` |\n| TTL | 5 minutes |\n| Per-file size | 200 MB |\n| Files per batch | 200 |\n| File types | All (set `accept_all_files = false` for images only) |\n| Clipboard after upload | Prompt (`clipboard_copy = \"prompt\"`; `\"path\"` or `\"none\"`) |\n\nTransport is your system OpenSSH. Each file is streamed over `ssh` into a `.partial` directory, then renamed into place so the agent never sees a half-written folder. On a TTY, the spinner counts bytes as they are written.\n\n## Features\n\n- **Four collect modes** — file args, native picker, clipboard loop, foreground folder watch\n- **One agent folder** — stable `image-NN` / `video-NN` / `file-NN` names inside `agents-…/`\n- **Profiles and aliases** — saved hosts in config, or `--ssh-host` for a one-shot `~/.ssh/config` alias\n- **Clipboard-ready output** — prompt copied by default; set `clipboard_copy` to `path` or `none`\n- **JSON for scripts** — `--json` on stdout; spinner stays on stderr\n- **TTL cleanup** — remote sweeper every minute, a client-side fallback delete, or `vmup prune --all` to wipe now\n\n## Getting started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org) 18 or newer\n- OpenSSH client (`ssh`)\n- A remote host you can reach with a key, or an alias in `~/.ssh/config`\n\nConfirm both before installing:\n\n```bash\nnode -v\nssh -V\n```\n\n### Install\n\n```bash\nnpm i -g @nyxsky404/vmup\n```\n\nAlso:\n\n```bash\npnpm add -g @nyxsky404/vmup\nyarn global add @nyxsky404/vmup\nbun install -g @nyxsky404/vmup\n```\n\nOne-shot, no global binary:\n\n```bash\nnpx @nyxsky404/vmup init\n```\n\nSame pattern with `pnpm dlx`, `yarn dlx`, or `bunx`.\n\ncurl installer (still needs Node 18+). It picks npm, then pnpm, yarn, or bun. Override with `VMUP_PM`:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/nyxsky404/vmup/main/scripts/install.sh | sh\n```\n\n```bash\nVMUP_PM=pnpm curl -fsSL https://raw.githubusercontent.com/nyxsky404/vmup/main/scripts/install.sh | sh\n```\n\nThen:\n\n```bash\nvmup --version\n```\n\n> **Tip:** Newer releases print a two-line notice at most once per day while you stay on an older version. The command does not wait on npm. Disable with `VMUP_NO_UPDATE_CHECK=1`. CI (`CI=true` or `CI=1`), `--json`, non-TTY output, and `-V` skip it.\n\n## Quickstart\n\n```bash\nvmup init\nvmup check\nvmup ./shot.png\n```\n\n`vmup init` writes `~/.config/vmup/config.toml`. Press Enter to keep a value in `[brackets]`. First run asks for profile name, host, SSH user (`ubuntu`), key (`~/.ssh/id_ed25519`), port (`22`), remote dir (`~/vmup`), TTL minutes (`5`), watch folder, whether to accept all file types, and whether to install the remote sweeper.\n\n`vmup check` tests SSH without the wizard:\n\n```text\nSSH OK  default  ubuntu@192.168.1.10\nRemote dir: ~/vmup\nSweeper: installed\n```\n\nAfter a successful upload, paste into the agent. The clipboard already holds the prompt.\n\n> **Tip:** Non-interactive setup: `VMUP_HOST=… vmup init -y`. Add `VMUP_USER` / `VMUP_KEY` as needed. `--no-sweeper` skips remote cron.\n\nIf the VM is off during init, config is still saved. You will see `SSH setup incomplete`. Retry with `vmup check`, then `vmup check --sweeper` if cleanup never landed.\n\n## Usage\n\nEvery collect mode ends the same way: one remote folder, a printed prompt, that prompt on your clipboard (human mode). Set `clipboard_copy` to `path` or `none` if you want something else.\n\n### File arguments\n\n```bash\nvmup shot.png notes.pdf\nvmup ~/Downloads\n```\n\nA directory sends **immediate children** only. Hidden names, `.DS_Store`, `Thumbs.db`, and `desktop.ini` are skipped. Nested trees need the inner folder or the files themselves.\n\n### Native picker\n\n```bash\nvmup\n```\n\nNo arguments and no `--clip` / `--watch` opens a GUI picker.\n\n| Platform | Picker |\n| --- | --- |\n| macOS | Multi-select (`choose file`) |\n| Linux | `zenity` (multi) or `kdialog` (single) |\n| Windows | Not supported. Pass paths, or use WSL. |\n\n### Clipboard loop\n\n```bash\nvmup --clip\n```\n\nCopy a file or an image, press **Enter** to capture, repeat, then type `done` / `stop` / `q`, or Ctrl+D. Ctrl+C cancels (exit 130). Duplicate clipboard bytes are skipped while `clip_dedup` is true (default).\n\n> **Note:** `--clip` reads the **OS clipboard**, not terminal paste. On macOS, a copied Finder file needs no extra tools; a bitmap (screenshot) needs [pngpaste](https://github.com/jcsalterego/pngpaste) (`brew install pngpaste`). Linux uses `wl-paste` or `xclip`.\n\n### Watch a folder\n\n```bash\nvmup watch\nvmup watch --dir ~/Desktop\n```\n\nForeground only. Files already in the folder at start are ignored. Files added or copied after start are staged (Finder copies included). Press Enter or type `stop` to upload. Ctrl+C cancels.\n\nDefault folder: `~/Desktop` on macOS, `~/Pictures/Screenshots` on Linux. Only the folder itself is watched, not subfolders.\n\nDo not combine `--clip` and `--watch`.\n\n### Target a host\n\n```bash\nvmup -p work shot.png\nvmup --ssh-host lab shot.png\n```\n\nDo not pass `--profile` and `--ssh-host` together.\n\n`--video` and `--force` only change type filtering when `accept_all_files` is false. `--force` never skips SSH checks or size/count limits.\n\n```bash\nvmup shot.png --ttl 15 --keep-local\nvmup shot.png --json\n```\n\n## Commands\n\n| Command | Purpose |\n| --- | --- |\n| `vmup [files…]` | Upload (picker if no files) |\n| `vmup init` | Create or update config; optional remote sweeper |\n| `vmup check` | Test SSH using saved config. `--sweeper` installs/refreshes cleanup |\n| `vmup profiles` | List saved profiles |\n| `vmup watch` | Same as `vmup --watch` |\n| `vmup prune` | Delete expired remote batches (`--all` ignores TTL) |\n\n`vmup init -y` requires `VMUP_HOST`. Re-running `vmup init` interactively adds a profile or overwrites an existing one (current values shown in brackets).\n\n## Profiles\n\nSaved remotes live under `[profiles.<name>]`. The default profile is used when you pass neither `-p` nor `--ssh-host`.\n\n**Direct** (host + user + key + port):\n\n```toml\n[profiles.work]\nhost = \"192.168.1.10\"\nuser = \"ubuntu\"\nkey = \"~/.ssh/id_ed25519\"\nport = 22\nremote_dir = \"~/vmup\"\nttl_minutes = 5\n```\n\nvmup passes `-i`, `-p`, `BatchMode=yes`, and `StrictHostKeyChecking=accept-new`.\n\n**SSH config alias** (`ssh_host`):\n\n```toml\n[profiles.lab]\nssh_host = \"lab\"\nremote_dir = \"~/vmup\"\nttl_minutes = 5\n```\n\nvmup runs `ssh lab …`. User, key, and port come from `~/.ssh/config`.\n\n`--ssh-host lab` is the one-shot version (printed profile name `ssh:lab`). A profile with `ssh_host` set uses alias mode even if `host` is also present.\n\n## Config\n\nPath: `~/.config/vmup/config.toml`\n\nOverrides: `VMUP_CONFIG_DIR` (directory) → `$XDG_CONFIG_HOME/vmup` → `~/.config/vmup`.\n\n**Precedence:** flag → env (`VMUP_*`) → profile → top-level file → built-in default.\n\n```toml\ndefault_profile = \"default\"\nprompt_template = \"Please inspect all files in {{remote_path}}\"\nremote_dir = \"~/vmup\"\nttl_minutes = 5\nwatch_dir = \"/Users/you/Desktop\"\nwatch_include_video = false\naccept_all_files = true\nmax_file_mb = 200\nclip_dedup = true\nclipboard_copy = \"prompt\"\n\n[profiles.default]\nhost = \"192.168.1.10\"\nuser = \"ubuntu\"\nkey = \"~/.ssh/id_ed25519\"\nport = 22\nremote_dir = \"~/vmup\"\nttl_minutes = 5\n```\n\n`{{remote_path}}` is replaced with the remote folder (trailing `/` added if missing). After upload, human mode copies the prompt to the clipboard (`clipboard_copy = \"prompt\"`). Use `\"path\"` for the folder only, or `\"none\"` to skip the copy. `--json` never copies. After you change `ttl_minutes`, run `vmup check --sweeper` so the remote script matches. Editing the file alone does not rewrite `~/vmup/.cleanup.sh`.\n\nSelected environment variables:\n\n| Variable | Role |\n| --- | --- |\n| `VMUP_HOST` / `VMUP_USER` / `VMUP_KEY` / `VMUP_PORT` | Direct-mode target. `VMUP_HOST` required for `init -y` |\n| `VMUP_PROFILE` / `VMUP_SSH_HOST` | Profile name, or one-shot OpenSSH alias |\n| `VMUP_REMOTE_DIR` / `VMUP_TTL_MINUTES` | Remote root and TTL |\n| `VMUP_ACCEPT_ALL` | `0` images-only, `1` all types |\n| `VMUP_CLIPBOARD_COPY` | `prompt` (default), `path`, or `none` |\n| `VMUP_MAX_FILE_MB` | Per-file size cap |\n| `VMUP_NO_UPDATE_CHECK` | `1` skips the notice and the background registry check |\n| `NO_COLOR` | Any value: no ANSI |\n\nEmpty string is treated as unset. `SSH_AUTH_SOCK` allows a missing `key` in direct mode.\n\n## Cleanup\n\nRemote batches expire after **TTL minutes** (default 5). `vmup init` installs `~/vmup/.cleanup.sh` and a crontab line that runs every minute. The script removes `agents-*` and `agents-*.partial` directories older than TTL. It does not wipe the remote root.\n\n```bash\nvmup prune\nvmup prune --all\nvmup prune --id agents-20260911-140128-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\nvmup prune --local\nvmup prune --install-sweeper\n```\n\n`vmup prune --all` deletes every remote `agents-*` batch immediately, even if TTL has not elapsed. `--local` also deletes staging under `~/.cache/vmup/` older than 24 hours. Successful uploads already delete that cache unless you pass `--keep-local`. Failed SSH or upload **keeps** local staging.\n\n> **Warning:** The client-side delete is a detached `sleep` then `ssh rm`. It dies if this machine sleeps or exits. If `~/vmup/.cleanup.sh` is missing, batches may linger. Reinstall with `vmup check --sweeper`.\n\n## JSON and exit codes\n\n```bash\nvmup shot.png --json\nvmup check --json\n```\n\nJSON goes to **stdout**. Spinner, skip warnings, and human text stay on **stderr**. `--json` does not copy to the clipboard.\n\n```json\n{\n  \"ok\": true,\n  \"batchId\": \"agents-20260911-140128-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n  \"profile\": \"default\",\n  \"remotePath\": \"~/vmup/agents-20260911-140128-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/\",\n  \"prompt\": \"Please inspect all files in ~/vmup/agents-20260911-140128-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/\",\n  \"count\": 2,\n  \"files\": [\"image-01.png\", \"file-01.pdf\"],\n  \"sweeper\": true\n}\n```\n\n`vmup prune --json` (including with `--all`) does not emit this schema. The flag only hides the update notice.\n\n| Code | Meaning |\n| --- | --- |\n| `0` | Success. `init` also returns 0 when config was written even if SSH failed. |\n| `1` | Bad flags or unusable target |\n| `2` | Nothing to upload |\n| `3` | SSH / preflight / sweeper install / prune |\n| `4` | Upload failed (staging kept) |\n| `130` | Cancelled during collect (staging deleted) |\n\n## Troubleshooting\n\n| You see | What to do |\n| --- | --- |\n| `Profile \"default\" has no host` | Run `vmup init`, or set `VMUP_HOST` |\n| `SSH key not found` | Fix `key` in config or `VMUP_KEY` |\n| `permissions are too open` | `chmod 600` on the private key |\n| `Permission denied (publickey)` | User, key, or `authorized_keys` mismatch |\n| `Connection refused` / timed out | Port, firewall, VPN, VM power |\n| `Could not resolve hostname` | DNS, or the `Host` name in `~/.ssh/config` |\n| `No files to upload` (exit 2) | Path missing, picker cancelled, or watch/clip with zero captures |\n| `SSH preflight failed` + `Local staging kept` | Fix the host, then retry. Staging stays under `~/.cache/vmup/` |\n| `Use either --profile or --ssh-host` | Pick one |\n| `Use either --all or --id, not both` | Pick one |\n| Sweeper missing | `vmup check --sweeper` |\n| Batches still on the VM | `vmup prune --all` (ignores TTL). One batch: `vmup prune --id …` |\n| Clipboard image ignored (macOS) | `brew install pngpaste` |\n| No GUI picker (Linux) | Install `zenity`/`kdialog`, or pass file paths |\n\n`vmup check` is the retry path that skips the wizard. Preflight timeout is 20 seconds. Upload timeout is 10 minutes per file. `--force` never skips connectivity checks.\n\nA working `ssh lab` and a failing `vmup -p lab` usually means the profile is in **direct** mode (`ubuntu@host`) while you expected the alias. `vmup profiles` prints `ssh_host=lab` for alias mode.\n\n## Development\n\nDocs: [https://vmup.dev/docs](https://vmup.dev/docs). Source and issues: [github.com/nyxsky404/vmup](https://github.com/nyxsky404/vmup). How to send a change: [CONTRIBUTING.md](CONTRIBUTING.md). Clone, then `npm install && npm run build && npm test`.\n","readmeFilename":"README.md"}