Skip to content

d0mkaaa/gopull

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gopull

CI Release Go License

A terminal HTTP client. Send requests, manage collections, inspect responses - keyboard-driven, single binary, no Electron.

demo


Install

# macOS (Intel + Apple Silicon)
brew install d0mkaaa/tap/gopull
# if macOS blocks the binary: xattr -d com.apple.quarantine "$(which gopull)"

# Windows
scoop bucket add d0mkaaa https://github.com/d0mkaaa/scoop-gopull
scoop install gopull

# Go toolchain
go install github.com/d0mkaaa/gopull@latest

Or grab a binary from releases - Linux, macOS, Windows all covered.

Build from source:

git clone https://github.com/d0mkaaa/gopull
cd gopull
go build -o gopull .

Features

  • Collections - save and organise requests, run them in sequence with pass/fail reporting
  • Environments - create, edit, select, and delete named variable sets with {{VAR}} substitution
  • History - browse the last 500 requests, replay them, save them, or diff responses
  • Streaming - SSE responses arrive live line by line
  • Themes - dark, light, nord, gruvbox - or create your own in JSON
  • Curl import - paste a curl command into the URL field and press tab
  • Import/export - Postman collections, .http files (VS Code REST Client), OpenAPI v2/v3
  • CLI runner - run local collections in scripts or CI with text, JSON, or JUnit reports
  • Git-friendly files - export collections as plain .gopull request files
  • Search - / to search the response body, n/N to jump between matches
  • JSON tree - t to collapse/expand JSON responses interactively
  • Assertions - write tests that run after every response; extract values into env vars with set TOKEN = $.data.token
  • Multipart and files - send multipart forms or a file as the request body
  • Cookies and certs - opt-in cookie jar, CA bundle, and client certificate paths
  • Proxy - per-request proxy URL or HTTP_PROXY / HTTPS_PROXY env vars
  • Custom methods - type any method (PROPFIND, REPORT, etc.) in the method field

Usage

gopull
gopull ./api-requests

Run a collection from the shell:

gopull init ./my-api --env
gopull lint ./my-api
gopull run ./my-api --env dev --report json
gopull run collection.json --bail
gopull run ./my-api --tags smoke --exclude-tags slow --report junit
gopull run ./my-api --offline

Useful CLI flags:

--env dev                 use a saved environment by name or id
--env-file .env           merge variables from dotenv or JSON
--env-var TOKEN=value     override a variable, repeatable
--tags smoke              include only matching request tags
--exclude-tags slow       skip matching request tags
--iteration-count 3       run selected requests multiple times
--report text|json|junit  choose output format
--offline                 print built requests without sending

Three panels: sidebar (collections), editor (request builder), response. tab / shift+tab moves focus.

Editor

[ and ] cycle tabs: body, params, headers, auth, tests, opts.

  • Method: space / up / down cycle standard methods; press any letter to type a custom one
  • Params: query params append to the URL; path params fill :id placeholders
  • Headers: Key: Value, one per line. Prefix with # to disable a header
  • Body: raw by default, alt+m toggles raw / form / GraphQL / multipart / file mode
  • Auth: bearer token or basic auth under the auth tab
  • Completion: alt+/ completes {{env}} variables, header names, content types, and missing path params from the URL
  • ctrl+r sends

Multipart body lines use:

name=value
file avatar=/path/to/avatar.png

File body mode reads the body from the path in the body field.

Collections

ctrl+s saves the current request. Auto-names from method + URL path if no name is set.

From the sidebar: up / down navigate, enter open, r run all requests in sequence, n rename, ctrl+d duplicate a request, ctrl+j / ctrl+k move a request, d twice to delete.

Environments

ctrl+e opens the environment manager. enter selects, n creates, e edits, and d deletes.

Variables use a compact line format:

BASE_URL=https://api.example.com
secret TOKEN=value
# DISABLED=value

secret values are masked in the picker. If an environment has a dotenv path, file variables load first and inline variables override them.

History

alt+h opens the history browser. Filter by typing, enter loads a request into the editor, ctrl+r replays it, s saves it to the active collection, and D diffs its response body against another history entry.

Response

Responses open on a preview tab with status, timing, size, header count, cookies, and a content-aware body summary. JSON responses show top-level keys and shapes, HTML responses show title/headings/text, XML responses show root/children, and plain text shows the first readable lines.

[ / ] switches response tabs: preview, body, headers, and tests when assertions ran.

j/k scroll, / search, t JSON tree view from the body tab, y copy body, w save to file, D diff against history.

In tree view: space collapse/expand, c collapse all, e expand all, {/} jump between siblings.

Assertions

Write assertions in the Tests tab:

assert status == 200
assert header Content-Type contains json
assert body contains "token"
assert jsonpath $.data.id > 0
assert response_time < 500
set TOKEN = $.data.access_token

set extracts a JSONPath value and stores it in the active environment for use in the next request.

Import

ctrl+i accepts:

  • Postman collection JSON
  • .http / .rest files (VS Code REST Client format)
  • OpenAPI v2 (Swagger) or v3 JSON files
  • OpenAPI spec URLs (https://...)
  • gopull plain-text collection directories

Plain-text collections look like:

my-api/
  gopull.collection
  list-users.gopull
  create-user.gopull

Each .gopull request file uses simple sections like [query], [path], [headers], [body raw], and [tests]. Add tags: smoke, auth near the top of a request file to make CLI filters work.

Open a plain collection directly with gopull ./my-api. In workspace mode, saves write back to the .gopull files instead of copying the collection into the config store.

Scaffold a new plain collection:

gopull init ./my-api --env

Validate a collection before committing:

gopull lint ./my-api
gopull lint ./my-api --format json

Command palette

alt+p - fuzzy search over all actions and saved requests.


Keybindings

Key Action
ctrl+r Send request
ctrl+s Save request
alt+n New request
alt+p Command palette
alt+b Toggle sidebar
alt+o Settings
ctrl+e Environment manager
alt+h History browser
alt+l Plugin manager
ctrl+i Import collection
ctrl+x Export collection (Postman JSON)
alt+j Format JSON body
alt+m Toggle body mode
alt+/ Complete current editor field
alt+c Copy request as curl
alt+e Open body in external editor
[ / ] Switch editor tabs
tab / shift+tab Move focus between panels
/ Search response body
t Toggle JSON tree view
y Copy response to clipboard
w Save response to file
D Diff response against history
alt+q Quit

Custom bindings go in ~/.config/gopull/keybindings.json.


Config

~/.config/gopull/
  collections/        one JSON file per collection
  environments/       named variable sets
  history.json        last 500 requests
  config.json         theme, timeout, max display bytes
  keybindings.json    key overrides
  themes/             custom theme files
  plugins/            experimental local hooks
    disabled.json     local plugin enable/disable state

config.json options:

{
  "timeout_secs": 30,
  "theme": "dark",
  "max_display_bytes": 5242880
}

Themes

Built-in: dark (catppuccin mocha), light (catppuccin latte), nord, gruvbox. Settings (alt+o) lets you switch themes, change the default timeout, set the max response body display size, and confirm whether you are using the config store or a plain .gopull workspace.

Drop a JSON file in ~/.config/gopull/themes/ to add your own - a starter template is written there on first run.

Experimental Hooks

Executables in ~/.config/gopull/plugins/ can register local pre_request and post_response hooks. Hooks are local executables that speak JSON over stdin/stdout; there is no marketplace, remote install, account, or sync layer.

Plugins return a manifest from --manifest:

{
  "name": "aws-sigv4",
  "version": "0.1.0",
  "api_version": "v1",
  "hooks": ["pre_request"],
  "permissions": ["read_env", "read_body", "read_secrets", "write_headers"]
}

pre_request hooks receive request JSON and may return changed fields. post_response hooks receive the request plus a response snapshot and may return env updates.

v1 permissions:

  • read_env - receive non-secret environment variables
  • read_body - receive the request body
  • read_secrets - receive secret environment variables and auth secrets
  • write_request - change method or URL
  • write_headers - replace request headers
  • write_body - replace the request body
  • write_env - write environment variables from post_response

Manifests without api_version run in legacy mode for compatibility. New plugins should use api_version: "v1" and declare the narrowest permissions they need.

Open the plugin manager with alt+l to inspect local plugins, review hooks and permissions, reload manifests, or enable/disable a plugin.


License

MIT

About

A terminal HTTP client. Send requests, manage collections, inspect responses - all from the keyboard, all in your shell.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors