Command line
Your launch package, from the terminal
Install launchtowin once and your Launch to Win package is a command away: read it, change it, add logos, screenshots and videos, and pull a copy-ready launch kit for any directory. Made for makers who live in a terminal, and for the AI agents working for them.
The package as data
Create a package with one command, set its tagline, descriptions, pricing, categories and links with key=value pairs, read it back as JSON.
Every asset, every format
Add logos, screenshots and videos to the library with tags and notes. Pick which ones publish as logo, screenshots or demo video; the originals stay.
Launch kits for agents
For any directory: the form's fields with your copy trimmed to its limits, the submission link, and your images exported to its sizes, saved to disk. --json on everything.
Install
Two lines to install, one to sign in, and that's it. There is nothing else to set up: it runs on the Ruby that macOS and most Linux distributions already ship, with no packages to add.
curl -fsSL https://launchto.win/cli/launchtowin -o ~/.local/bin/launchtowin
chmod +x ~/.local/bin/launchtowin
launchtowin login # paste the token shown below
launchtowin whoami
In a product's repo, launchtowin init <slug> writes a launchtowin.json that names the package (and can hold its fields and the files to publish), so every command there works without a slug and launchtowin push syncs the lot.
The token is kept in ~/.config/launchtowin/config.json, readable by you only. Agents and CI can set LAUNCHTOWIN_TOKEN instead. Read the script before you run it, as you should with anything you curl.
Packages
launchtowin list
launchtowin kode # show it; created on the spot when new
launchtowin kode set tagline="Passwords, done right" pricing_model=free \
platforms=ios,mac categories=utilities description=@README.md
launchtowin kode set --for product-hunt tagline="A shorter line for PH"
launchtowin kode get descriptions.long
launchtowin kode check # what is missing, and every directory the copy would not pass
launchtowin fields # every field, its limit and allowed values
Values can come from files with @path, lists are comma-separated, and unknown fields are refused with the valid list. Descriptions are capped at 200, 600 and 10,000 characters, the same limits as the editor, and every set warns when the new copy breaks a directory's limit.
Assets
launchtowin kode assets # id, status, kind, size, dimensions, roles, tags
launchtowin kode assets add icon.png --as logo --tags icon,square
launchtowin kode assets add shot-1.png shot-2.png --as screenshot --tags "ios,dark"
launchtowin kode assets add demo.mp4 --as video
launchtowin kode assets add new.png --replace 42 # new bytes, same title, tags and roles
launchtowin kode assets select 42 --as none
launchtowin kode assets download --role screenshot --dir ./shots
The library keeps every original, up to 50 MB per file, and uploading the same bytes twice returns the existing entry. Roles decide what publishes: one logo, any number of screenshots, one demo video. Removing a library entry never removes a selected file from the package.
Publish anywhere
launchtowin kode directories --ready # fit and submission state per directory
launchtowin kode publish product-hunt --dir ./kit
launchtowin kode submitted product-hunt --url https://www.producthunt.com/posts/kode
launchtowin kode submissions
publish prints the directory's fields with your copy trimmed to its limits (per-directory overrides win), the submission link, whether an account is needed, and saves your logo and screenshots converted to its image requirements. It marks the submission as in progress; submitted closes it with the listing URL. A directory can be named by slug, host or submission URL; with none you get the generic kit for any site.
For AI agents
Run launchtowin skill --install once and Claude Code, Codex and Cursor get a skill that teaches them the CLI (it is this guide). Every command takes --json and prints the API response unchanged; errors go to stderr as JSON with a code such as validation or limit_reached; exit codes are 0, 1 (API or network) and 2 (usage). To publish a product on a site the agent runs:
launchtowin <slug> --jsonfor the package: descriptions, pricing, links, media URLs and what is still missing.launchtowin <slug> publish <directory> --json --dir ./kitfor fields sized to the form and image files on disk.- Fills the form, uploads the files, and you press submit.
launchtowin <slug> submitted <directory> --url <listing url>.
Prefer tools inside the browser? The same packages are exposed through WebMCP. The Chrome extension uses the same token.
Your API token
Sign in to see your API token.